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 @@ |
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 | 38 | \ No newline at end of file | ... | ... |
app/models/project.rb
app/views/layouts/application.html.erb
... | ... | @@ -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 | 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 | 2 | |
3 | 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 | 7 | <%= render :partial => 'signature' %> |
8 | 8 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | 13 | \ No newline at end of file | ... | ... |
config/routes.rb
... | ... | @@ -6,8 +6,13 @@ Hypnotoad::Application.routes.draw do |
6 | 6 | |
7 | 7 | resources :notices, :only => [:show] |
8 | 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 | 14 | end |
12 | 15 | |
16 | + root :to => 'projects#index' | |
17 | + | |
13 | 18 | end | ... | ... |
... | ... | @@ -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 @@ |
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 | 75 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | ... | ... |