Commit 2f899f227414ec2e61fed3ac2b509aee2b105b93
1 parent
5d56e805
Exists in
master
and in
1 other branch
Add a project index page supplemented with a simple, hopefully temporary, theme
Showing
19 changed files
with
351 additions
and
17 deletions
Show diff stats
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +module NavigationHelper | ||
2 | + | ||
3 | + # Returns ' active' if you are on a given controller | ||
4 | + # - active_if_here(:users) => ' active' if users controller | ||
5 | + # Or on one of a list of controllers | ||
6 | + # - active_if_here([:users, :blogs, :comments]) | ||
7 | + # Or on certain action(s) in a certain controller | ||
8 | + # - active_if_here(:users => :index, :blogs => [:create, :update], :comments) | ||
9 | + # | ||
10 | + # Useful for navigation elements that have a certain state when your on a given page. | ||
11 | + # Returns nil if there are no matches so when passing: | ||
12 | + # link_to 'link', '#', :class => active_if_here(:users) | ||
13 | + # will not even set a class attribute if nil is passed back. | ||
14 | + def active_if_here(matches) | ||
15 | + current_controller = controller.controller_name.to_sym | ||
16 | + current_action = controller.action_name.to_sym | ||
17 | + | ||
18 | + sections = case matches | ||
19 | + when Hash | ||
20 | + matches | ||
21 | + when Array | ||
22 | + s = {} | ||
23 | + matches.each {|c| s[c] = :all} | ||
24 | + s | ||
25 | + else | ||
26 | + {matches => :all} | ||
27 | + end | ||
28 | + | ||
29 | + active = nil | ||
30 | + sections.each do |controller, actions| | ||
31 | + actions = ([] << actions) unless actions.kind_of?(Array) | ||
32 | + active = ' active' if current_controller == controller && (actions.include?(:all) || actions.include?(current_action)) | ||
33 | + end | ||
34 | + active | ||
35 | + end | ||
36 | + | ||
37 | +end | ||
0 | \ No newline at end of file | 38 | \ No newline at end of file |
app/models/project.rb
app/views/layouts/application.html.erb
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +!!! html | ||
2 | +%html | ||
3 | + %head | ||
4 | + %title | ||
5 | + Cartless — | ||
6 | + = yield(:page_title).present? ? yield(:page_title) : yield(:title) | ||
7 | + %meta{ :content => "text/html; charset=utf-8", "http-equiv" => "content-type" }/ | ||
8 | + = javascript_include_tag :defaults | ||
9 | + = stylesheet_link_tag 'reset', 'application' | ||
10 | + = yield :head | ||
11 | + %body{:id => controller.controller_name, :class => controller.action_name} | ||
12 | + #header | ||
13 | + = link_to 'Hypnotoad', root_path, :id => 'site-name' | ||
14 | + | ||
15 | + = render :partial => 'shared/navigation' | ||
16 | + | ||
17 | + #content-title | ||
18 | + %h1= yield :title | ||
19 | + %span.meta= yield :meta | ||
20 | + - if action_bar = yield(:action_bar) | ||
21 | + #action-bar | ||
22 | + = action_bar | ||
23 | + #content | ||
24 | + = render :partial => 'shared/flash_messages' | ||
25 | + = yield | ||
26 | + #footer | ||
27 | + Powered by Hypnotoad. All Glory to the Hypnotoad. | ||
28 | + = yield :scripts | ||
0 | \ No newline at end of file | 29 | \ No newline at end of file |
app/views/mailer/error_notification.text.erb
@@ -2,6 +2,6 @@ An error has just occurred in <%= @notice.err.environment %>: <%= @notice.err.me | @@ -2,6 +2,6 @@ An error has just occurred in <%= @notice.err.environment %>: <%= @notice.err.me | ||
2 | 2 | ||
3 | This error has occurred <%= pluralize @notice.err.notices.count, 'time' %>. You should really look into it here: | 3 | This error has occurred <%= pluralize @notice.err.notices.count, 'time' %>. You should really look into it here: |
4 | 4 | ||
5 | - <%= error_notice_url(@notice.err, @notice) %> | 5 | + <%= project_err_notice_url(@project, @notice.err, @notice) %> |
6 | 6 | ||
7 | <%= render :partial => 'signature' %> | 7 | <%= render :partial => 'signature' %> |
8 | \ No newline at end of file | 8 | \ No newline at end of file |
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +- content_for :title, 'Projects' | ||
2 | + | ||
3 | +%table | ||
4 | + %thead | ||
5 | + %tr | ||
6 | + %th Project Name | ||
7 | + %th Errors | ||
8 | + %tbody | ||
9 | + - @projects.each do |project| | ||
10 | + %tr | ||
11 | + %td= link_to project.name, project_path(project) | ||
12 | + %td= link_to project.errs.unresolved.count, project_errs_path(project) | ||
0 | \ No newline at end of file | 13 | \ No newline at end of file |
config/routes.rb
@@ -6,8 +6,13 @@ Hypnotoad::Application.routes.draw do | @@ -6,8 +6,13 @@ Hypnotoad::Application.routes.draw do | ||
6 | 6 | ||
7 | resources :notices, :only => [:show] | 7 | resources :notices, :only => [:show] |
8 | resources :deploys, :only => [:show] | 8 | resources :deploys, :only => [:show] |
9 | - resources :errors do | ||
10 | - resources :notices | 9 | + |
10 | + resources :projects do | ||
11 | + resources :errs do | ||
12 | + resources :notices | ||
13 | + end | ||
11 | end | 14 | end |
12 | 15 | ||
16 | + root :to => 'projects#index' | ||
17 | + | ||
13 | end | 18 | end |
@@ -0,0 +1,161 @@ | @@ -0,0 +1,161 @@ | ||
1 | +html { | ||
2 | + margin: 0; padding: 0; | ||
3 | + color: #585858; background-color: #E2E2E2; | ||
4 | + font-size: 62.8%; font-family: "Lucida Grande","Lucida Sans",Arial,sans-serif; | ||
5 | +} | ||
6 | +body { | ||
7 | + margin: 0 auto; padding: 0 5px; width: 900px; | ||
8 | + font-size: 1.3em; line-height: 1.4em; | ||
9 | +} | ||
10 | + | ||
11 | +/* Convenience Classes */ | ||
12 | +.clear { clear: both; } | ||
13 | +.clear-left { clear: left; } | ||
14 | +.clear-right { clear: right; } | ||
15 | +.nowrap { white-space: nowrap; } | ||
16 | + | ||
17 | +/* Headings */ | ||
18 | +h1, h2, h3, h4, h5, h6 { padding: 0.2em 0; margin-bottom: 1em; border-bottom: 1px solid #E2E2E2;} | ||
19 | +h1 { font-size: 2.0em; line-height: 1.2em; } | ||
20 | +h2 { font-size: 1.7em; line-height: 1.2em; } | ||
21 | +h3 { font-size: 1.5em; line-height: 1.2em; } | ||
22 | +h4 { font-size: 1.3em; line-height: 1.2em; } | ||
23 | +h5 { font-size: 1.1em; line-height: 1.2em; } | ||
24 | +h6 { font-size: 0.9em; line-height: 1.2em; } | ||
25 | + | ||
26 | +/* General */ | ||
27 | +p { margin-bottom: 1em; } | ||
28 | + | ||
29 | +/* Links */ | ||
30 | +a { color: #BF3838; text-decoration: none;} | ||
31 | +a:visited { color: #674646;} | ||
32 | +a:hover { color: #BF3838; text-decoration: underline; } | ||
33 | +a.action { float: right; font-size: 0.9em;} | ||
34 | + | ||
35 | +/* Header */ | ||
36 | +#header { | ||
37 | + height: 90px; | ||
38 | + position: relative; | ||
39 | +} | ||
40 | +#header #site-name { | ||
41 | + font-size: 2.31em; font-weight: bold; line-height: 90px; text-decoration: none; text-transform: uppercase; | ||
42 | + color: #585858; | ||
43 | +} | ||
44 | +#header #session-links { | ||
45 | + position: absolute; top: 15px; right: 0; | ||
46 | + font-size: 0.9em; | ||
47 | +} | ||
48 | + | ||
49 | +/* Navigation */ | ||
50 | +#nav-bar { | ||
51 | + margin-bottom: 20px; | ||
52 | + background-color: #585858; | ||
53 | +} | ||
54 | +#nav-bar li { float: left; } | ||
55 | +#nav-bar li a { | ||
56 | + display: block; padding: 20px 30px; | ||
57 | + color: #fff; | ||
58 | + font-size: 1.231em; font-weight: bold; line-height: 1em; text-decoration: none; | ||
59 | +} | ||
60 | +#nav-bar li a:hover { background-color: #686868; } | ||
61 | +#nav-bar li a.active { background-color: #BF3838;} | ||
62 | + | ||
63 | +/* Content Title */ | ||
64 | +#content-title { | ||
65 | + padding: 30px 20px; border: 1px solid #C6C6C6; border-bottom: none; | ||
66 | + background-color: #FFF; | ||
67 | +} | ||
68 | +#content-title h1 { | ||
69 | + padding: 0; margin: 0; border: none; | ||
70 | + font-size: 2em; line-height: 1em; font-weight: bold; font-style: italic; font-family: georgia, times, serif; | ||
71 | +} | ||
72 | +#content-title .meta { font-size: 0.9em; color: #787878; } | ||
73 | + | ||
74 | +/* Action Bar */ | ||
75 | +#action-bar { | ||
76 | + padding: 5px 20px; border: 1px solid #C6C6C6; border-top:none; border-bottom: none; | ||
77 | + color: #E2E2E2; background-color: #585858; | ||
78 | + text-align: right; | ||
79 | +} | ||
80 | +#action-bar a { color: #E2E2E2; text-decoration: none; } | ||
81 | +#action-bar a:hover { color: #FFF; text-decoration: underline;} | ||
82 | + | ||
83 | +/* Content */ | ||
84 | +#content { | ||
85 | + padding: 20px; border: 1px solid #C6C6C6; | ||
86 | + background-color: #FFF; | ||
87 | +} | ||
88 | + | ||
89 | +/* Footer */ | ||
90 | +#footer { | ||
91 | + padding: 20px 0; | ||
92 | + font-size: 0.8em; text-align: center; | ||
93 | + color: #929292; | ||
94 | +} | ||
95 | + | ||
96 | +/* Flash Messages */ | ||
97 | +#flash-messages li { | ||
98 | + padding: 13px 45px; margin-bottom:25px; border: 1px solid #C6C6C6; | ||
99 | + background-color: #F9F9F9; | ||
100 | + line-height: 1em; | ||
101 | +} | ||
102 | +#flash-messages .notice, #flash-messages .success { background: transparent url(images/icons/success.png) 16px 50% no-repeat; } | ||
103 | +#flash-messages .error { background: transparent url(images/icons/error.png) 16px 50% no-repeat; } | ||
104 | + | ||
105 | +/* Forms */ | ||
106 | +form { | ||
107 | + width: 620px; | ||
108 | +} | ||
109 | +form > div, form fieldset > div { margin: 1em 0;} | ||
110 | +form fieldset { | ||
111 | + padding: 0.8em; margin-bottom: 1em; | ||
112 | + background-color: #F0F0F0; border: 1px solid #C6C6C6; border-left: none; border-right: none; | ||
113 | +} | ||
114 | +form fieldset legend { | ||
115 | + font-size: 1.2em; font-weight: bold; text-transform: uppercase; | ||
116 | + color: #555; | ||
117 | +} | ||
118 | +form label { | ||
119 | + font-weight: bold; text-transform: uppercase; line-height: 1.6em; | ||
120 | + display: block; | ||
121 | +} | ||
122 | +form label.inline { display: inline; } | ||
123 | +form .required label { color: #BF3838;} | ||
124 | +form input[type=text], form input[type=password] { | ||
125 | + width: 96%; padding: 0.8em; | ||
126 | + font-size: 1em; | ||
127 | + color: #787878; border: 1px solid #C6C6C6; | ||
128 | +} | ||
129 | +form textarea { | ||
130 | + width: 100%; padding: 0.8em; | ||
131 | + font-size: inherit; font-family: inherit; | ||
132 | + color: #787878; border: 1px solid #C6C6C6; | ||
133 | +} | ||
134 | +form textarea.short { height: 8em; } | ||
135 | +form textarea.supershort { height: 4em; } | ||
136 | +form input[type=submit] { | ||
137 | + display:block; width: auto; padding: 0.5em; | ||
138 | + font-size: 1.2em; line-height: 1em; text-transform: uppercase; | ||
139 | + border: none; color: #FFF; background-color: #387fc1; | ||
140 | +} | ||
141 | +form > div > span { | ||
142 | + display: block; margin-top: 0.5em; | ||
143 | + font-size: 0.85em; | ||
144 | + color: #787878; | ||
145 | +} | ||
146 | + | ||
147 | +/* Tables */ | ||
148 | +table { width: 100%; border: 1px solid #C6C6C6; margin-bottom: 1.5em; } | ||
149 | +table th, table td { border-bottom: 1px solid #C6C6C6; padding: 10px 8px; text-align: left; } | ||
150 | +table th { background-color: #E2E2E2; font-weight: bold; text-transform: uppercase; } | ||
151 | +table tbody tr:nth-child(odd) td { background-color: #F9F9F9; } | ||
152 | +table .main { width: 100%; } | ||
153 | + | ||
154 | +/* HTML Styling */ | ||
155 | +.html { padding-left: 1em; border-left: 2px solid #C6C6C6;} | ||
156 | +.html h1, .html h2, .html h3, .html h4, .html h5, .html h6 { | ||
157 | + border: none; | ||
158 | +} | ||
159 | +.html ul, .html ol { margin-left: 2em; margin-bottom: 1em; } | ||
160 | +.html ul li { margin-bottom: 0.5em; list-style: disc; } | ||
161 | +.html ol li { margin-bottom: 0.5em; list-style: decimal; } |
No preview for this file type
473 Bytes
695 Bytes
157 Bytes
393 Bytes
133 Bytes
@@ -0,0 +1,74 @@ | @@ -0,0 +1,74 @@ | ||
1 | +/* | ||
2 | + * Reset.css - by Eric Meyer | ||
3 | + * Modified for NewsStand | ||
4 | + * By Jared Pace | ||
5 | + * Codeword: Studios | ||
6 | + */ | ||
7 | + | ||
8 | + html, body, div, span, applet, object, iframe, | ||
9 | + h1, h2, h3, h4, h5, h6, p, blockquote, pre, | ||
10 | + a, abbr, acronym, address, big, cite, code, | ||
11 | + del, dfn, em, font, img, ins, kbd, q, s, samp, | ||
12 | + small, strike, strong, sub, sup, tt, var, | ||
13 | + b, u, i, center, | ||
14 | + dl, dt, dd, ol, ul, li, | ||
15 | + fieldset, form, label, legend, | ||
16 | + table, caption, tbody, tfoot, thead, tr, th, td { | ||
17 | + margin: 0; | ||
18 | + padding: 0; | ||
19 | + border: 0; | ||
20 | + outline: 0; | ||
21 | + font-size: 100%; | ||
22 | + vertical-align: baseline; | ||
23 | + background: transparent; | ||
24 | + } | ||
25 | + body { | ||
26 | + line-height: 1; | ||
27 | + } | ||
28 | + ol, ul { | ||
29 | + list-style: none; | ||
30 | + } | ||
31 | + blockquote, q { | ||
32 | + quotes: none; | ||
33 | + } | ||
34 | + td { | ||
35 | + vertical-align: top; | ||
36 | +} | ||
37 | + | ||
38 | + /* remember to define focus styles! */ | ||
39 | + :focus { | ||
40 | + outline: 0; | ||
41 | + } | ||
42 | + | ||
43 | + /* remember to highlight inserts somehow! */ | ||
44 | + ins { | ||
45 | + text-decoration: none; | ||
46 | + } | ||
47 | + del { | ||
48 | + text-decoration: line-through; | ||
49 | + } | ||
50 | + | ||
51 | + /* tables still need 'cellspacing="0"' in the markup */ | ||
52 | + table { | ||
53 | + border-collapse: collapse; | ||
54 | + border-spacing: 0; | ||
55 | + } | ||
56 | + | ||
57 | + sup, sub { | ||
58 | + height: 0; | ||
59 | + line-height: 1; | ||
60 | + vertical-align: baseline; | ||
61 | + _vertical-align: bottom; | ||
62 | + position: relative; | ||
63 | + font-size: 0.8em; | ||
64 | + } | ||
65 | + | ||
66 | + sup { | ||
67 | + bottom: 1ex; | ||
68 | + } | ||
69 | + | ||
70 | + sub { | ||
71 | + top: .5ex; | ||
72 | + } | ||
73 | + | ||
74 | +p { margin-bottom: 1em; } | ||
0 | \ No newline at end of file | 75 | \ No newline at end of file |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +require 'spec_helper' | ||
2 | + | ||
3 | +describe ProjectsController do | ||
4 | + | ||
5 | + describe "GET /projects" do | ||
6 | + it 'finds all projects' do | ||
7 | + 3.times { Factory(:project) } | ||
8 | + projects = Project.all | ||
9 | + get :index | ||
10 | + assigns(:projects).should == projects | ||
11 | + end | ||
12 | + end | ||
13 | + | ||
14 | +end |