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 |