From 8b7621793fe5f8fa55c955045a71821c53d4759f Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:26:35 -0700 Subject: start of new ui - css changes, layout changes, navigation changes. --- app/assets/stylesheets/application.scss | 17 +++--- app/assets/stylesheets/leap.scss | 65 +++++++++++++++++++++++ app/helpers/application_helper.rb | 17 ++++++ app/helpers/navigation_helper.rb | 82 +++++++++++++++++++++++++++++ app/views/home/_home_text.html.haml | 3 ++ app/views/home/index.html.haml | 23 ++++---- app/views/layouts/_footer.html.haml | 0 app/views/layouts/_header.html.haml | 3 ++ app/views/layouts/_masthead.html.haml | 4 ++ app/views/layouts/_masthead_large.html.haml | 3 ++ app/views/layouts/_navigation.html.haml | 17 ++++-- app/views/layouts/application.html.haml | 30 +++++++---- config/defaults.yml | 4 +- config/locales/en.yml | 7 +++ 14 files changed, 239 insertions(+), 36 deletions(-) create mode 100644 app/assets/stylesheets/leap.scss create mode 100644 app/helpers/navigation_helper.rb create mode 100644 app/views/home/_home_text.html.haml create mode 100644 app/views/layouts/_footer.html.haml create mode 100644 app/views/layouts/_header.html.haml create mode 100644 app/views/layouts/_masthead.html.haml create mode 100644 app/views/layouts/_masthead_large.html.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index bb3b8bc..298a758 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,23 +1,18 @@ // // import custom scss, content to be set in deployment. // -@import "tail"; +@import "head"; // // import bootstrap. // @import "bootstrap"; -body { - padding: 40px; -} @import "bootstrap-responsive"; -table.table-hover .btn { - opacity: 0; -} -table.table-hover tr:hover .btn { - opacity: 1; -} -@import "bootstrap-editable"; + +// +// LEAP web app specific overrides +// +@import "leap"; // // import custom scss, content to be set in deployment. diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss new file mode 100644 index 0000000..42638eb --- /dev/null +++ b/app/assets/stylesheets/leap.scss @@ -0,0 +1,65 @@ + +table.table-hover .btn { + opacity: 0; +} +table.table-hover tr:hover .btn { + opacity: 1; +} + +.debug { + outline: 1px solid red; +} + +// +// Icons +// + + +// force a black icon, even if bootstrap thinks differently +.icon-black { + background-image: url(/assets/glyphicons-halflings.png) !important; +} + +// +// Typography +// + +.first { + margin-top: 0; + padding-top: 0; +} + +// +// Boring default masthead +// + +#masthead { + background: #eee; + margin-bottom: 10px; + border-bottom: 1px solid #e6e6e6; + .title { + padding: 20px; + font-size: 1.25em; + } + .sitename { + font-weight: bold; + } +} + +// +// Side Navigation +// + +.sidenav { + @extend .nav-tabs; + @extend .nav-stacked; + box-shadow: 0 2px 4px rgba(0,0,0,.1); + li.active { + a, a:hover { + background-color: $blueDark; + color: $white; + border-color: darken($blueDark, 10%); + cursor: pointer; + } + } +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..db70109 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,19 @@ module ApplicationHelper + + # + # markup for bootstrap icon + # + # http://twitter.github.io/bootstrap/base-css.html#icons + # + def icon(name, color=nil) + if color.nil? + color_class = nil + elsif color == :black + color_class = 'icon-black' + elsif color == :white + color_class = 'icon-white' + end + " ".html_safe + end + end diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb new file mode 100644 index 0000000..19cb934 --- /dev/null +++ b/app/helpers/navigation_helper.rb @@ -0,0 +1,82 @@ +module NavigationHelper + + # + # used to create a side navigation link. + # + # Signature is the same as link_to, except it accepts an :active value in the html_options + # + def link_to_navigation(*args) + if args.last.is_a? Hash + html_options = args.pop.dup + active_class = html_options.delete(:active) ? 'active' : nil + html_options[:class] = [html_options[:class], active_class].join(' ') + args << html_options + else + active_class = nil + end + content_tag :li, :class => active_class do + link_to(*args) + end + end + + # + # returns true if params[:action] matches one of the args. + # + def action?(*actions) + actions.detect do |action| + if action.is_a? String + action == action_string + elsif action.is_a? Symbol + if action == :none + action_string == nil + else + action == action_symbol + end + end + end + end + + # + # returns true if params[:controller] matches one of the args. + # + # for example: + # controller?(:me, :home) + # controller?('groups/') <-- matches any controller in namespace 'groups' + # + def controller?(*controllers) + controllers.each do |cntr| + if cntr.is_a? String + if cntr.ends_with?('/') + return true if controller_string.starts_with?(cntr.chop) + end + return true if cntr == controller_string + elsif cntr.is_a? Symbol + return true if cntr == controller_symbol + end + end + return false + end + + private + + def controller_string + @controller_string ||= params[:controller].to_s.gsub(/^\//, '') + end + + def controller_symbol + @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym + end + + def action_string + params[:action] + end + + def action_symbol + @action_symbol ||= if params[:action].present? + params[:action].to_sym + else + nil + end + end + +end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml new file mode 100644 index 0000000..1055091 --- /dev/null +++ b/app/views/home/_home_text.html.haml @@ -0,0 +1,3 @@ +Welcome to the LEAP web application. + +For more information, visit #{link_to('leap.se', 'https://leap.se')} \ No newline at end of file diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index c02dcad..0b3bbf9 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,11 +1,16 @@ -Try to fetch a -= link_to "cert", cert_path +.row-fluid + .span8 + = render 'home_text' + .span4 + = render '/login_or_signup' -%p -Create a -= link_to "ticket", new_ticket_path +- if Rails.env == 'development' + .row-fluid + %hr + %p + Try to fetch a + = link_to "cert", cert_path -- if logged_in? - %p - See all - = link_to "tickets", tickets_path + %p + Create a + = link_to "ticket", new_ticket_path diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml new file mode 100644 index 0000000..e69de29 diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml new file mode 100644 index 0000000..aa4054b --- /dev/null +++ b/app/views/layouts/_header.html.haml @@ -0,0 +1,3 @@ +- if user + %strong.user_address + = user.email_address diff --git a/app/views/layouts/_masthead.html.haml b/app/views/layouts/_masthead.html.haml new file mode 100644 index 0000000..280f2c2 --- /dev/null +++ b/app/views/layouts/_masthead.html.haml @@ -0,0 +1,4 @@ +.title + %span.sitename + = APP_CONFIG[:domain] + = t(:user_control_panel) \ No newline at end of file diff --git a/app/views/layouts/_masthead_large.html.haml b/app/views/layouts/_masthead_large.html.haml new file mode 100644 index 0000000..6bb1943 --- /dev/null +++ b/app/views/layouts/_masthead_large.html.haml @@ -0,0 +1,3 @@ +.title + %span.sitename + = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index b75eed7..7cd0f38 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,6 +1,13 @@ -= link_to "Leap Web", root_path, :class => 'brand' -%ul.nav - // = render '/tickets/nav' +//= link_to "Leap Web", root_path, :class => 'brand' +//%ul.nav +// // = render '/tickets/nav' +// +//%ul.nav.pull-right +// = render '/sessions/nav' -%ul.nav.pull-right - = render '/sessions/nav' +%ul.nav.sidenav + = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) + = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) + =# link_to_navigation t(:email_settings), edit_email_path(user), :active => controller?(:emails) + = link_to_navigation t(:support_tickets), tickets_path, :active => controller?(:tickets) + = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e6d22f0..719d699 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -9,15 +9,27 @@ = csrf_meta_tags = yield(:head) %body - %header.navbar.navbar-fixed-top - %nav.navbar-inner - .container - = render 'layouts/navigation' - #main{:role => "main"} - .container - .content - .row + #masthead + - if logged_in? + = render 'layouts/masthead' + - else + = render 'layouts/masthead_large' + #main + .container-fluid + - if logged_in? + .row-fluid .span12 + = render 'layouts/header' + .row-fluid + .span2 + = render 'layouts/navigation' + .span10 = render 'layouts/messages' = yield - %footer + - else + .row-fluid + .span12 + = render 'layouts/messages' + = yield + #footer + = render 'layouts/footer' diff --git a/config/defaults.yml b/config/defaults.yml index f3b92c0..25537fe 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -17,7 +17,7 @@ development: <<: *dev_ca <<: *cert_options admins: [admin, admin2] - domain: develop.me + domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' test: @@ -30,4 +30,4 @@ test: production: <<: *cert_options admins: [] - domain: deploy.me + domain: example.net diff --git a/config/locales/en.yml b/config/locales/en.yml index fc61c31..40cdb4a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -4,3 +4,10 @@ en: hello: "Hello world" no_such_thing: "No such %{thing}." + + overview: "Overview" + user_control_panel: "user control panel" + + created: "Created" + updated: "Updated" + -- cgit v1.2.3 From 8550dcb0096017f94f855cad75dc61da63d92970 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:01 -0700 Subject: new ui - ticket navigation --- help/app/helpers/tickets_helper.rb | 20 ++++++++++++++++---- help/app/views/tickets/_order-nav.html.haml | 2 +- help/app/views/tickets/_status-nav.html.haml | 2 ++ help/app/views/tickets/_table-nav.html.haml | 9 ++++----- help/app/views/tickets/index.html.haml | 23 +++++++++-------------- help/app/views/tickets/new.html.haml | 25 ++++++++++++++++--------- help/config/locales/en.yml | 5 +++++ 7 files changed, 53 insertions(+), 33 deletions(-) diff --git a/help/app/helpers/tickets_helper.rb b/help/app/helpers/tickets_helper.rb index bd2c069..8b4ff71 100644 --- a/help/app/helpers/tickets_helper.rb +++ b/help/app/helpers/tickets_helper.rb @@ -1,7 +1,7 @@ module TicketsHelper def status - params[:open_status] || 'open' + params[:open_status] end def admin @@ -14,8 +14,14 @@ module TicketsHelper end def link_to_status(new_status) - label = new_status + ' issues' - link_to label, :open_status => new_status, :admin_status => admin, :sort_order => order + if new_status == "open" + label = t(:open_tickets) + elsif new_status == "closed" + label = t(:closed_tickets) + elsif new_status == "all" + label = t(:all_tickets) + end + link_to label, tickets_path(:open_status => new_status, :admin_status => admin, :sort_order => order) end def link_to_order(order_field) @@ -35,8 +41,14 @@ module TicketsHelper direction = 'desc' end + if order_field == 'updated' + label = t(:updated) + elsif order_field == 'created' + label = t(:created) + end + link_to :sort_order => order_field + '_at_' + direction, :open_status => status, :admin_status => admin do - arrow + order_field + ' at' + arrow + label end end diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml index 9e8bcee..a2ddb72 100644 --- a/help/app/views/tickets/_order-nav.html.haml +++ b/help/app/views/tickets/_order-nav.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-pills.pull-right +%ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} %li{:class=> ("active" if order.start_with? 'created_at' )} = link_to_order('created') %li{:class=> ("active" if order.start_with? 'updated_at' )} diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index 69f4248..e1dca84 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -5,3 +5,5 @@ = link_to_status 'closed' %li{:class => ("active" if status == 'all')} = link_to_status 'all' + %li{:class => ("active" if action?(:new))} + = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index 635b59b..45ebfb2 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,5 +1,4 @@ -.row - .span6 - = render 'tickets/status-nav' - .span4 - = render 'tickets/order-nav' +- unless action?(:new) + = render 'tickets/order-nav' += render 'tickets/status-nav' + diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index 23a503d..a3cbfcf 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,17 +1,12 @@ -%h1 tickets index +- if admin? + = render 'tickets/admin-nav' -Create a -= link_to "new ticket", new_ticket_path += render 'tickets/table-nav' + +%table.table-striped.table-bordered.table-hover + //{:style => "width:100%;"} + %tbody + = render @tickets.all += paginate @tickets -= #%div{"data-pjax-container" => ""} # not sure how to get this working right -.row - .span2 - - if admin? - = render 'tickets/admin-nav' - .span10 - = render 'tickets/table-nav' - %table.table-striped.table-bordered.table-hover{:style => "width:100%;"} - %tbody - = render @tickets.all - = paginate @tickets diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 1aa689b..5442910 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,10 +1,17 @@ -.span12 - %h2=t :new_ticket - = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| - = f.input :title - = f.input :email if !current_user #hmm--might authenticated users want to submit an alternate email? + +//%h2.first= t :new_ticket + += render 'tickets/table-nav' + += simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| + = f.input :title + - if user + = f.input :email, input_html: {value: user.email_address} + = f.input :regarding_user, input_html: {value: user.login} + - else + = f.input :email = f.input :regarding_user - = render :partial => 'new_comment', :locals => {:f => f} - .form-actions - = f.button :submit, :class => 'btn-primary' - = link_to t(:cancel), tickets_path, :class => :btn + = render :partial => 'new_comment', :locals => {:f => f} + .form-actions + = f.button :submit, :class => 'btn-primary' + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 4ea662a..2835e4e 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -1,2 +1,7 @@ en: access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" + support_tickets: "Support Tickets" + all_tickets: "All Tickets" + open_tickets: "Open Tickets" + closed_tickets: "Closed Tickets" + new_ticket: "New Ticket" \ No newline at end of file -- cgit v1.2.3 From 742f01f1ca5f1006fba3c5c74489f920acca43b3 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:30 -0700 Subject: add link to simple_form to the docs --- DEVELOP.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/DEVELOP.md b/DEVELOP.md index 9548774..e19b827 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -1,5 +1,11 @@ # Development # +## Hacking ## + +Some tips on modifying the views: + +* Many of the forms use [simple_form gem](https://github.com/plataformatec/simple_form) + ## Engines ## Leap Web consists of different Engines. They live in their own subdirectory and are included through bundler via their path. This way changes to the engines immediately affect the server as if they were in the main `app` directory. @@ -37,7 +43,7 @@ require File.expand_path('../../lib/leap_web/version.rb', __FILE__) # ... Gem::Specification.new do |s| # ... - s.add_dependency "rails" + s.add_dependency "rails" s.add_dependency "leap_web_core", LeapWeb::Version end ``` -- cgit v1.2.3 From a089c452a414e7d34d49f0e2703c632141361e2b Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:55 -0700 Subject: new ui - initial user changes --- .../app/controllers/account_settings_controller.rb | 0 users/app/controllers/email_settings_controller.rb | 0 users/app/controllers/overviews_controller.rb | 9 ++++++++ users/app/controllers/users_base_controller.rb | 18 ++++++++++++++++ users/app/helpers/users_helper.rb | 2 +- users/app/views/_login_or_signup.html.haml | 25 ++++++++++++++++++++++ users/app/views/emails/edit.html.haml | 5 +++++ users/app/views/overviews/show.html.haml | 15 +++++++++++++ users/app/views/sessions/_new.html.haml | 7 ++++++ users/app/views/sessions/new.html.haml | 17 ++++++++------- users/app/views/users/_login_field.html.haml | 2 +- users/app/views/users/_new.html.haml | 7 ++++++ users/app/views/users/_password_fields.html.haml | 4 ++-- users/app/views/users/edit.html.haml | 20 +++-------------- users/app/views/users/new.html.haml | 5 ++--- users/config/locales/en.yml | 17 +++++++++------ users/config/routes.rb | 3 +++ 17 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 users/app/controllers/account_settings_controller.rb create mode 100644 users/app/controllers/email_settings_controller.rb create mode 100644 users/app/controllers/overviews_controller.rb create mode 100644 users/app/controllers/users_base_controller.rb create mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/emails/edit.html.haml create mode 100644 users/app/views/overviews/show.html.haml create mode 100644 users/app/views/sessions/_new.html.haml create mode 100644 users/app/views/users/_new.html.haml diff --git a/users/app/controllers/account_settings_controller.rb b/users/app/controllers/account_settings_controller.rb new file mode 100644 index 0000000..e69de29 diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb new file mode 100644 index 0000000..e69de29 diff --git a/users/app/controllers/overviews_controller.rb b/users/app/controllers/overviews_controller.rb new file mode 100644 index 0000000..52ce267 --- /dev/null +++ b/users/app/controllers/overviews_controller.rb @@ -0,0 +1,9 @@ +class OverviewsController < UsersBaseController + + before_filter :authorize + before_filter :fetch_user + + def show + end + +end diff --git a/users/app/controllers/users_base_controller.rb b/users/app/controllers/users_base_controller.rb new file mode 100644 index 0000000..dc2fa16 --- /dev/null +++ b/users/app/controllers/users_base_controller.rb @@ -0,0 +1,18 @@ +# +# common base class for all user related controllers +# + +class UsersBaseController < ApplicationController + + protected + + def fetch_user + @user = User.find_by_param(params[:user_id] || params[:id]) + if !@user && admin? + redirect_to users_url, :alert => t(:no_such_thing, :thing => 'user') + elsif !admin? && @user != current_user + access_denied + end + end + +end diff --git a/users/app/helpers/users_helper.rb b/users/app/helpers/users_helper.rb index 9feae62..559b3f7 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -24,7 +24,7 @@ module UsersHelper end def user_form_html_classes(options) - classes = %W/form-horizontal user form/ + classes = %W/user form/ classes << options[:legend] classes << (@user.new_record? ? 'new' : 'edit') classes.compact diff --git a/users/app/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml new file mode 100644 index 0000000..b353526 --- /dev/null +++ b/users/app/views/_login_or_signup.html.haml @@ -0,0 +1,25 @@ +// +// displays a little widget to login or sign up +// + +%ul.nav.nav-tabs + %li.active + %a{:href => ''}= t(:login) + %li + = link_to t(:signup), new_user_path + += render 'sessions/new' + +// +// this is nice, but it doesn't work because both forms have the same names for fields. +// +// %ul.nav.nav-tabs +// %li.active +// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) +// %li +// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) +// .tab-content +// #login.tab-pane.active +// = render 'sessions/new' +// #signup.tab-pane +// = render 'users/new' diff --git a/users/app/views/emails/edit.html.haml b/users/app/views/emails/edit.html.haml new file mode 100644 index 0000000..b44b569 --- /dev/null +++ b/users/app/views/emails/edit.html.haml @@ -0,0 +1,5 @@ + + += user_form_with 'public_key_field', :legend => :public_key += user_form_with 'email_forward_field', :legend => :forward_email += user_form_with 'email_aliases', :legend => :add_email_alias diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml new file mode 100644 index 0000000..eda9899 --- /dev/null +++ b/users/app/views/overviews/show.html.haml @@ -0,0 +1,15 @@ +%p + Username: + = @user.login + +%p + User since: + = @user.created_at + +%p + Last update: + = @user.updated_at + +%p + Quota: + N/A \ No newline at end of file diff --git a/users/app/views/sessions/_new.html.haml b/users/app/views/sessions/_new.html.haml new file mode 100644 index 0000000..640fec5 --- /dev/null +++ b/users/app/views/sessions/_new.html.haml @@ -0,0 +1,7 @@ +- @session ||= Session.new += simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| + = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } + = f.input :password, :required => false, :input_html => { :id => :srp_password } + .form-actions + = f.button :submit, :value => t(:login), :class => 'btn-primary' + // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index a04f584..4d14801 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -1,8 +1,9 @@ -.span8.offset2 - %h2=t :login - = simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| - %legend=t :login_message - = f.input :login, :input_html => { :id => :srp_username } - = f.input :password, :required => true, :input_html => { :id => :srp_password } - = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn +//= render 'sessions/new' + +%h2=t :login += simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| + %legend=t :login_message + = f.input :login, :input_html => { :id => :srp_username } + = f.input :password, :required => true, :input_html => { :id => :srp_password } + = f.button :submit, :value => t(:login), :class => 'btn-primary' + = link_to t(:cancel), root_url, :class => :btn \ No newline at end of file diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml index 8ab36c3..e58c36f 100644 --- a/users/app/views/users/_login_field.html.haml +++ b/users/app/views/users/_login_field.html.haml @@ -1 +1 @@ -= f.input :login, :input_html => { :id => :srp_username } += f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } diff --git a/users/app/views/users/_new.html.haml b/users/app/views/users/_new.html.haml new file mode 100644 index 0000000..3d0f2ac --- /dev/null +++ b/users/app/views/users/_new.html.haml @@ -0,0 +1,7 @@ +- @user ||= User.new += user_form do |f| + = render :partial => 'users/login_field', :locals => {:f => f} + = render :partial => 'users/password_fields', :locals => {:f => f} + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' + = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml index 47b7b07..7b3358d 100644 --- a/users/app/views/users/_password_fields.html.haml +++ b/users/app/views/users/_password_fields.html.haml @@ -1,2 +1,2 @@ -= f.input :password, :required => true, :validate => true, :input_html => { :id => :srp_password } -= f.input :password_confirmation, :required => true, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } += f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } += f.input :password_confirmation, :required => false, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index 97bd48d..4e70d69 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,17 +1,3 @@ -.span8.offset2 - %h2=t :settings - - tabs = [] - - content_for :account do - = user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user - = render 'cancel_account' - - tabs << :account - - if @user == current_user - - content_for :email do - %legend=t :email_address - =t :associated_email - = render @user.email_address, :as => :span - = user_form_with 'public_key_field', :legend => :public_key - = user_form_with 'email_forward_field', :legend => :forward_email - = user_form_with 'email_aliases', :legend => :add_email_alias - - tabs << :email - = render 'tabs/tabs', :tabs => tabs += user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user += render 'cancel_account' + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index 98cccb0..d8a43d5 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -4,8 +4,7 @@ %legend= t(:signup_message) = render :partial => 'login_field', :locals => {:f => f} = render :partial => 'password_fields', :locals => {:f => f} - .pull-right - = f.button :submit, :class => 'btn-primary' + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' = link_to t(:cancel), root_url, :class => :btn - .clearfix diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 2077858..5192e30 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -1,9 +1,14 @@ en: - none: "None." - signup: "Sign up" + email_settings: "Email Settings" + account_settings: "Account Settings" + logout: "Logout" + none: "None" + signup: "Sign Up" signup_message: "Please create an account." cancel: "Cancel" - login: "Login" + login: "Log In" + username: "Username" + password: "Password" login_message: "Please login with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." @@ -19,13 +24,13 @@ en: user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored PGP key" + use_ascii_key: "Use ASCII-armored OpenPGP key" can_retype_old_password: "Retype your old password if you would like to keep that" associated_email: "The associated email address is" activemodel: models: - user: + user: one: User other: "%{count} Users" simple_form: @@ -39,4 +44,4 @@ en: placeholders: user: email_forward: "my_other_email@domain.net" - + diff --git a/users/config/routes.rb b/users/config/routes.rb index 9a9a40e..d07cda9 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -14,6 +14,9 @@ Rails.application.routes.draw do get "signup" => "users#new", :as => "signup" resources :users do + resource :overview, :only => [:show] + resource :email_settings, :only => [:edit, :update] + resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From c0dcf6bd6ae163ab39886a86c337d008ac2365a6 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:33:19 -0700 Subject: new ui for tickets --- app/assets/stylesheets/leap.scss | 73 ++++++++++++-- core/config/initializers/simple_form_bootstrap.rb | 12 +++ help/README.md | 1 + help/Readme.md | 0 help/app/controllers/tickets_controller.rb | 109 +++++++++++---------- help/app/views/tickets/_admin-nav.html.haml | 10 +- help/app/views/tickets/_comment.html.haml | 34 +++---- help/app/views/tickets/_edit_form.html.haml | 46 +++++++++ help/app/views/tickets/_new_comment.html.haml | 4 - help/app/views/tickets/_new_comment_form.html.haml | 13 +++ help/app/views/tickets/_table-nav.html.haml | 3 + help/app/views/tickets/_ticket.html.haml | 20 +--- help/app/views/tickets/_ticket_data.html.haml | 35 ------- help/app/views/tickets/index.html.haml | 21 ++-- help/app/views/tickets/new.html.haml | 10 +- help/app/views/tickets/show.html.haml | 26 ++--- help/config/locales/en.yml | 12 ++- 17 files changed, 261 insertions(+), 168 deletions(-) create mode 100644 help/README.md delete mode 100644 help/Readme.md create mode 100644 help/app/views/tickets/_edit_form.html.haml delete mode 100644 help/app/views/tickets/_new_comment.html.haml create mode 100644 help/app/views/tickets/_new_comment_form.html.haml delete mode 100644 help/app/views/tickets/_ticket_data.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 42638eb..6b44986 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -6,27 +6,80 @@ table.table-hover tr:hover .btn { opacity: 1; } +.ticket { + td.user { + white-space: nowrap; + } + td.comment { + width: 100%; + } +} + +// +// UTILITY +// + .debug { outline: 1px solid red; } +.full-width { + width: 100%; +} + +.slim { + margin: 0; +} + +.first { + margin-top: 0; + padding-top: 0; +} + // -// Icons +// Typography // +input.large { + font-size: $baseFontSize * 1.25; + line-height: $baseLineHeight * 1.5; +} -// force a black icon, even if bootstrap thinks differently -.icon-black { - background-image: url(/assets/glyphicons-halflings.png) !important; +// +// FORMS +// + +// +// Sometimes we really want full width controls, but this flies in the face of +// what bootstrap does for control sizes, so we have to step on bootstrap's +// toes a bit to make this work. +// +input, textarea { + &.full-width { + height: inherit; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + } } // -// Typography +// Labels // -.first { - margin-top: 0; - padding-top: 0; +.label-clear { + background-color: $white; + text-shadow: none; + color: $black; +} + +// +// Icons +// + +// force a black icon, even if bootstrap thinks differently +.icon-black { + background-image: url(/assets/glyphicons-halflings.png) !important; } // @@ -56,9 +109,9 @@ table.table-hover tr:hover .btn { box-shadow: 0 2px 4px rgba(0,0,0,.1); li.active { a, a:hover { - background-color: $blueDark; + background-color: $linkColor; color: $white; - border-color: darken($blueDark, 10%); + border-color: darken($linkColor, 0%); cursor: pointer; } } diff --git a/core/config/initializers/simple_form_bootstrap.rb b/core/config/initializers/simple_form_bootstrap.rb index 1a22967..c949f5e 100644 --- a/core/config/initializers/simple_form_bootstrap.rb +++ b/core/config/initializers/simple_form_bootstrap.rb @@ -37,6 +37,18 @@ SimpleForm.setup do |config| end end + # + # when you don't want any bootstrap "control-group" or "controls" wrappers. + # + config.wrappers :none, :tag => 'div', :error_class => 'error' do |b| + b.use :html5 + b.use :placeholder + b.use :label + b.use :input + b.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + b.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } + end + # Wrappers for forms and inputs using the Twitter Bootstrap toolkit. # Check the Bootstrap docs (http://twitter.github.com/bootstrap) # to learn about the different styles for forms and inputs, diff --git a/help/README.md b/help/README.md new file mode 100644 index 0000000..c9573e6 --- /dev/null +++ b/help/README.md @@ -0,0 +1 @@ +Implements a simple, clean, and easy to use help ticketing system. \ No newline at end of file diff --git a/help/Readme.md b/help/Readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index 6562048..d478da9 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -3,10 +3,9 @@ class TicketsController < ApplicationController respond_to :html, :json #has_scope :open, :type => boolean - before_filter :set_strings - before_filter :authorize, :only => [:index] before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method + before_filter :set_title def new @ticket = Ticket.new @@ -20,61 +19,68 @@ class TicketsController < ApplicationController @ticket.created_by = current_user.id if logged_in? @ticket.email = current_user.email_address if logged_in? and current_user.email_address - flash[:notice] = 'Ticket was successfully created.' if @ticket.save + if @ticket.save + flash[:notice] = t(:thing_was_successfully_created, :thing => t(:ticket)) + end # cannot set this until ticket has been saved, as @ticket.id will not be set - flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) if !logged_in? and flash[:notice] + if !logged_in? and flash[:notice] + flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) + end respond_with(@ticket) - - end - -=begin - def edit - @ticket.comments.build - # build ticket comments? end -=end def show @comment = TicketComment.new if !@ticket - redirect_to tickets_path, :alert => "No such ticket" + redirect_to tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) return end end def update + if params[:commit] == t(:close) + @ticket.is_open = false + @ticket.save + redirect_to tickets_path + elsif params[:commit] == t(:open) + @ticket.is_open = true + @ticket.save + redirect_to @ticket + else + @ticket.attributes = cleanup_ticket_params(params[:ticket]) - if params[:post] #currently changes to title or is_open status - @ticket.attributes = params[:post] - # TODO: do we want to keep the history of title changes? one possibility was adding a comment that said something like 'user changed the title from a to b' + if params[:commit] == t(:reply_and_close) + @ticket.close + should_redirect = true + else + should_redirect = !logged_in? + end - else - params[:ticket][:comments_attributes] = nil if params[:ticket][:comments_attributes].values.first[:body].blank? #unset comments hash if no new comment was typed - @ticket.attributes = params[:ticket] #this will call comments_attributes= - @ticket.close if params[:commit] == @reply_close_str #this overrides is_open selection - # what if there is an update and no new comment? Confirm that there is a new comment to update posted_by: - @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) if @ticket.comments_changed? #protecting posted_by isn't working, so this should protect it. - end - if @ticket.changed? and @ticket.save - flash[:notice] = 'Ticket was successfully updated.' - if @ticket.is_open || !logged_in? - respond_with @ticket - else #for closed tickets with authenticated users, redirect to index. - redirect_to tickets_path + if @ticket.comments_changed? + @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) end - else - #redirect_to [:show, @ticket] # - flash[:alert] = 'Ticket has not been changed' - redirect_to @ticket - #respond_with(@ticket) # why does this go to edit?? redirect??? - end + if @ticket.changed? + if @ticket.save + flash[:notice] = t(:changes_saved) + if should_redirect + redirect_to tickets_path + else + redirect_to @ticket + end + else + respond_with @ticket + end + else + redirect_to @ticket + end + end end def index @all_tickets = Ticket.for_user(current_user, params, admin?) #for tests, useful to have as separate variable - @tickets = @all_tickets.page(params[:page]).per(10) + @tickets = @all_tickets.page(params[:page]).per(APP_CONFIG[:pagination_size]) end def destroy @@ -83,15 +89,26 @@ class TicketsController < ApplicationController redirect_to tickets_path end + protected + + def set_title + @title = t(:tickets) + end + private - def ticket_access? - @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by)) + # unset comments hash if no new comment was typed + def cleanup_ticket_params(ticket) + if ticket && ticket[:comments_attributes] + if ticket[:comments_attributes].values.first[:body].blank? + ticket[:comments_attributes] = nil + end + end + return ticket end - def set_strings - @post_reply_str = 'Post reply' #t :post_reply - @reply_close_str = 'Reply and close' #t :reply_and_close + def ticket_access? + @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by)) end def fetch_ticket @@ -102,13 +119,5 @@ class TicketsController < ApplicationController end access_denied unless ticket_access? end - # not using now, as we are using comment_attributes= from the Ticket model -=begin - def add_comment - comment = TicketComment.new(params[:comment]) - comment.posted_by = User.current.id if User.current #could be nil - comment.posted_at = Time.now # TODO: it seems strange to have this here, and not in model - @ticket.comments << comment - end -=end + end diff --git a/help/app/views/tickets/_admin-nav.html.haml b/help/app/views/tickets/_admin-nav.html.haml index 0e45c40..3e65e44 100644 --- a/help/app/views/tickets/_admin-nav.html.haml +++ b/help/app/views/tickets/_admin-nav.html.haml @@ -1,5 +1,5 @@ -%ul.nav.nav-pills.nav-stacked - %li{:class => ("active" if admin == 'mine')} - = link_to 'tickets i admin', {:admin_status => 'mine', :open_status => status, :sort_order => order} - %li{:class => ("active" if admin == 'all')} - = link_to 'all tickets', {:admin_status => 'all', :open_status => status, :sort_order => order} +.btn-group + %span.btn.disabled= t(:admin) + ':' + = link_to t(:my_tickets), {:admin_status => 'mine', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'mine')].join(' ') + = link_to t(:all_tickets), {:admin_status => 'all', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'all')].join(' ') +%br \ No newline at end of file diff --git a/help/app/views/tickets/_comment.html.haml b/help/app/views/tickets/_comment.html.haml index 501ceec..c02246c 100644 --- a/help/app/views/tickets/_comment.html.haml +++ b/help/app/views/tickets/_comment.html.haml @@ -1,20 +1,20 @@ -- # style is super ugly but just for now - if admin? or !comment.private # only show comment if user is admin or comment is not private %tr - %td - - if comment.posted_by_user - %b - = 'Posted by' + (comment.posted_by_user.is_admin? ? ' admin' : '') + ':' - = comment.posted_by_user.login - - else - %b - Unauthenticated post + %td.user + %div + %strong + - if comment.posted_by_user + = comment.posted_by_user.login + - else + = t(:unknown) + %div= comment.posted_at.to_s(:short) + - if comment.posted_by_user.is_admin? + %div + %span.label.label-inverse + = t(:admin) - if comment.private - (Private comment) - .pull-right - %b - Posted at: - = comment.posted_at.to_s(:short) - %br - = comment.body - + %div + %span.label.label-important + = t(:private) + %td.comment + = comment.body \ No newline at end of file diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml new file mode 100644 index 0000000..3d1d879 --- /dev/null +++ b/help/app/views/tickets/_edit_form.html.haml @@ -0,0 +1,46 @@ +- # created by user link +- if @ticket.created_by_user + - created_by = link_to(@ticket.created_by_user.login, user_overview_path(@ticket.created_by_user)) +- else + - created_by = t(:anonymous) + +- # regarding user link +- if admin? + - if @ticket.regarding_user_actual_user + - regarding_user_link = link_to @ticket.regarding_user_actual_user.login, user_overview_path(@ticket.regarding_user_actual_user) + - else + - regarding_user_link = "(#{t(:unknown)})" +- else + - regarding_user_link = '' + += form_for @ticket do |f| + %p.first + - if @ticket.is_open? + %span.label.label-info= t(:open) + - else + %span.label.label-success= t(:closed) + %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe + = t(:subject) + %br + = f.text_field :title, :class => 'large full-width' + .row-fluid + .span4 + %div= t(:status) + = f.select :is_open, [[t(:open), "true"], [t(:closed), "false"]] + .span4 + %div= t(:email) + = f.text_field :email + .span4 + %div + = t(:regarding) + = regarding_user_link + = f.text_field :regarding_user + = f.submit t(:save), :class => 'btn' + - if @ticket.is_open? + = f.submit t(:close), :class => 'btn' + =# button_to t(:close), {:post => {:is_open => false}}, :method => :put, :class => 'btn' + - else + = f.submit t(:open), :class => 'btn' + =# button_to t(:open), {:post => {:is_open => true}}, :method => :put, :class => 'btn' + + diff --git a/help/app/views/tickets/_new_comment.html.haml b/help/app/views/tickets/_new_comment.html.haml deleted file mode 100644 index 96388ea..0000000 --- a/help/app/views/tickets/_new_comment.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -= f.simple_fields_for :comments, @comment do |c| - = c.input :body, :label => 'Comment', :as => :text, :input_html => {:class => "span9", :rows=>4} - - if admin? - = c.input :private, :as => :boolean, :label => false, :inline_label => true diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml new file mode 100644 index 0000000..b273503 --- /dev/null +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -0,0 +1,13 @@ +-# +-# for posting a new comment to an existing ticket. +-# += simple_form_for @ticket, :html => {:class => 'slim'} do |f| + = f.simple_fields_for :comments, @comment, :wrapper => :none, :html => {:class => 'slim'} do |c| + = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} + - if admin? + = c.input :private, :as => :boolean, :label => false, :inline_label => true + = f.button :submit, t(:post_reply), :class => 'btn-primary' + - if @ticket.is_open + = f.button :submit, t(:reply_and_close) + = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index 45ebfb2..a5cf8be 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,3 +1,6 @@ +- if admin? + = render 'tickets/admin-nav' + - unless action?(:new) = render 'tickets/order-nav' = render 'tickets/status-nav' diff --git a/help/app/views/tickets/_ticket.html.haml b/help/app/views/tickets/_ticket.html.haml index 7b37652..9a1e899 100644 --- a/help/app/views/tickets/_ticket.html.haml +++ b/help/app/views/tickets/_ticket.html.haml @@ -1,17 +1,5 @@ -- updated_at_text = 'updated: ' + ticket.updated_at.to_s(:long) %tr - %td - %b - = link_to ticket.title, ticket - - if params[:controller] == 'tickets' - %br - %small - created: - = ticket.created_at.to_s(:long) - = updated_at_text - %small.pull-right - comments by: - = ticket.commenters - - else - %small - = updated_at_text \ No newline at end of file + %td= link_to ticket.title, ticket + %td= link_to ticket.created_at.to_s(:short), ticket + %td= link_to ticket.updated_at.to_s(:short), ticket + %td= ticket.commenters diff --git a/help/app/views/tickets/_ticket_data.html.haml b/help/app/views/tickets/_ticket_data.html.haml deleted file mode 100644 index 6a1a896..0000000 --- a/help/app/views/tickets/_ticket_data.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -.spam12 - %b - Created by: - - if @ticket.created_by_user - = link_to @ticket.created_by_user.login, user_path(@ticket.created_by_user) - - else - Unauthenticated ticket creator - - if @ticket.regarding_user - %b - Regarding user: - - if admin? - - if @ticket.regarding_user_actual_user - = link_to @ticket.regarding_user_actual_user.login, user_path(@ticket.regarding_user_actual_user) - - else - = @ticket.regarding_user + ' (no such user)' - - else # a non-admin is viewing the ticket, so they shouldn't see confirmation of whether the regarding_user exists or not. - = @ticket.regarding_user - - if @ticket.email - %b - email: - = @ticket.email - %b - Created at: - = @ticket.created_at.to_s(:short) - %b - Updated at: - = @ticket.updated_at.to_s(:short) - %b - = "Status:" - - if @ticket.is_open - = 'open' - = button_to 'Close', {:post => {:is_open => false}}, :method => :put, :class => 'btn btn-small' - - else - = 'closed' - = button_to 'Open', {:post => {:is_open => true}}, :method => :put, :class => 'btn btn-small' diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index a3cbfcf..f4597a7 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,12 +1,17 @@ -- if admin? - = render 'tickets/admin-nav' - = render 'tickets/table-nav' -%table.table-striped.table-bordered.table-hover - //{:style => "width:100%;"} +%table.table.table-striped.table-bordered + %thead + %tr + %th= t(:subject) + %th= t(:created) + %th= t(:updated) + %th= t(:voices) %tbody - = render @tickets.all -= paginate @tickets - + - if @tickets.any? + = render @tickets.all + - else + %tr + %td{:colspan=>4}= t(:none) += paginate @tickets diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 5442910..acb9537 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,17 +1,17 @@ - -//%h2.first= t :new_ticket - = render 'tickets/table-nav' = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| - = f.input :title + = f.input :title, :label => t(:subject) - if user = f.input :email, input_html: {value: user.email_address} = f.input :regarding_user, input_html: {value: user.login} - else = f.input :email = f.input :regarding_user - = render :partial => 'new_comment', :locals => {:f => f} + = f.simple_fields_for :comments, @comment do |c| + = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5} + - if admin? + = c.input :private, :as => :boolean, :label => false, :inline_label => true .form-actions = f.button :submit, :class => 'btn-primary' = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/show.html.haml b/help/app/views/tickets/show.html.haml index a69048b..ddd4e9f 100644 --- a/help/app/views/tickets/show.html.haml +++ b/help/app/views/tickets/show.html.haml @@ -1,18 +1,10 @@ -.spam12 - %h2 - %a#title.editable.editable-click{"data-name" => "title", "data-resource" => "post", "data-type" => "text", "data-url" => ticket_path(@ticket.id), "data-pk" => @ticket.id, :href => "#"} - = @ticket.title - = render 'tickets/ticket_data' - %table.table-striped.table-bordered.table-hover{:style => "width:100%;"} +.ticket + = render 'tickets/edit_form' + %table.table.table-striped.table-bordered %tbody - = render(:partial => "comment", :collection => @ticket.comments) - = #render @ticket.comments should work if view is in /app/views/comments/_comment - - = simple_form_for @ticket, :html => {:class => 'form-horizontal'} do |f| # don't need validations so long as this is so simple - = render :partial => 'new_comment', :locals => {:f => f} - .span10.offset3 - = f.button :submit, @post_reply_str, :class => 'btn-primary' - - if @ticket.is_open - = f.button :submit, @reply_close_str - = link_to t(:Destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? - = link_to t(:cancel), tickets_path, :class => :btn + = render :partial => 'tickets/comment', :collection => @ticket.comments + %tr + %td.user + = logged_in? ? current_user.login : t(:anonymous) + %td.comment + = render 'tickets/new_comment_form' \ No newline at end of file diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 2835e4e..901cd76 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -2,6 +2,16 @@ en: access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" support_tickets: "Support Tickets" all_tickets: "All Tickets" + my_tickets: "My Tickets" open_tickets: "Open Tickets" closed_tickets: "Closed Tickets" - new_ticket: "New Ticket" \ No newline at end of file + new_ticket: "New Ticket" + tickets: "Tickets" + subject: "Subject" + destroy: "Destroy" + open: "Open" + closed: "Closed" + close: "Close" + post_reply: "Post Reply" + reply_and_close: "Reply and Close" + description: "Description" \ No newline at end of file -- cgit v1.2.3 From 52846835676ecbf57fe2e1f3613cc50e2c486ade Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:34:11 -0700 Subject: remove gem bootstrap-editable --- app/assets/javascripts/application.js | 4 ++-- ui_dependencies.rb | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 049a392..ad4dbbf 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,8 +14,8 @@ //= require jquery_ujs //= require srp //= require bootstrap -//= require bootstrap-editable -//= require bootstrap-editable-rails +//# require bootstrap-editable +//# require bootstrap-editable-rails //= require rails.validations //= require rails.validations.simple_form diff --git a/ui_dependencies.rb b/ui_dependencies.rb index 2eb1e77..c01de44 100644 --- a/ui_dependencies.rb +++ b/ui_dependencies.rb @@ -4,9 +4,16 @@ gem "jquery-rails" gem "simple_form" gem 'client_side_validations' gem 'client_side_validations-simple_form' -gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be issues with 0.14.0 when using couchrest -gem 'bootstrap-editable-rails', "~>0.0.4" +gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be + # issues with 0.14.0 when using couchrest + +# gem 'bootstrap-editable-rails', "~>0.0.4" + +gem 'rails-i18n' # locale files for built-in validation messages and times + # https://github.com/svenfuchs/rails-i18n + # for a list of keys: + # https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml group :assets do gem "haml-rails", "~> 0.3.4" gem "sass-rails", "~> 3.2.5" -- cgit v1.2.3 From 775035d30cbfb197300f094a6402d6664b2fd04e Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:34:27 -0700 Subject: set pagination size via config file --- config/defaults.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/defaults.yml b/config/defaults.yml index 25537fe..6317082 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -19,6 +19,7 @@ development: admins: [admin, admin2] domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' + pagination_size: 30 test: <<: *dev_ca @@ -26,8 +27,10 @@ test: admins: [admin, admin2] domain: test.me secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' + pagination_size: 30 production: <<: *cert_options admins: [] domain: example.net + pagination_size: 30 \ No newline at end of file -- cgit v1.2.3 From 0e9818a80f7ca4afb35d4738f9721bc4753d2762 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:35:22 -0700 Subject: i18n - added a few strongs to app, fixed language at english for now. --- config/initializers/i18n.rb | 2 ++ config/locales/en.yml | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 config/initializers/i18n.rb diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb new file mode 100644 index 0000000..574d169 --- /dev/null +++ b/config/initializers/i18n.rb @@ -0,0 +1,2 @@ + +I18n.available_locales = ['en'] diff --git a/config/locales/en.yml b/config/locales/en.yml index 40cdb4a..f4e35f2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -9,5 +9,14 @@ en: user_control_panel: "user control panel" created: "Created" + created_by_on: "Created by %{user} on %{time}" updated: "Updated" + none: "None" + unknown: "Unknown" + admin: "Admin" + anonymous: "Anonymous" + save: "Save" + + changes_saved: "Changes saved successfully." + thing_was_successfully_created: "%{thing} was successfully created." \ No newline at end of file -- cgit v1.2.3 From 1185eea8c3f8cbd6450c3f5317235d0f07b911ae Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:02 -0700 Subject: added html_title helper - use @title to set page title. --- app/helpers/application_helper.rb | 13 +++++++++++++ app/views/layouts/application.html.haml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index db70109..a236a0a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,5 +1,18 @@ module ApplicationHelper + # + # determine title for the page + # + def html_title + if content_for?(:title) + yield(:title) + elsif @title + [@title, ' - ', APP_CONFIG[:domain]].join + else + APP_CONFIG[:domain] + end + end + # # markup for bootstrap icon # diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 719d699..71364fc 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -2,7 +2,7 @@ %html %head %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"} - %title= content_for?(:title) ? yield(:title) : "Leap Web" + %title= html_title %meta{:content => content_for?(:description) ? yield(:description) : "Leap Web", :name => "description"} = stylesheet_link_tag "application", :media => "all" = javascript_include_tag "application" -- cgit v1.2.3 From 2d8f4914c84db51a95539ecdbf13f44ce220f3e9 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:16 -0700 Subject: redirect to overview if authenticated --- app/controllers/home_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 4e1983a..120541e 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,6 +1,9 @@ class HomeController < ApplicationController def index + if logged_in? + redirect_to user_overview_url(current_user) + end debugger if params[:debug] end end -- cgit v1.2.3 From 7b6463d424af490bd8f09d0dd6898512bbb9ca2f Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:32 -0700 Subject: style kaminari pagination to work with bootstrap --- core/app/views/kaminari/_first_page.html.haml | 9 +++++++++ core/app/views/kaminari/_gap.html.haml | 8 ++++++++ core/app/views/kaminari/_last_page.html.haml | 9 +++++++++ core/app/views/kaminari/_next_page.html.haml | 12 ++++++++++++ core/app/views/kaminari/_page.html.haml | 14 ++++++++++++++ core/app/views/kaminari/_paginator.html.haml | 19 +++++++++++++++++++ core/app/views/kaminari/_prev_page.html.haml | 12 ++++++++++++ 7 files changed, 83 insertions(+) create mode 100644 core/app/views/kaminari/_first_page.html.haml create mode 100644 core/app/views/kaminari/_gap.html.haml create mode 100644 core/app/views/kaminari/_last_page.html.haml create mode 100644 core/app/views/kaminari/_next_page.html.haml create mode 100644 core/app/views/kaminari/_page.html.haml create mode 100644 core/app/views/kaminari/_paginator.html.haml create mode 100644 core/app/views/kaminari/_prev_page.html.haml diff --git a/core/app/views/kaminari/_first_page.html.haml b/core/app/views/kaminari/_first_page.html.haml new file mode 100644 index 0000000..34436e3 --- /dev/null +++ b/core/app/views/kaminari/_first_page.html.haml @@ -0,0 +1,9 @@ +-# Link to the "First" page +-# available local variables +-# url: url to the first page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li + = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote diff --git a/core/app/views/kaminari/_gap.html.haml b/core/app/views/kaminari/_gap.html.haml new file mode 100644 index 0000000..51de678 --- /dev/null +++ b/core/app/views/kaminari/_gap.html.haml @@ -0,0 +1,8 @@ +-# Non-link tag that stands for skipped pages... +-# available local variables +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li.disabled + = raw(t 'views.pagination.truncate') diff --git a/core/app/views/kaminari/_last_page.html.haml b/core/app/views/kaminari/_last_page.html.haml new file mode 100644 index 0000000..c90433c --- /dev/null +++ b/core/app/views/kaminari/_last_page.html.haml @@ -0,0 +1,9 @@ +-# Link to the "Last" page +-# available local variables +-# url: url to the last page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li + = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} diff --git a/core/app/views/kaminari/_next_page.html.haml b/core/app/views/kaminari/_next_page.html.haml new file mode 100644 index 0000000..ea6cab2 --- /dev/null +++ b/core/app/views/kaminari/_next_page.html.haml @@ -0,0 +1,12 @@ +-# Link to the "Next" page +-# available local variables +-# url: url to the next page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +- if current_page.last? + %li.disabled + %span= raw(t 'views.pagination.next') +- else + %li= link_to(raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote) diff --git a/core/app/views/kaminari/_page.html.haml b/core/app/views/kaminari/_page.html.haml new file mode 100644 index 0000000..2f2f142 --- /dev/null +++ b/core/app/views/kaminari/_page.html.haml @@ -0,0 +1,14 @@ +-# Link showing page number +-# available local variables +-# page: a page object for "this" page +-# url: url to this page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote + +- if page.current? + %li.active + %span= page +- else + %li= link_to(page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil}) diff --git a/core/app/views/kaminari/_paginator.html.haml b/core/app/views/kaminari/_paginator.html.haml new file mode 100644 index 0000000..79c5b92 --- /dev/null +++ b/core/app/views/kaminari/_paginator.html.haml @@ -0,0 +1,19 @@ +-# The container tag +-# available local variables +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +-# paginator: the paginator that renders the pagination tags inside += paginator.render do + .pagination + %ul + -#= first_page_tag unless current_page.first? + = prev_page_tag #unless current_page.first? + - each_page do |page| + - if page.left_outer? || page.right_outer? || page.inside_window? + = page_tag page + - elsif !page.was_truncated? + = gap_tag + = next_page_tag #unless current_page.last? + -#= last_page_tag unless current_page.last? diff --git a/core/app/views/kaminari/_prev_page.html.haml b/core/app/views/kaminari/_prev_page.html.haml new file mode 100644 index 0000000..d274bf4 --- /dev/null +++ b/core/app/views/kaminari/_prev_page.html.haml @@ -0,0 +1,12 @@ +-# Link to the "Previous" page +-# available local variables +-# url: url to the previous page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +- if current_page.first? + %li.disabled + %span= raw(t 'views.pagination.previous') +- else + %li= link_to(raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote) -- cgit v1.2.3 From 5c19ac7f6f457552c7c11a87b8417591abde7061 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:37:04 -0700 Subject: add commented out code of how redirect should work with Warden, although I can't get it working. --- users/app/controllers/sessions_controller.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/users/app/controllers/sessions_controller.rb b/users/app/controllers/sessions_controller.rb index 01ecff6..d6c455b 100644 --- a/users/app/controllers/sessions_controller.rb +++ b/users/app/controllers/sessions_controller.rb @@ -22,4 +22,15 @@ class SessionsController < ApplicationController logout redirect_to root_path end + + # + # this is a bad hack, but user_overview_url(user) is not available + # also, this doesn't work because the redirect happens as a PUT. no idea why. + # + #Warden::Manager.after_authentication do |user, auth, opts| + # response = Rack::Response.new + # response.redirect "/users/#{user.id}/overview" + # throw :warden, response.finish + #end + end -- cgit v1.2.3 From fb7187561d7143da458c102353ee9e0090d71532 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:37:32 -0700 Subject: use session/new partial for all login forms. --- users/app/views/sessions/new.html.haml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 4d14801..48f914c 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -1,9 +1 @@ -//= render 'sessions/new' - -%h2=t :login -= simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| - %legend=t :login_message - = f.input :login, :input_html => { :id => :srp_username } - = f.input :password, :required => true, :input_html => { :id => :srp_password } - = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn \ No newline at end of file += render 'sessions/new' \ No newline at end of file -- cgit v1.2.3 From ebdceb115f8a426bea61e4bf144463b67dbaf125 Mon Sep 17 00:00:00 2001 From: jessib Date: Thu, 20 Jun 2013 11:54:16 -0700 Subject: For removing account, redirect to root path, and ask confirmation message: https://leap.se/code/issues/2923 --- users/app/controllers/users_controller.rb | 2 +- users/app/views/users/_cancel_account.html.haml | 2 +- users/config/locales/en.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index dff1ed5..38a69e3 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -43,7 +43,7 @@ class UsersController < ApplicationController def destroy @user.destroy - redirect_to admin? ? users_path : login_path + redirect_to admin? ? users_path : root_path end protected diff --git a/users/app/views/users/_cancel_account.html.haml b/users/app/views/users/_cancel_account.html.haml index 756170b..c5ab36a 100644 --- a/users/app/views/users/_cancel_account.html.haml +++ b/users/app/views/users/_cancel_account.html.haml @@ -4,6 +4,6 @@ %small You will not be able to login anymore. - else =t :admin_cancel_account, :username => @user.login -= link_to user_path(@user), :method => :delete, :class => "btn btn-danger" do += link_to user_path(@user), :method => :delete, :confirm => t(:confirm_question), :class => "btn btn-danger" do %i.icon-remove.icon-white =t :remove_account diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index dded88c..32d183b 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -16,6 +16,7 @@ en: email_aliases: "Email aliases" public_key: "Public Key" add_email_alias: "Add email alias" + confirm_question: "Are you sure?" user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." -- cgit v1.2.3 From 9f8549fd485ee3dc9e63850a2af2a8859fdb70cc Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:12:54 -0700 Subject: added 'thin' and 'quiet_assets' gems to make development mode much nicer. --- common_dependencies.rb | 2 ++ config/application.rb | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/common_dependencies.rb b/common_dependencies.rb index 1650fee..63c3710 100644 --- a/common_dependencies.rb +++ b/common_dependencies.rb @@ -7,5 +7,7 @@ end group :test, :development do gem 'faker' gem 'factory_girl_rails' + gem 'thin' + gem 'quiet_assets' end diff --git a/config/application.rb b/config/application.rb index 957bb0d..5e52c7b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -59,11 +59,18 @@ module LeapWeb # parameters by using an attr_accessible or attr_protected declaration. # config.active_record.whitelist_attributes = true + ## + ## ASSETS + ## + # Enable the asset pipeline config.assets.enabled = true config.assets.initialize_on_precompile = false # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' + + # Set to false in order to see asset requests in the log + config.quiet_assets = true end end -- cgit v1.2.3 From fdf67344a80fcde0aab21c27d00412eeca609ca1 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:14:45 -0700 Subject: fix several issues with tickets: js error, when to redirect, navigation, localization. --- help/app/assets/javascripts/tickets.js | 8 +++--- help/app/controllers/tickets_controller.rb | 30 +++++++++++++++------- help/app/views/tickets/_comment.html.haml | 4 +-- help/app/views/tickets/_edit_form.html.haml | 10 +++----- help/app/views/tickets/_new_comment_form.html.haml | 5 ++-- help/app/views/tickets/_status-nav.html.haml | 13 +++++----- help/app/views/tickets/new.html.haml | 3 ++- help/config/locales/en.yml | 9 +++++-- help/leap_web_help.gemspec | 2 +- 9 files changed, 50 insertions(+), 34 deletions(-) diff --git a/help/app/assets/javascripts/tickets.js b/help/app/assets/javascripts/tickets.js index 5376a6e..bf7965c 100644 --- a/help/app/assets/javascripts/tickets.js +++ b/help/app/assets/javascripts/tickets.js @@ -1,4 +1,4 @@ -$(document).ready(function () { - $.fn.editable.defaults.mode = 'inline'; - $('#title').editable(); -}); \ No newline at end of file +//$(document).ready(function () { +// $.fn.editable.defaults.mode = 'inline'; +// $('#title').editable(); +//}); \ No newline at end of file diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index d478da9..3be7d10 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -42,19 +42,18 @@ class TicketsController < ApplicationController if params[:commit] == t(:close) @ticket.is_open = false @ticket.save - redirect_to tickets_path + redirect_to_tickets elsif params[:commit] == t(:open) @ticket.is_open = true @ticket.save redirect_to @ticket + elsif params[:commit] == t(:cancel) + redirect_to_tickets else @ticket.attributes = cleanup_ticket_params(params[:ticket]) if params[:commit] == t(:reply_and_close) @ticket.close - should_redirect = true - else - should_redirect = !logged_in? end if @ticket.comments_changed? @@ -64,11 +63,7 @@ class TicketsController < ApplicationController if @ticket.changed? if @ticket.save flash[:notice] = t(:changes_saved) - if should_redirect - redirect_to tickets_path - else - redirect_to @ticket - end + redirect_to_tickets else respond_with @ticket end @@ -97,6 +92,23 @@ class TicketsController < ApplicationController private + # + # redirects to ticket index, if appropriate. + # otherwise, just redirects to @ticket + # + def redirect_to_tickets + if logged_in? + if params[:commit] == t(:reply_and_close) + redirect_to tickets_url + else + redirect_to @ticket + end + else + # if we are not logged in, there is no index to view + redirect_to @ticket + end + end + # unset comments hash if no new comment was typed def cleanup_ticket_params(ticket) if ticket && ticket[:comments_attributes] diff --git a/help/app/views/tickets/_comment.html.haml b/help/app/views/tickets/_comment.html.haml index c02246c..4252eee 100644 --- a/help/app/views/tickets/_comment.html.haml +++ b/help/app/views/tickets/_comment.html.haml @@ -6,9 +6,9 @@ - if comment.posted_by_user = comment.posted_by_user.login - else - = t(:unknown) + = t(:anonymous) %div= comment.posted_at.to_s(:short) - - if comment.posted_by_user.is_admin? + - if comment.posted_by_user && comment.posted_by_user.is_admin? %div %span.label.label-inverse = t(:admin) diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 3d1d879..151d6f1 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -20,8 +20,7 @@ - else %span.label.label-success= t(:closed) %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe - = t(:subject) - %br + %div= t(:subject) = f.text_field :title, :class => 'large full-width' .row-fluid .span4 @@ -32,15 +31,14 @@ = f.text_field :email .span4 %div - = t(:regarding) + = t(:regarding_account) = regarding_user_link = f.text_field :regarding_user = f.submit t(:save), :class => 'btn' - if @ticket.is_open? = f.submit t(:close), :class => 'btn' - =# button_to t(:close), {:post => {:is_open => false}}, :method => :put, :class => 'btn' - else = f.submit t(:open), :class => 'btn' - =# button_to t(:open), {:post => {:is_open => true}}, :method => :put, :class => 'btn' - + - if admin? + = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn' diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml index b273503..de54259 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -7,7 +7,6 @@ - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true = f.button :submit, t(:post_reply), :class => 'btn-primary' - - if @ticket.is_open + - if logged_in? && @ticket.is_open = f.button :submit, t(:reply_and_close) - = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index e1dca84..c8279ed 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -1,9 +1,10 @@ %ul.nav.nav-tabs - %li{:class => ("active" if status == 'open')} - = link_to_status 'open' - %li{:class => ("active" if status == 'closed')} - = link_to_status 'closed' - %li{:class => ("active" if status == 'all')} - = link_to_status 'all' + - if logged_in? + %li{:class => ("active" if status == 'open')} + = link_to_status 'open' + %li{:class => ("active" if status == 'closed')} + = link_to_status 'closed' + %li{:class => ("active" if status == 'all')} + = link_to_status 'all' %li{:class => ("active" if action?(:new))} = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index acb9537..7d3f76c 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -14,4 +14,5 @@ = c.input :private, :as => :boolean, :label => false, :inline_label => true .form-actions = f.button :submit, :class => 'btn-primary' - = link_to t(:cancel), tickets_path, :class => :btn + - if logged_in? + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 901cd76..79e745f 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -1,5 +1,8 @@ en: - access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" + access_ticket_text: > + You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. + Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to + remove it from the browser history. support_tickets: "Support Tickets" all_tickets: "All Tickets" my_tickets: "My Tickets" @@ -14,4 +17,6 @@ en: close: "Close" post_reply: "Post Reply" reply_and_close: "Reply and Close" - description: "Description" \ No newline at end of file + description: "Description" + ticket: "Ticket" + regarding_account: "Regarding Account" \ No newline at end of file diff --git a/help/leap_web_help.gemspec b/help/leap_web_help.gemspec index 09827dc..4914694 100644 --- a/help/leap_web_help.gemspec +++ b/help/leap_web_help.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.summary = "Help Desk for LeapWeb" s.description = "Managing Tickets for a Leap provider" - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] + s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"] s.test_files = Dir["test/**/*"] s.add_dependency "leap_web_core", LeapWeb::VERSION -- cgit v1.2.3 From 7190ef710f246ddd86faed3c62bcfb5026fcbf83 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:18:28 -0700 Subject: new home page --- app/assets/stylesheets/leap.scss | 22 ++++++ app/helpers/navigation_helper.rb | 82 ---------------------- app/views/home/_home_text.html.haml | 7 +- app/views/home/index.html.haml | 12 ++-- core/app/helpers/navigation_helper.rb | 82 ++++++++++++++++++++++ core/app/helpers/snippet_helper.rb | 11 +++ core/app/views/common/_home_page_buttons.html.haml | 18 +++++ 7 files changed, 145 insertions(+), 89 deletions(-) delete mode 100644 app/helpers/navigation_helper.rb create mode 100644 core/app/helpers/navigation_helper.rb create mode 100644 core/app/helpers/snippet_helper.rb create mode 100644 core/app/views/common/_home_page_buttons.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 6b44986..a7d6261 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -45,6 +45,10 @@ input.large { line-height: $baseLineHeight * 1.5; } +.p { + @extend p; +} + // // FORMS // @@ -99,6 +103,24 @@ input, textarea { } } +.home-buttons { + .span6 { + margin-bottom: 20px; + } + div { + a { + width: 10em; + margin-bottom: 4px; + display: block; + } + .info { + } + span { + } + } +} + + // // Side Navigation // diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb deleted file mode 100644 index 19cb934..0000000 --- a/app/helpers/navigation_helper.rb +++ /dev/null @@ -1,82 +0,0 @@ -module NavigationHelper - - # - # used to create a side navigation link. - # - # Signature is the same as link_to, except it accepts an :active value in the html_options - # - def link_to_navigation(*args) - if args.last.is_a? Hash - html_options = args.pop.dup - active_class = html_options.delete(:active) ? 'active' : nil - html_options[:class] = [html_options[:class], active_class].join(' ') - args << html_options - else - active_class = nil - end - content_tag :li, :class => active_class do - link_to(*args) - end - end - - # - # returns true if params[:action] matches one of the args. - # - def action?(*actions) - actions.detect do |action| - if action.is_a? String - action == action_string - elsif action.is_a? Symbol - if action == :none - action_string == nil - else - action == action_symbol - end - end - end - end - - # - # returns true if params[:controller] matches one of the args. - # - # for example: - # controller?(:me, :home) - # controller?('groups/') <-- matches any controller in namespace 'groups' - # - def controller?(*controllers) - controllers.each do |cntr| - if cntr.is_a? String - if cntr.ends_with?('/') - return true if controller_string.starts_with?(cntr.chop) - end - return true if cntr == controller_string - elsif cntr.is_a? Symbol - return true if cntr == controller_symbol - end - end - return false - end - - private - - def controller_string - @controller_string ||= params[:controller].to_s.gsub(/^\//, '') - end - - def controller_symbol - @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym - end - - def action_string - params[:action] - end - - def action_symbol - @action_symbol ||= if params[:action].present? - params[:action].to_sym - else - nil - end - end - -end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml index 1055091..4de4b5e 100644 --- a/app/views/home/_home_text.html.haml +++ b/app/views/home/_home_text.html.haml @@ -1,3 +1,6 @@ -Welcome to the LEAP web application. +%h1= t(:welcome, :provider => APP_CONFIG[:domain]) -For more information, visit #{link_to('leap.se', 'https://leap.se')} \ No newline at end of file +%p + We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). + += home_page_buttons diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 0b3bbf9..96a3aee 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,8 +1,10 @@ -.row-fluid - .span8 - = render 'home_text' - .span4 - = render '/login_or_signup' +/ .row-fluid +/ .span8 +/ = render 'home_text' +/ .span4 +/ = render '/login_or_signup' + += render 'home_text' - if Rails.env == 'development' .row-fluid diff --git a/core/app/helpers/navigation_helper.rb b/core/app/helpers/navigation_helper.rb new file mode 100644 index 0000000..19cb934 --- /dev/null +++ b/core/app/helpers/navigation_helper.rb @@ -0,0 +1,82 @@ +module NavigationHelper + + # + # used to create a side navigation link. + # + # Signature is the same as link_to, except it accepts an :active value in the html_options + # + def link_to_navigation(*args) + if args.last.is_a? Hash + html_options = args.pop.dup + active_class = html_options.delete(:active) ? 'active' : nil + html_options[:class] = [html_options[:class], active_class].join(' ') + args << html_options + else + active_class = nil + end + content_tag :li, :class => active_class do + link_to(*args) + end + end + + # + # returns true if params[:action] matches one of the args. + # + def action?(*actions) + actions.detect do |action| + if action.is_a? String + action == action_string + elsif action.is_a? Symbol + if action == :none + action_string == nil + else + action == action_symbol + end + end + end + end + + # + # returns true if params[:controller] matches one of the args. + # + # for example: + # controller?(:me, :home) + # controller?('groups/') <-- matches any controller in namespace 'groups' + # + def controller?(*controllers) + controllers.each do |cntr| + if cntr.is_a? String + if cntr.ends_with?('/') + return true if controller_string.starts_with?(cntr.chop) + end + return true if cntr == controller_string + elsif cntr.is_a? Symbol + return true if cntr == controller_symbol + end + end + return false + end + + private + + def controller_string + @controller_string ||= params[:controller].to_s.gsub(/^\//, '') + end + + def controller_symbol + @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym + end + + def action_string + params[:action] + end + + def action_symbol + @action_symbol ||= if params[:action].present? + params[:action].to_sym + else + nil + end + end + +end diff --git a/core/app/helpers/snippet_helper.rb b/core/app/helpers/snippet_helper.rb new file mode 100644 index 0000000..6fee454 --- /dev/null +++ b/core/app/helpers/snippet_helper.rb @@ -0,0 +1,11 @@ +# +# various html snippets we use throughout. +# + +module SnippetHelper + + def home_page_buttons + render 'common/home_page_buttons' + end + +end \ No newline at end of file diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml new file mode 100644 index 0000000..ed70ff7 --- /dev/null +++ b/core/app/views/common/_home_page_buttons.html.haml @@ -0,0 +1,18 @@ +- link_class = 'btn' +- icon_color = :black + +.home-buttons + .row-fluid.first + .login.span6 + %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => link_class) + %span.info= t(:login_info) + .signup.span6 + %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => link_class) + %span.info= t(:signup_info) + .row-fluid.second + .download.span6 + %span.link= link_to(icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => link_class) + %span.info= t(:download_client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe + .help.span6 + %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => link_class) + %span.info= t(:help_info) -- cgit v1.2.3 From 8083bf9ab76e7f253b94979cd9102250d70350d0 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:21:55 -0700 Subject: moved app locales to core gem. --- config/locales/en.yml | 21 --------------------- core/config/locales/en.yml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 core/config/locales/en.yml diff --git a/config/locales/en.yml b/config/locales/en.yml index f4e35f2..63f1c3e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,22 +1 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. - en: - hello: "Hello world" - no_such_thing: "No such %{thing}." - - overview: "Overview" - user_control_panel: "user control panel" - - created: "Created" - created_by_on: "Created by %{user} on %{time}" - updated: "Updated" - - none: "None" - unknown: "Unknown" - admin: "Admin" - anonymous: "Anonymous" - save: "Save" - - changes_saved: "Changes saved successfully." - thing_was_successfully_created: "%{thing} was successfully created." \ No newline at end of file diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml new file mode 100644 index 0000000..24a2a13 --- /dev/null +++ b/core/config/locales/en.yml @@ -0,0 +1,25 @@ +en: + no_such_thing: "No such %{thing}." + thing_was_successfully_created: "%{thing} was successfully created." + + overview: "Overview" + user_control_panel: "user control panel" + + created: "Created" + created_by_on: "Created by %{user} on %{time}" + updated: "Updated" + + none: "None" + unknown: "Unknown" + admin: "Admin" + anonymous: "Anonymous" + save: "Save" + changes_saved: "Changes saved successfully." + + download_client: "Download LEAP" + download_client_info: "The LEAP application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." + login_info: "Log in to change your account settings, create support tickets, and manage payments." + signup_info: "Sign up for a new user account via this website (it is better if you use the LEAP application to sign up, but this website works too)." + welcome: "Welcome to %{provider}." + get_help: "Get Help" + help_info: "Can't login? Create a new support ticket anonymously." \ No newline at end of file -- cgit v1.2.3 From 7fb77290c1d051527f8fb1076c17c5678ccd6a02 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 27 Jun 2013 11:28:09 +0200 Subject: bootstrap menu now has 60 px height - adjust body padding --- app/assets/stylesheets/application.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 3e1b42c..25e854e 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -10,10 +10,10 @@ // import bootstrap. // @import "bootstrap"; -body { - padding: 40px; -} +body { padding-top: 60px; } + @import "bootstrap-responsive"; + table.table-hover .btn { opacity: 0; } -- cgit v1.2.3 From facff38aee864d124f5eb2fbc0ebc46fa37179ec Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 27 Jun 2013 11:29:59 +0200 Subject: ignore files added on deploy so 'git status' is nice and clean --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 73cd22e..a79d841 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ public/provider.json config/config.yml bin .*.swp +public/1/* +vendor/bundle/* -- cgit v1.2.3 From 3dbf13f3c53a741341897aa2af36d6ef8dcead2c Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 28 Jun 2013 20:38:14 -0700 Subject: new layout for the home buttons --- app/assets/stylesheets/leap.scss | 112 +++++++++++++-------- app/controllers/application_controller.rb | 12 +++ app/helpers/application_helper.rb | 8 ++ app/views/home/_home_text.html.haml | 6 -- app/views/home/index.html.haml | 11 +- app/views/layouts/_masthead_large.html.haml | 3 - app/views/layouts/_masthead_noauth.html.haml | 3 + app/views/layouts/_messages.html.haml | 2 +- app/views/layouts/application.html.haml | 4 +- core/app/views/common/_home_page_buttons.html.haml | 23 +++-- public/img/32/arrow-down.png | Bin 0 -> 453 bytes 11 files changed, 114 insertions(+), 70 deletions(-) delete mode 100644 app/views/home/_home_text.html.haml delete mode 100644 app/views/layouts/_masthead_large.html.haml create mode 100644 app/views/layouts/_masthead_noauth.html.haml create mode 100644 public/img/32/arrow-down.png diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index a7d6261..577d211 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -1,27 +1,24 @@ +// +// LAYOUT +// -table.table-hover .btn { - opacity: 0; -} -table.table-hover tr:hover .btn { - opacity: 1; -} - -.ticket { - td.user { - white-space: nowrap; - } - td.comment { - width: 100%; - } +// This is a trick to be able to use bootstrap fluid layout and also have a max-width. +// It is like having your cake and eating it too. +#main { + *zoom: 1; + margin-left: auto; + margin-right: auto; + width: 1000px; + max-width: 100%; } // // UTILITY // -.debug { - outline: 1px solid red; -} +//.debug { +// outline: 1px solid red; +//} .full-width { width: 100%; @@ -36,8 +33,35 @@ table.table-hover tr:hover .btn { padding-top: 0; } +.last { + margin-bottom: 0; + padding-bottom: 0; +} + // -// Typography +// ICONS +// + +[class^="big-icon-"], +[class*=" big-icon-"] { + display: inline-block; + width: 32px; + height: 32px; + @include ie7-restore-right-whitespace(); + line-height: 32px; + vertical-align: middle; + //background-image: $iconSpritePath; + //background-position: 14px 14px; + background-repeat: no-repeat; + margin-top: 1px; +} + +.big-icon-arrow-down { + background-image: url(/img/32/arrow-down.png) +} + +// +// TYPOGRAPHY // input.large { @@ -50,7 +74,7 @@ input.large { } // -// FORMS +// BOOSTRAP TWEAKS // // @@ -67,27 +91,33 @@ input, textarea { } } -// -// Labels -// - +// like a label, but with no background .label-clear { background-color: $white; text-shadow: none; color: $black; } -// -// Icons -// - // force a black icon, even if bootstrap thinks differently .icon-black { background-image: url(/assets/glyphicons-halflings.png) !important; } // -// Boring default masthead +// TICKETS +// + +.ticket { + td.user { + white-space: nowrap; + } + td.comment { + width: 100%; + } +} + +// +// BORING DEFAULT MASTHEAD // #masthead { @@ -104,25 +134,25 @@ input, textarea { } .home-buttons { - .span6 { - margin-bottom: 20px; + text-align: center; + .first { + margin: 20px 0; } - div { - a { - width: 10em; - margin-bottom: 4px; - display: block; - } - .info { - } - span { + .download { + a.btn { + width: 14em; } } + a.btn { + font-weight: bold; + width: 11em; + margin: 10px auto; + display: block; + } } - // -// Side Navigation +// SIDE NAVIGATION // .sidenav { diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 06b245a..62d9df2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,4 +3,16 @@ class ApplicationController < ActionController::Base ActiveSupport.run_load_hooks(:application_controller, self) + protected + + # + # Allows us to pass through bold text to flash messages. See format_flash() for where this is reversed. + # + # TODO: move to core + # + def bold(str) + "[b]#{str}[/b]" + end + helper_method :bold + end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a236a0a..1e79990 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -29,4 +29,12 @@ module ApplicationHelper " ".html_safe end + def big_icon(name, color=nil) + " ".html_safe + end + + def format_flash(msg) + html_escape(msg).gsub('[b]', '').gsub('[/b]', '').html_safe + end + end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml deleted file mode 100644 index 4de4b5e..0000000 --- a/app/views/home/_home_text.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%h1= t(:welcome, :provider => APP_CONFIG[:domain]) - -%p - We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). - -= home_page_buttons diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 96a3aee..9da66a1 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,10 +1,9 @@ -/ .row-fluid -/ .span8 -/ = render 'home_text' -/ .span4 -/ = render '/login_or_signup' +%h1= t(:welcome, :provider => APP_CONFIG[:domain]) -= render 'home_text' +%p + We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). + += home_page_buttons - if Rails.env == 'development' .row-fluid diff --git a/app/views/layouts/_masthead_large.html.haml b/app/views/layouts/_masthead_large.html.haml deleted file mode 100644 index 6bb1943..0000000 --- a/app/views/layouts/_masthead_large.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -.title - %span.sitename - = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_masthead_noauth.html.haml b/app/views/layouts/_masthead_noauth.html.haml new file mode 100644 index 0000000..6bb1943 --- /dev/null +++ b/app/views/layouts/_masthead_noauth.html.haml @@ -0,0 +1,3 @@ +.title + %span.sitename + = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_messages.html.haml b/app/views/layouts/_messages.html.haml index 80e34d4..a3bbbac 100644 --- a/app/views/layouts/_messages.html.haml +++ b/app/views/layouts/_messages.html.haml @@ -2,4 +2,4 @@ - if msg.is_a?(String) %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} %a.close{"data-dismiss" => "alert"} × - = content_tag :div, msg, :id => "flash_#{name}" + = content_tag :div, format_flash(msg), :id => "flash_#{name}" diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 71364fc..e185f26 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -12,8 +12,8 @@ #masthead - if logged_in? = render 'layouts/masthead' - - else - = render 'layouts/masthead_large' + - elsif params[:controller] != 'home' + = render 'layouts/masthead_noauth' #main .container-fluid - if logged_in? diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml index ed70ff7..82a5cc2 100644 --- a/core/app/views/common/_home_page_buttons.html.haml +++ b/core/app/views/common/_home_page_buttons.html.haml @@ -1,18 +1,19 @@ -- link_class = 'btn' - icon_color = :black .home-buttons .row-fluid.first - .login.span6 - %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => link_class) - %span.info= t(:login_info) - .signup.span6 - %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => link_class) - %span.info= t(:signup_info) - .row-fluid.second + .span3 .download.span6 - %span.link= link_to(icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => link_class) + %span.link= link_to(big_icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => 'btn btn-large') %span.info= t(:download_client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe - .help.span6 - %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => link_class) + .span3 + .row-fluid.second + .login.span4 + %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => 'btn') + %span.info= t(:login_info) + .signup.span4 + %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => 'btn') + %span.info= t(:signup_info) + .help.span4 + %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => 'btn') %span.info= t(:help_info) diff --git a/public/img/32/arrow-down.png b/public/img/32/arrow-down.png new file mode 100644 index 0000000..3b16e6d Binary files /dev/null and b/public/img/32/arrow-down.png differ -- cgit v1.2.3 From 7ce929161604f6ee5b156b4e039bab1edcbf48ad Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 1 Jul 2013 08:56:33 +0200 Subject: redirect to root_path after canceling account login makes little sense. This change was applied already... just updated the test --- users/test/functional/users_controller_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/test/functional/users_controller_test.rb b/users/test/functional/users_controller_test.rb index fd8869a..7f81c59 100644 --- a/users/test/functional/users_controller_test.rb +++ b/users/test/functional/users_controller_test.rb @@ -162,7 +162,7 @@ class UsersControllerTest < ActionController::TestCase delete :destroy, :id => @current_user.id assert_response :redirect - assert_redirected_to login_path + assert_redirected_to root_path end test "non-admin can't destroy user" do -- cgit v1.2.3 From fbe23fc59814f0b27dbc1073c34f03a6d22cab99 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:11:23 -0700 Subject: add js to report all errors to the user, not just ones related to field validation. --- app/assets/javascripts/application.js | 3 +- core/app/assets/javascripts/leap.js | 7 ++ users/app/assets/javascripts/users.js | 74 ++++++++++++++++++++++ users/app/assets/javascripts/users.js.coffee | 46 -------------- .../controller_extension/authentication.rb | 15 ++++- 5 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 core/app/assets/javascripts/leap.js create mode 100644 users/app/assets/javascripts/users.js delete mode 100644 users/app/assets/javascripts/users.js.coffee diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ad4dbbf..cd90934 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,11 +14,10 @@ //= require jquery_ujs //= require srp //= require bootstrap -//# require bootstrap-editable -//# require bootstrap-editable-rails //= require rails.validations //= require rails.validations.simple_form +//= require leap //= require tickets //= require users diff --git a/core/app/assets/javascripts/leap.js b/core/app/assets/javascripts/leap.js new file mode 100644 index 0000000..94e602d --- /dev/null +++ b/core/app/assets/javascripts/leap.js @@ -0,0 +1,7 @@ + +// +// add a bootstrap alert to the page via javascript. +// +function alert_message(msg) { + $('#messages').append('
×'+msg+'
'); +} diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js new file mode 100644 index 0000000..eed1961 --- /dev/null +++ b/users/app/assets/javascripts/users.js @@ -0,0 +1,74 @@ +(function() { + // + // LOCAL FUNCTIONS + // + + var poll_users, prevent_default, form_failed, form_passed; + + prevent_default = function(event) { + return event.preventDefault(); + }; + + poll_users = function(query, process) { + return $.get("/users.json", { + query: query + }).done(process); + }; + + // + // PUBLIC FUNCTIONS + // + + srp.session = new srp.Session(); + + srp.signedUp = function() { + return srp.login(); + }; + + srp.loggedIn = function() { + return window.location = '/'; + }; + + srp.updated = function() { + return window.location = '/users/' + srp.session.id(); + }; + + // + // if a json request returns an error, this function gets called and + // decorates the appropriate fields with the error messages. + // + srp.error = function(message) { + var element, error, field; + if ($.isPlainObject(message) && message.errors) { + for (field in message.errors) { + error = message.errors[field]; + element = $('form input[name$="[' + field + ']"]'); + if (!element) { + next; + } + element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false); + } + } else if (message.error) { + alert_message(message.error); + } else { + alert_message(JSON.stringify(message)); + } + }; + + // + // INIT + // + + $(document).ready(function() { + $('#new_user').submit(prevent_default); + $('#new_user').submit(srp.signup); + $('#new_session').submit(prevent_default); + $('#new_session').submit(srp.login); + $('#update_login_and_password').submit(prevent_default); + $('#update_login_and_password').submit(srp.update); + return $('.user.typeahead').typeahead({ + source: poll_users + }); + }); + +}).call(this); diff --git a/users/app/assets/javascripts/users.js.coffee b/users/app/assets/javascripts/users.js.coffee deleted file mode 100644 index 955556c..0000000 --- a/users/app/assets/javascripts/users.js.coffee +++ /dev/null @@ -1,46 +0,0 @@ -preventDefault = (event) -> - event.preventDefault() - -srp.session = new srp.Session() -srp.signedUp = -> - srp.login() - -srp.loggedIn = -> - window.location = '/' - -#// TODO: not sure this is what we want. -srp.updated = -> - window.location = '/' - -srp.error = (message) -> - if $.isPlainObject(message) && message.errors - for field, error of message.errors - element = $('form input[name$="['+field+']"]') - next unless element - element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false) - else - alert(message) - -pollUsers = (query, process) -> - $.get( "/users.json", query: query).done(process) - -followLocationHash = -> - location = window.location.hash - if location - href_select = 'a[href="' + location + '"]' - link = $(href_select) - link.tab('show') if link - -$(document).ready -> - followLocationHash() - $('#new_user').submit preventDefault - $('#new_user').submit srp.signup - $('#new_session').submit preventDefault - $('#new_session').submit srp.login - $('.user.form.update_login_and_password').submit srp.update - $('.user.form.update_login_and_password').submit preventDefault - $('.user.typeahead').typeahead({source: pollUsers}); - $('a[data-toggle="tab"]').on('shown', -> - $(ClientSideValidations.selectors.forms).validate() - ) - diff --git a/users/app/controllers/controller_extension/authentication.rb b/users/app/controllers/controller_extension/authentication.rb index f0a6564..72df7a7 100644 --- a/users/app/controllers/controller_extension/authentication.rb +++ b/users/app/controllers/controller_extension/authentication.rb @@ -38,9 +38,18 @@ module ControllerExtension::Authentication end def access_denied - # TODO: should we redirect to the root_url in either case, and have the root_url include the login screen (and also ability to create unauthenticated tickets) when no user is logged in? - redirect_to login_url, :alert => "Not authorized" if !logged_in? - redirect_to root_url, :alert => "Not authorized" if logged_in? + respond_to do |format| + format.html do + if logged_in? + redirect_to root_url, :alert => t(:not_authorized) + else + redirect_to login_url, :alert => t(:not_authorized_login) + end + end + format.json do + render :json => {'error' => t(:not_authorized)}, status: :unprocessable_entity + end + end end def admin? -- cgit v1.2.3 From 96206389a863f105bd0b37dcdb9d00b7c30d8b51 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:17:44 -0700 Subject: users engine changes - rewrite of the views, separate email settings to a separate controller, make users_controller html only and v1/users_controller json only. --- users/app/controllers/email_aliases_controller.rb | 18 ++---- users/app/controllers/email_settings_controller.rb | 34 +++++++++++ users/app/controllers/users_controller.rb | 68 +++++++++------------- users/app/controllers/v1/users_controller.rb | 9 ++- users/app/helpers/users_helper.rb | 36 +----------- users/app/views/_login_or_signup.html.haml | 25 -------- users/app/views/email_settings/edit.html.haml | 38 ++++++++++++ users/app/views/emails/_email.html.haml | 2 +- users/app/views/emails/edit.html.haml | 5 -- users/app/views/sessions/_admin_nav.html.haml | 6 -- users/app/views/sessions/_nav.html.haml | 13 ----- users/app/views/sessions/_new.html.haml | 7 --- users/app/views/sessions/new.html.haml | 10 +++- users/app/views/users/_cancel_account.html.haml | 9 --- users/app/views/users/_edit.html.haml | 37 ++++++++++++ users/app/views/users/_email_aliases.html.haml | 6 -- users/app/views/users/_email_field.html.haml | 1 - .../app/views/users/_email_forward_field.html.haml | 1 - users/app/views/users/_form.html.haml | 11 ---- users/app/views/users/_legend_and_submit.html.haml | 4 -- .../users/_login_and_password_fields.html.haml | 2 - users/app/views/users/_login_field.html.haml | 1 - users/app/views/users/_password_fields.html.haml | 2 - users/app/views/users/_public_key_field.html.haml | 1 - users/app/views/users/edit.html.haml | 7 ++- users/app/views/users/index.html.haml | 31 +++++----- users/app/views/users/new.html.haml | 20 +++++-- users/app/views/users/show.html.haml | 61 ++++++++++--------- users/config/locales/en.yml | 32 +++++----- users/config/routes.rb | 3 +- 30 files changed, 243 insertions(+), 257 deletions(-) delete mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/email_settings/edit.html.haml delete mode 100644 users/app/views/emails/edit.html.haml delete mode 100644 users/app/views/sessions/_admin_nav.html.haml delete mode 100644 users/app/views/sessions/_nav.html.haml delete mode 100644 users/app/views/sessions/_new.html.haml delete mode 100644 users/app/views/users/_cancel_account.html.haml create mode 100644 users/app/views/users/_edit.html.haml delete mode 100644 users/app/views/users/_email_aliases.html.haml delete mode 100644 users/app/views/users/_email_field.html.haml delete mode 100644 users/app/views/users/_email_forward_field.html.haml delete mode 100644 users/app/views/users/_form.html.haml delete mode 100644 users/app/views/users/_legend_and_submit.html.haml delete mode 100644 users/app/views/users/_login_and_password_fields.html.haml delete mode 100644 users/app/views/users/_login_field.html.haml delete mode 100644 users/app/views/users/_password_fields.html.haml delete mode 100644 users/app/views/users/_public_key_field.html.haml diff --git a/users/app/controllers/email_aliases_controller.rb b/users/app/controllers/email_aliases_controller.rb index 3b0d5ac..4628a7f 100644 --- a/users/app/controllers/email_aliases_controller.rb +++ b/users/app/controllers/email_aliases_controller.rb @@ -1,20 +1,12 @@ -class EmailAliasesController < ApplicationController - +class EmailAliasesController < UsersBaseController before_filter :fetch_user - respond_to :html - def destroy @alias = @user.email_aliases.delete(params[:id]) - @user.save - flash[:notice] = t(:email_alias_destroyed_successfully, :alias => @alias) - redirect_to edit_user_path(@user, :anchor => :email) + if @user.save + flash[:notice] = t(:email_alias_destroyed_successfully, :alias => bold(@alias)) + end + redirect_to edit_user_email_settings_path(@user) end - protected - - def fetch_user - @user = User.find_by_param(params[:user_id]) - access_denied unless admin? or (@user == current_user) - end end diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb index e69de29..0261b47 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -0,0 +1,34 @@ +class EmailSettingsController < UsersBaseController + + before_filter :authorize + before_filter :fetch_user + + def edit + @email_alias = LocalEmail.new + end + + def update + @user.attributes = params[:user] + if @user.changed? + if @user.save + flash[:notice] = t(:changes_saved) + redirect + else + if @user.email_aliases.last && !@user.email_aliases.last.valid? + # display bad alias in text field: + @email_alias = @user.email_aliases.pop + end + render 'email_settings/edit' + end + else + redirect + end + end + + private + + def redirect + redirect_to edit_user_email_settings_url(@user) + end + +end diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index dff1ed5..09622b3 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -1,12 +1,15 @@ -class UsersController < ApplicationController +# +# This is an HTML-only controller. For the JSON-only controller, see v1/users_controller.rb +# - before_filter :authorize, :only => [:show, :edit, :destroy, :update] +class UsersController < UsersBaseController + + before_filter :authorize, :only => [:show, :edit, :update, :destroy] before_filter :fetch_user, :only => [:show, :edit, :update, :destroy] - before_filter :authorize_self, :only => [:update] - before_filter :set_anchor, :only => [:edit, :update] + #before_filter :authorize_self, :only => [:update] before_filter :authorize_admin, :only => [:index] - respond_to :json, :html + respond_to :json def index if params[:query] @@ -14,8 +17,8 @@ class UsersController < ApplicationController else @users = User.by_created_at.descending end - @users = @users.limit(10) - respond_with @users.map(&:login).sort + @users = @users.limit(APP_CONFIG[:pagination_size]) + #respond_with @users.map(&:login).sort end def new @@ -27,48 +30,33 @@ class UsersController < ApplicationController respond_with @user end - def edit - @email_alias = LocalEmail.new + def show end - def update - @user.attributes = params[:user] - if @user.changed? and @user.save - flash[:notice] = t(:user_updated_successfully) - elsif @user.email_aliases.last and !@user.email_aliases.last.valid? - @email_alias = @user.email_aliases.pop - end - respond_with @user, :location => edit_user_path(@user, :anchor => @anchor) + def edit end + # + # The API user update is used instead. Maybe someday we will have something for which this makes sense. + # + #def update + # @user.update_attributes(params[:user]) + # respond_with @user + #end + def destroy @user.destroy - redirect_to admin? ? users_path : login_path - end - - protected - - def fetch_user - # authorize filter has been checked first, so won't get here unless authenticated - @user = User.find_by_param(params[:id]) - if !@user and admin? - redirect_to users_path, :alert => t(:no_such_thing, :thing => 'user') - return + respond_to do |format| + format.html { redirect_to(admin? ? users_path : root_path) } + format.json { head :no_content } end - access_denied unless admin? or (@user == current_user) end - def authorize_self - # have already checked that authorized - access_denied unless (@user == current_user) - end + protected - def set_anchor - @anchor = email_settings? ? :email : :account - end + #def authorize_self + # # have already checked that authorized + # access_denied unless (@user == current_user) + #end - def email_settings? - params[:user] && - params[:user].keys.detect{|key| key.index('email')} - end end diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index 617bd4b..e7516bc 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -1,8 +1,9 @@ module V1 - class UsersController < ApplicationController + class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token before_filter :authorize, :only => [:update] + before_filter :fetch_user, :only => [:update] respond_to :json @@ -12,9 +13,11 @@ module V1 end def update - # For now, only allow public key to be updated via the API. Eventually we might want to store in a config what attributes can be updated via the API. @user = User.find_by_param(params[:id]) - @user.update_attributes params[:user].slice(:public_key) if params[:user].respond_to?(:slice) + @user.update_attributes params[:user] + if @user.valid? + flash[:notice] = t(:user_updated_successfully) + end respond_with @user end diff --git a/users/app/helpers/users_helper.rb b/users/app/helpers/users_helper.rb index 559b3f7..f56faab 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -1,39 +1,7 @@ module UsersHelper - def user_form_with(partial, options = {}) - user_form(options) do |f| - options[:f] = f - render :partial => partial, - :layout => 'legend_and_submit', - :locals => options - end - end - - def user_form(options = {}) - simple_form_for @user, - :html => user_form_html_options(options), - :validate => true do |f| - yield f - end - end - - def user_form_html_options(options) - { :class => user_form_html_classes(options).join(" "), - :id => dom_id(@user, options[:legend]) - } - end - - def user_form_html_classes(options) - classes = %W/user form/ - classes << options[:legend] - classes << (@user.new_record? ? 'new' : 'edit') - classes.compact - end - - def user_field(field) - value = @user.send(field) - value = value.to_s(:long) if field.end_with? '_at' - value || 'not set' + def user_form_class(*classes) + (classes + ['user', 'form', (@user.new_record? ? 'new' : 'edit')]).compact.join(' ') end def wrapped(item, options = {}) diff --git a/users/app/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml deleted file mode 100644 index b353526..0000000 --- a/users/app/views/_login_or_signup.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -// -// displays a little widget to login or sign up -// - -%ul.nav.nav-tabs - %li.active - %a{:href => ''}= t(:login) - %li - = link_to t(:signup), new_user_path - -= render 'sessions/new' - -// -// this is nice, but it doesn't work because both forms have the same names for fields. -// -// %ul.nav.nav-tabs -// %li.active -// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) -// %li -// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) -// .tab-content -// #login.tab-pane.active -// = render 'sessions/new' -// #signup.tab-pane -// = render 'users/new' diff --git a/users/app/views/email_settings/edit.html.haml b/users/app/views/email_settings/edit.html.haml new file mode 100644 index 0000000..7757a31 --- /dev/null +++ b/users/app/views/email_settings/edit.html.haml @@ -0,0 +1,38 @@ +- form_options = {:url => user_email_settings_path(@user), :html => {:class => 'form-horizontal'}, :validate => true} +- alias_error_class = @email_alias.username && !@email_alias.valid? ? 'error' : '' + +- content_for :head do + :css + table.aliases tr:first-child td { + border-top: none; + } + += simple_form_for @user, form_options.dup do |f| + %legend= t(:email_aliases) + .control-group + %label.control-label= t(:current_aliases) + .controls + %table.table.table-condensed.no-header.slim.aliases + - if @user.email_aliases.any? + - @user.email_aliases.each do |email| + %tr + %td= email + %td= link_to(icon(:remove) + t(:remove), user_email_alias_path(@user, email), :method => :delete) + - else + %tr + %td{:colspan=>2}= t(:none) + .control-group{:class => alias_error_class} + %label.control-label= t(:add_email_alias) + .controls + = f.simple_fields_for :email_aliases, @email_alias do |e| + .input-append + = e.input_field :username + = e.submit t(:add), :class => 'btn' + = e.error :username + += simple_form_for @user, form_options do |f| + %legend= t(:advanced_options) + = f.input :email_forward + = f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "full-width", :rows => 4} + .form-actions + = f.submit t(:save), :class => 'btn btn-primary' diff --git a/users/app/views/emails/_email.html.haml b/users/app/views/emails/_email.html.haml index c81b396..ea59cec 100644 --- a/users/app/views/emails/_email.html.haml +++ b/users/app/views/emails/_email.html.haml @@ -3,4 +3,4 @@ - if local_assigns[:with].try(:include?, :delete) = link_to(user_email_alias_path(@user, email), :method => :delete) do %i.icon-remove -.clearfix + diff --git a/users/app/views/emails/edit.html.haml b/users/app/views/emails/edit.html.haml deleted file mode 100644 index b44b569..0000000 --- a/users/app/views/emails/edit.html.haml +++ /dev/null @@ -1,5 +0,0 @@ - - -= user_form_with 'public_key_field', :legend => :public_key -= user_form_with 'email_forward_field', :legend => :forward_email -= user_form_with 'email_aliases', :legend => :add_email_alias diff --git a/users/app/views/sessions/_admin_nav.html.haml b/users/app/views/sessions/_admin_nav.html.haml deleted file mode 100644 index 14dfbdc..0000000 --- a/users/app/views/sessions/_admin_nav.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%a#admin-menu{"data-toggle" => "dropdown", :role => :button} - Admin -%ul.dropdown-menu{:role => "menu", "aria-labelledby" => "admin-menu"} - %li - = link_to Ticket.model_name.human(:count => ""), tickets_path, {:tabindex => -1} - = link_to User.model_name.human(:count => ""), users_path, {:tabindex => -1} diff --git a/users/app/views/sessions/_nav.html.haml b/users/app/views/sessions/_nav.html.haml deleted file mode 100644 index ac85bb5..0000000 --- a/users/app/views/sessions/_nav.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- if logged_in? - - if admin? - %li.dropdown - = render 'sessions/admin_nav' - %li - = link_to current_user.login, edit_user_path(current_user) - %li - = link_to t(:logout), logout_path, :method => :delete -- else - %li - = link_to t(:login), login_path - %li - = link_to t(:signup), signup_path diff --git a/users/app/views/sessions/_new.html.haml b/users/app/views/sessions/_new.html.haml deleted file mode 100644 index 640fec5..0000000 --- a/users/app/views/sessions/_new.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- @session ||= Session.new -= simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| - = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } - = f.input :password, :required => false, :input_html => { :id => :srp_password } - .form-actions - = f.button :submit, :value => t(:login), :class => 'btn-primary' - // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 48f914c..81a55b8 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -1 +1,9 @@ -= render 'sessions/new' \ No newline at end of file +.span1 +.span9 + %h2=t :login + = simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| + = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } + = f.input :password, :required => false, :input_html => { :id => :srp_password } + .form-actions + = f.button :submit, :value => t(:login), :class => 'btn-primary' + = link_to t(:cancel), root_path, :class => 'btn' diff --git a/users/app/views/users/_cancel_account.html.haml b/users/app/views/users/_cancel_account.html.haml deleted file mode 100644 index 756170b..0000000 --- a/users/app/views/users/_cancel_account.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%legend - - if @user == current_user - =t :cancel_account - %small You will not be able to login anymore. - - else - =t :admin_cancel_account, :username => @user.login -= link_to user_path(@user), :method => :delete, :class => "btn btn-danger" do - %i.icon-remove.icon-white - =t :remove_account diff --git a/users/app/views/users/_edit.html.haml b/users/app/views/users/_edit.html.haml new file mode 100644 index 0000000..adee8a4 --- /dev/null +++ b/users/app/views/users/_edit.html.haml @@ -0,0 +1,37 @@ +-# +-# edit user form, used by both show and edit actions. +-# + +-# +-# CHANGE PASSWORD +-# +-# * everything about this form is handled with javascript. So take care when changing any ids. +-# * the login is required when changing the password because it is used as part of the salt when calculating the password verifier. +-# however, we don't want the user to change their login without generating a new key, so we hide the ui for this +-# (although it works perfectly fine to change username if the field was visible). +-# +- form_options = {:url => '/not-used', :html => {:class => user_form_class('form-horizontal'), :id => 'update_login_and_password'}, :validate => true} += simple_form_for @user, form_options do |f| + %legend= t(:change_password) + = hidden_field_tag 'user_param', @user.to_param + .hidden + = f.input :login, :label => t(:username), :required => false, :input_html => {:id => :srp_username} + = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } + = f.input :password_confirmation, :required => false, :input_html => { :id => :srp_password_confirmation } + .control-group + .controls + = f.submit t(:save), :class => 'btn btn-primary' + +-# +-# DESTROY ACCOUNT +-# + +%legend + - if @user == current_user + = t(:destroy_my_account) + - else + = t(:admin_destroy_account, :username => @user.login) +%p= t(:destroy_account_info) += link_to user_path(@user), :method => :delete, :confirm => t(:are_you_sure), :class => "btn btn-danger" do + %i.icon-remove.icon-white + = t(:destroy_my_account) diff --git a/users/app/views/users/_email_aliases.html.haml b/users/app/views/users/_email_aliases.html.haml deleted file mode 100644 index 6e32700..0000000 --- a/users/app/views/users/_email_aliases.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.span6 - %ul.unstyled - = render @user.email_aliases, :as => :li, :with => [:delete] -.clearfix -= f.simple_fields_for :email_aliases, @email_alias do |e| - = e.input :username, :placeholder => "alias" diff --git a/users/app/views/users/_email_field.html.haml b/users/app/views/users/_email_field.html.haml deleted file mode 100644 index edf62c9..0000000 --- a/users/app/views/users/_email_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :email, :placeholder => "me@#{APP_CONFIG[:domain]}" diff --git a/users/app/views/users/_email_forward_field.html.haml b/users/app/views/users/_email_forward_field.html.haml deleted file mode 100644 index 049428f..0000000 --- a/users/app/views/users/_email_forward_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :email_forward diff --git a/users/app/views/users/_form.html.haml b/users/app/views/users/_form.html.haml deleted file mode 100644 index cb51175..0000000 --- a/users/app/views/users/_form.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- only = local_assigns[:only] -- html = {:class => 'form-horizontal user form ' + (@user.new_record? ? 'new' : 'edit')} -= simple_form_for @user, :validate => true, :format => :json, :html => html do |f| - %legend - = t(only || :signup_message) - = yield - .pull-right - = f.button :submit - - unless only - = link_to t(:cancel), root_url, :class => :btn - .clearfix diff --git a/users/app/views/users/_legend_and_submit.html.haml b/users/app/views/users/_legend_and_submit.html.haml deleted file mode 100644 index 6fc0e4a..0000000 --- a/users/app/views/users/_legend_and_submit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%legend= t(legend) -=yield -.pull-right= f.button :submit, :value => t(legend) -.clearfix diff --git a/users/app/views/users/_login_and_password_fields.html.haml b/users/app/views/users/_login_and_password_fields.html.haml deleted file mode 100644 index 0baefc7..0000000 --- a/users/app/views/users/_login_and_password_fields.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= render :partial => 'login_field', :locals => {:f => f} -= render :partial => 'password_fields', :locals => {:f => f, :password_confirmation_hint => t(:can_retype_old_password)} \ No newline at end of file diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml deleted file mode 100644 index e58c36f..0000000 --- a/users/app/views/users/_login_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml deleted file mode 100644 index 7b3358d..0000000 --- a/users/app/views/users/_password_fields.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } -= f.input :password_confirmation, :required => false, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } diff --git a/users/app/views/users/_public_key_field.html.haml b/users/app/views/users/_public_key_field.html.haml deleted file mode 100644 index af88cbd..0000000 --- a/users/app/views/users/_public_key_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "span5", :rows => 20} # will want to tweak this to be wide enough (maybe smaller text?) diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index 4e70d69..f06df44 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,3 +1,6 @@ -= user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user -= render 'cancel_account' += render 'edit' + + +=# user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user +=# render 'cancel_account' diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 9e6a179..254e177 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -1,17 +1,14 @@ -.page-header - %h1= User.model_name.human(:count =>User.count) -.row - .span8 - %h2= params[:query] ? "Users starting with '#{params[:query]}'" : "Last users who signed up" - %table.table.table-hover - %tr - %th Login - %th Created - %th Action - = render @users.all - .span4 - %h4 Find user - = form_tag users_path, :method => :get, :class => "form-search" do - .input-append - = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off - %button.btn{:type => :submit} Search +- @show_navigation = false + += form_tag users_path, :method => :get, :class => "form-search" do + .input-append + = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off + %button.btn{:type => :submit} Search + +%table.table.table-hover + %tr + %th Login + %th Created + %th Action + = render @users.all + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index d8a43d5..b1953e1 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -1,10 +1,18 @@ -.span8.offset2 +-# +-# This form is handled entirely by javascript, so take care when changing element ids. +-# + +- form_options = {:url => '/not-used', :html => {:id => 'new_user', :class => user_form_class('form-horizontal')}, :validate => true} + +.span1 +.span9 %h2=t :signup - = user_form do |f| + = simple_form_for(@user, form_options) do |f| %legend= t(:signup_message) - = render :partial => 'login_field', :locals => {:f => f} - = render :partial => 'password_fields', :locals => {:f => f} + = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } + = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } + = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } .form-actions - = f.button :submit, :value => t(:signup), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn + = f.button :submit, :value => t(:signup), :class => 'btn btn-primary' + = link_to t(:cancel), root_url, :class => 'btn' diff --git a/users/app/views/users/show.html.haml b/users/app/views/users/show.html.haml index 056ed57..dc5e015 100644 --- a/users/app/views/users/show.html.haml +++ b/users/app/views/users/show.html.haml @@ -1,31 +1,34 @@ -.span8.offset1 - %h2= @user.login - .small - = link_to 'edit', edit_user_path(@user) - %dl.offset1 - - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward'] - - fields.each do |field| += render 'edit' + +-# + .span8.offset1 + %h2= @user.login + .small + = link_to 'edit', edit_user_path(@user) + %dl.offset1 + - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward'] + - fields.each do |field| + %dt + = field.titleize + %dd + = user_field(field) %dt - = field.titleize + =t :email_aliases %dd - = user_field(field) - %dt - =t :email_aliases - %dd - - aliases = @user.email_aliases - - if aliases.present? - %ul.pull-left.unstyled - = render aliases - - else - =t :none - .clearfix - %dt - =t :most_recently_updated_tickets - %dd - - tix = @user.most_recent_tickets - - if tix.present? - %table - %tbody - = render @user.most_recent_tickets - - else - =t :none \ No newline at end of file + - aliases = @user.email_aliases + - if aliases.present? + %ul.pull-left.unstyled + = render aliases + - else + =t :none + .clearfix + %dt + =t :most_recently_updated_tickets + %dd + - tix = @user.most_recent_tickets + - if tix.present? + %table + %tbody + = render @user.most_recent_tickets + - else + =t :none \ No newline at end of file diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 5192e30..63ac692 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -9,25 +9,26 @@ en: login: "Log In" username: "Username" password: "Password" - login_message: "Please login with your account." + change_password: "Change Password" + login_message: "Please log in with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." update_login_and_password: "Update Login and Password" - cancel_account: "Cancel your account" - remove_account: "Remove Account" - admin_cancel_account: "Cancel the account %{username}" + destroy_my_account: "Destroy my account" + destroy_account_info: "This will permanently destroy your account and all the data associated with it. Proceed with caution!" + admin_destroy_account: "Destroy the account %{username}" set_email_address: "Set email address" - forward_email: "Forward email" - email_aliases: "Email aliases" + forward_email: "Forward Email" + email_aliases: "Email Aliases" public_key: "Public Key" - add_email_alias: "Add email alias" + add_email_alias: "Add Email Alias" user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." - email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored OpenPGP key" - can_retype_old_password: "Retype your old password if you would like to keep that" - associated_email: "The associated email address is" - + email_alias_destroyed_successfully: "Removed email alias %{alias}." + use_ascii_key: "OpenPGP public key. Do not change this value unless you know what you are doing." + advanced_options: "Advanced Options" + not_authorized: "Sorry, but you are not authorized to perform that action." + not_authorized_login: "Please log in to perform that action." activemodel: models: user: @@ -36,11 +37,12 @@ en: simple_form: labels: user: - email_forward: "Email forward" + email_forward: "Email Forward" hints: user: - email_forward: "Forward all emails to this address" - email: "Your leap web email address" + email_forward: > + Forward all email messages to this address. Messages will be encrypted before being forwarded. + This is an option for advanced users who are familar with OpenPGP. placeholders: user: email_forward: "my_other_email@domain.net" diff --git a/users/config/routes.rb b/users/config/routes.rb index d07cda9..9eff2a1 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update] + resources :users, :only => [:create, :update, :destroy] end get "login" => "sessions#new", :as => "login" @@ -16,7 +16,6 @@ Rails.application.routes.draw do resources :users do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] - resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From fcd9c579866e7d17891c4d1426ef7f230d16f1c5 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:19:38 -0700 Subject: cleaned up application layout and some minor css. --- app/assets/stylesheets/leap.scss | 13 ++++++++++--- app/views/layouts/_content.html.haml | 19 +++++++++++++++++++ app/views/layouts/_header.html.haml | 10 ++++++++-- app/views/layouts/_messages.html.haml | 11 ++++++----- app/views/layouts/application.html.haml | 14 +++----------- 5 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 app/views/layouts/_content.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 577d211..4a3ca03 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -38,6 +38,10 @@ padding-bottom: 0; } +.hidden { + display: none; +} + // // ICONS // @@ -50,8 +54,6 @@ @include ie7-restore-right-whitespace(); line-height: 32px; vertical-align: middle; - //background-image: $iconSpritePath; - //background-position: 14px 14px; background-repeat: no-repeat; margin-top: 1px; } @@ -74,7 +76,7 @@ input.large { } // -// BOOSTRAP TWEAKS +// BOOTSTRAP TWEAKS // // @@ -155,6 +157,11 @@ input, textarea { // SIDE NAVIGATION // +.user_heading { + margin: 1em 0; + font-weight: bold; +} + .sidenav { @extend .nav-tabs; @extend .nav-stacked; diff --git a/app/views/layouts/_content.html.haml b/app/views/layouts/_content.html.haml new file mode 100644 index 0000000..19af627 --- /dev/null +++ b/app/views/layouts/_content.html.haml @@ -0,0 +1,19 @@ +-# +-# Partial for displaying the page content. This is the only place that content should be displayed. +-# + +- if content_for?(:content) + - content = yield(:content) +- else + - content = yield + +- if @show_navigation + .span2 + = render 'layouts/navigation' + .span10 + = render 'layouts/messages' + = content +- else + .span12 + = render 'layouts/messages' + = content diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index aa4054b..854ab40 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -1,3 +1,9 @@ -- if user - %strong.user_address +- if admin? + %ul.nav.nav-tabs + %li{:class => ("active" if controller?('users', 'email_settings', 'overviews') || params[:user_id])} + = link_to t(:users), users_path + %li{:class => ("active" if controller?('tickets') && !params[:user_id])} + = link_to t(:tickets), tickets_path +- if user && @show_navigation + .user_heading = user.email_address diff --git a/app/views/layouts/_messages.html.haml b/app/views/layouts/_messages.html.haml index a3bbbac..7ff985f 100644 --- a/app/views/layouts/_messages.html.haml +++ b/app/views/layouts/_messages.html.haml @@ -1,5 +1,6 @@ -- flash.each do |name, msg| - - if msg.is_a?(String) - %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} - %a.close{"data-dismiss" => "alert"} × - = content_tag :div, format_flash(msg), :id => "flash_#{name}" +#messages + - flash.each do |name, msg| + - if msg.is_a?(String) + %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} + %a.close{"data-dismiss" => "alert"} × + = content_tag :div, format_flash(msg), :id => "flash_#{name}" diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e185f26..db612b7 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,3 +1,4 @@ +- @show_navigation = true if @show_navigation.nil? !!! %html %head @@ -20,16 +21,7 @@ .row-fluid .span12 = render 'layouts/header' - .row-fluid - .span2 - = render 'layouts/navigation' - .span10 - = render 'layouts/messages' - = yield - - else - .row-fluid - .span12 - = render 'layouts/messages' - = yield + .row-fluid + = render 'layouts/content' #footer = render 'layouts/footer' -- cgit v1.2.3 From 743da86885379c240cb6946b57b9df72cc508c8e Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:19:56 -0700 Subject: added strings to core en.yml --- core/config/locales/en.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index 24a2a13..38724ca 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -14,12 +14,16 @@ en: admin: "Admin" anonymous: "Anonymous" save: "Save" + add: "Add" + remove: "Remove" changes_saved: "Changes saved successfully." + are_you_sure: "Are you sure? This change cannot be undone." - download_client: "Download LEAP" - download_client_info: "The LEAP application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." + download_client: "Download Bitmask" + download_client_info: "The Bitmask application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." login_info: "Log in to change your account settings, create support tickets, and manage payments." - signup_info: "Sign up for a new user account via this website (it is better if you use the LEAP application to sign up, but this website works too)." + signup_info: "Sign up for a new user account via this website (it is better if you use the Bitmask application to sign up, but this website works too)." welcome: "Welcome to %{provider}." get_help: "Get Help" - help_info: "Can't login? Create a new support ticket anonymously." \ No newline at end of file + help_info: "Can't login? Create a new support ticket anonymously." + example_email: 'user@domain.org' -- cgit v1.2.3 From 9f7e6ed3d44fb460cd0852a1f2335ef381f5dc1b Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:11:10 -0700 Subject: better ticket view navigation: tickets are now either global in scope (for admins) or stay as a nested resource for a particular user (for normal users and when you visit the tickets list of a particular user). --- app/assets/stylesheets/leap.scss | 9 ++++ app/views/layouts/_navigation.html.haml | 11 +---- help/app/controllers/tickets_controller.rb | 41 ++++++++++++----- help/app/helpers/auto_tickets_path_helper.rb | 51 ++++++++++++++++++++++ help/app/helpers/tickets_helper.rb | 41 ++++++++++++----- help/app/views/tickets/_admin-nav.html.haml | 5 --- help/app/views/tickets/_edit_form.html.haml | 3 +- help/app/views/tickets/_new_comment_form.html.haml | 3 +- help/app/views/tickets/_order-nav.html.haml | 4 +- help/app/views/tickets/_status-nav.html.haml | 8 ++-- help/app/views/tickets/_table-nav.html.haml | 3 -- help/app/views/tickets/_ticket.html.haml | 7 +-- help/app/views/tickets/index.html.haml | 2 + help/app/views/tickets/new.html.haml | 7 ++- help/app/views/tickets/show.html.haml | 2 + help/config/routes.rb | 7 +-- 16 files changed, 152 insertions(+), 52 deletions(-) create mode 100644 help/app/helpers/auto_tickets_path_helper.rb delete mode 100644 help/app/views/tickets/_admin-nav.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 4a3ca03..792aa3c 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -105,6 +105,15 @@ input, textarea { background-image: url(/assets/glyphicons-halflings.png) !important; } +// override stupid bootstrap behavior of making the active tab appear non-clickable +// and links not being underline +.nav-tabs > li > a:hover, .sidenav > li > a:hover { + text-decoration: underline; +} +.nav-tabs > .active > a:hover { + cursor: pointer; +} + // // TICKETS // diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index 7cd0f38..cbe6d3a 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,13 +1,6 @@ -//= link_to "Leap Web", root_path, :class => 'brand' -//%ul.nav -// // = render '/tickets/nav' -// -//%ul.nav.pull-right -// = render '/sessions/nav' - %ul.nav.sidenav = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) - =# link_to_navigation t(:email_settings), edit_email_path(user), :active => controller?(:emails) - = link_to_navigation t(:support_tickets), tickets_path, :active => controller?(:tickets) + = link_to_navigation t(:email_settings), edit_user_email_settings_path(user), :active => controller?(:email_settings) + = link_to_navigation t(:support_tickets), auto_tickets_path(user), :active => controller?(:tickets) = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index 3be7d10..6fc4024 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -1,10 +1,12 @@ class TicketsController < ApplicationController + include AutoTicketsPathHelper respond_to :html, :json #has_scope :open, :type => boolean before_filter :authorize, :only => [:index] before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method + before_filter :fetch_user before_filter :set_title def new @@ -27,13 +29,13 @@ class TicketsController < ApplicationController if !logged_in? and flash[:notice] flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) end - respond_with(@ticket) + respond_with(@ticket, :location => auto_ticket_path(@ticket)) end def show @comment = TicketComment.new if !@ticket - redirect_to tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) + redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) return end end @@ -46,7 +48,7 @@ class TicketsController < ApplicationController elsif params[:commit] == t(:open) @ticket.is_open = true @ticket.save - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) elsif params[:commit] == t(:cancel) redirect_to_tickets else @@ -68,20 +70,20 @@ class TicketsController < ApplicationController respond_with @ticket end else - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end end end def index - @all_tickets = Ticket.for_user(current_user, params, admin?) #for tests, useful to have as separate variable + @all_tickets = Ticket.search(search_options(params)) @tickets = @all_tickets.page(params[:page]).per(APP_CONFIG[:pagination_size]) end def destroy # should we allow non-admins to delete their own tickets? i don't think necessary. @ticket.destroy if admin? - redirect_to tickets_path + redirect_to auto_tickets_path end protected @@ -99,17 +101,19 @@ class TicketsController < ApplicationController def redirect_to_tickets if logged_in? if params[:commit] == t(:reply_and_close) - redirect_to tickets_url + redirect_to auto_tickets_path else - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end else # if we are not logged in, there is no index to view - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end end + # # unset comments hash if no new comment was typed + # def cleanup_ticket_params(ticket) if ticket && ticket[:comments_attributes] if ticket[:comments_attributes].values.first[:body].blank? @@ -126,10 +130,27 @@ class TicketsController < ApplicationController def fetch_ticket @ticket = Ticket.find(params[:id]) if !@ticket and admin? - redirect_to tickets_path, :alert => t(:no_such_thing, :thing => 'ticket') + redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => 'ticket') return end access_denied unless ticket_access? end + def fetch_user + if params[:user_id] + @user = User.find_by_param(params[:user_id]) + end + end + + # + # clean up params for ticket search + # + def search_options(params) + params.merge( + :admin_status => params[:user_id] ? 'mine' : 'all', + :user_id => @user ? @user.id : current_user.id, + :is_admin => admin? + ) + end + end diff --git a/help/app/helpers/auto_tickets_path_helper.rb b/help/app/helpers/auto_tickets_path_helper.rb new file mode 100644 index 0000000..bb71260 --- /dev/null +++ b/help/app/helpers/auto_tickets_path_helper.rb @@ -0,0 +1,51 @@ +# +# These "auto" forms of the normal ticket path route helpers allow us to do two things automatically: +# +# (1) include the user in the path if appropriate. +# (2) retain the sort params, if appropriate. +# +# Tickets views with a user_id are limited to that user. For admins, they don't need a user_id for any ticket action. +# +# This is available both to the views and the tickets_controller. +# +module AutoTicketsPathHelper + + protected + + def auto_tickets_path(options={}) + options = ticket_view_options.merge options + if @user + user_tickets_path(@user, options) + else + tickets_path(options) + end + end + + def auto_ticket_path(ticket, options={}) + options = ticket_view_options.merge options + if @user + user_ticket_path(@user, ticket, options) + else + ticket_path(ticket, options) + end + end + + def auto_new_ticket_path(options={}) + options = ticket_view_options.merge options + if @user + new_user_ticket_path(@user, options) + else + new_ticket_path(options) + end + end + + private + + def ticket_view_options + hsh = {} + hsh[:open_status] = params[:open_status] if params[:open_status] && !params[:open_status].empty? + hsh[:sort_order] = params[:sort_order] if params[:sort_order] && !params[:sort_order].empty? + hsh + end + +end \ No newline at end of file diff --git a/help/app/helpers/tickets_helper.rb b/help/app/helpers/tickets_helper.rb index 8b4ff71..7af50d6 100644 --- a/help/app/helpers/tickets_helper.rb +++ b/help/app/helpers/tickets_helper.rb @@ -1,18 +1,39 @@ module TicketsHelper + # + # FORM HELPERS + # - def status - params[:open_status] + # + # hidden fields that should be added to ever ticket form. + # these are use for proper redirection after successful actions. + # + def hidden_ticket_fields + haml_concat hidden_field_tag('open_status', params[:open_status]) + haml_concat hidden_field_tag('sort_order', params[:sort_order]) + haml_concat hidden_field_tag('user_id', params[:user_id]) + "" end - def admin - # do we not want this set for non-admins? the param will be viewable in the url - params[:admin_status] || 'all' + # + # PARAM HELPERS + # + + def search_status + if action?(:index) + params[:open_status] || 'open' + else + nil + end end - def order + def search_order params[:sort_order] || 'updated_at_desc' end + # + # LINK HELPERS + # + def link_to_status(new_status) if new_status == "open" label = t(:open_tickets) @@ -21,13 +42,13 @@ module TicketsHelper elsif new_status == "all" label = t(:all_tickets) end - link_to label, tickets_path(:open_status => new_status, :admin_status => admin, :sort_order => order) + link_to label, auto_tickets_path(:open_status => new_status, :sort_order => search_order) end def link_to_order(order_field) - if order.start_with?(order_field) + if search_order.start_with?(order_field) # link for currently-filtered field. Link to other direction of this field. - if order.end_with? 'asc' + if search_order.end_with? 'asc' direction = 'desc' icon_direction = 'up' else @@ -47,7 +68,7 @@ module TicketsHelper label = t(:created) end - link_to :sort_order => order_field + '_at_' + direction, :open_status => status, :admin_status => admin do + link_to auto_tickets_path(:sort_order => order_field + '_at_' + direction, :open_status => search_status) do arrow + label end end diff --git a/help/app/views/tickets/_admin-nav.html.haml b/help/app/views/tickets/_admin-nav.html.haml deleted file mode 100644 index 3e65e44..0000000 --- a/help/app/views/tickets/_admin-nav.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.btn-group - %span.btn.disabled= t(:admin) + ':' - = link_to t(:my_tickets), {:admin_status => 'mine', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'mine')].join(' ') - = link_to t(:all_tickets), {:admin_status => 'all', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'all')].join(' ') -%br \ No newline at end of file diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 151d6f1..9c981a3 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -14,6 +14,7 @@ - regarding_user_link = '' = form_for @ticket do |f| + = hidden_ticket_fields %p.first - if @ticket.is_open? %span.label.label-info= t(:open) @@ -40,5 +41,5 @@ - else = f.submit t(:open), :class => 'btn' - if admin? - = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn' + = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml index de54259..ff136f3 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -2,6 +2,7 @@ -# for posting a new comment to an existing ticket. -# = simple_form_for @ticket, :html => {:class => 'slim'} do |f| + = hidden_ticket_fields = f.simple_fields_for :comments, @comment, :wrapper => :none, :html => {:class => 'slim'} do |c| = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? @@ -9,4 +10,4 @@ = f.button :submit, t(:post_reply), :class => 'btn-primary' - if logged_in? && @ticket.is_open = f.button :submit, t(:reply_and_close) - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), auto_tickets_path, :class => :btn diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml index a2ddb72..b235350 100644 --- a/help/app/views/tickets/_order-nav.html.haml +++ b/help/app/views/tickets/_order-nav.html.haml @@ -1,5 +1,5 @@ %ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} - %li{:class=> ("active" if order.start_with? 'created_at' )} + %li{:class=> ("active" if search_order.start_with? 'created_at' )} = link_to_order('created') - %li{:class=> ("active" if order.start_with? 'updated_at' )} + %li{:class=> ("active" if search_order.start_with? 'updated_at' )} = link_to_order('updated') diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index c8279ed..8e51497 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -1,10 +1,10 @@ %ul.nav.nav-tabs - if logged_in? - %li{:class => ("active" if status == 'open')} + %li{:class => ("active" if search_status == 'open')} = link_to_status 'open' - %li{:class => ("active" if status == 'closed')} + %li{:class => ("active" if search_status == 'closed')} = link_to_status 'closed' - %li{:class => ("active" if status == 'all')} + %li{:class => ("active" if search_status == 'all')} = link_to_status 'all' %li{:class => ("active" if action?(:new))} - = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path + = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index a5cf8be..45ebfb2 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,6 +1,3 @@ -- if admin? - = render 'tickets/admin-nav' - - unless action?(:new) = render 'tickets/order-nav' = render 'tickets/status-nav' diff --git a/help/app/views/tickets/_ticket.html.haml b/help/app/views/tickets/_ticket.html.haml index 9a1e899..a064c4e 100644 --- a/help/app/views/tickets/_ticket.html.haml +++ b/help/app/views/tickets/_ticket.html.haml @@ -1,5 +1,6 @@ +- url = auto_ticket_path(ticket) %tr - %td= link_to ticket.title, ticket - %td= link_to ticket.created_at.to_s(:short), ticket - %td= link_to ticket.updated_at.to_s(:short), ticket + %td= link_to ticket.title, url + %td= link_to ticket.created_at.to_s(:short), url + %td= link_to ticket.updated_at.to_s(:short), url %td= ticket.commenters diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index f4597a7..1b32dc1 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,3 +1,5 @@ +- @show_navigation = !params[:user_id].nil? + = render 'tickets/table-nav' %table.table.table-striped.table-bordered diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 7d3f76c..04b091c 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,6 +1,9 @@ +- @show_navigation = !params[:user_id].nil? + = render 'tickets/table-nav' = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| + = hidden_ticket_fields = f.input :title, :label => t(:subject) - if user = f.input :email, input_html: {value: user.email_address} @@ -15,4 +18,6 @@ .form-actions = f.button :submit, :class => 'btn-primary' - if logged_in? - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), auto_tickets_path, :class => :btn + - else + = link_to t(:cancel), root_path, :class => 'btn' \ No newline at end of file diff --git a/help/app/views/tickets/show.html.haml b/help/app/views/tickets/show.html.haml index ddd4e9f..bfdb773 100644 --- a/help/app/views/tickets/show.html.haml +++ b/help/app/views/tickets/show.html.haml @@ -1,3 +1,5 @@ +- @show_navigation = !params[:user_id].nil? + .ticket = render 'tickets/edit_form' %table.table.table-striped.table-bordered diff --git a/help/config/routes.rb b/help/config/routes.rb index 86a9201..8f3241c 100644 --- a/help/config/routes.rb +++ b/help/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do - - resources :tickets, :only => [:new, :create, :index, :show, :update, :destroy] - #resources :ticket, :only => [:show] + resources :tickets, :except => :edit + resources :users do + resources :tickets, :except => :edit + end end -- cgit v1.2.3 From ec43635ebda591353b4cb30bbeb7a5a9ab07f9ba Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:20:06 -0700 Subject: removed commented out code from ticket.rb --- help/app/models/ticket.rb | 101 +++++++++++----------------------------------- 1 file changed, 24 insertions(+), 77 deletions(-) diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb index 738487a..09bc64d 100644 --- a/help/app/models/ticket.rb +++ b/help/app/models/ticket.rb @@ -1,49 +1,30 @@ +# +# TODO: thought i should reverse keys for descending, but that didn't work. +# look into whether that should be tweaked, and whether it works okay with +# pagination (seems to now...) +# +# TODO: better validation of email +# +# TODO: don't hardcode strings 'unknown user' and 'unauthenticated user' +# class Ticket < CouchRest::Model::Base - #include ActiveModel::Validations - use_database "tickets" - #require 'securerandom' -=begin - title - created_at - updated_at - email_address - user - user_verified? - admins (list of admins who have commented on the ticket) - code (secret url) -=end - - #belongs_to :user #from leap_web_users. doesn't necessarily belong to a user though - property :created_by, String, :protected => true #Integer #nil unless user was authenticated for ticket creation, #THIS should not be changed after being set - property :regarding_user, String#Integer # form cannot be submitted if they type in a username w/out corresponding ID. this field can be nil. for authenticated ticket creation by non-admins, should this just automatically be set to be same as created_by? or maybe we don't use this field unless created_by is nil? - #also, both created_by and regarding_user could be nil---say user forgets username, or has general question - property :title, String - property :email, String #verify - - #property :user_verified, TrueClass, :default => false #will be true exactly when user is set - #admins - #property :code, String, :protected => true # only should be set if created_by is nil #instead we will just use couchdb ID - property :is_open, TrueClass, :default => true - property :comments, [TicketComment] + + property :created_by, String, :protected => true # nil for anonymous tickets, should never be changed + property :regarding_user, String # may be nil or valid username + property :title, String + property :email, String + property :is_open, TrueClass, :default => true + property :comments, [TicketComment] timestamps! - #before_validation :set_created_by, :set_code, :set_email, :on => :create before_validation :set_email, :set_regarding_user, :on => :create - - #named_scope :open, :conditions => {:is_open => true} #?? - design do - #TODO--clean this all up - #view :by_is_open - #view :by_created_by - view :by_updated_at view :by_created_at - #view :by_is_open_and_created_by view :by_is_open_and_created_at view :by_is_open_and_updated_at @@ -52,21 +33,9 @@ class Ticket < CouchRest::Model::Base end validates :title, :presence => true - #validates :comments, :presence => true #do we want it like this? - - - # html5 has built-in validation which isn't ideal, as it says 'please enter an email address' for invalid email addresses, which implies an email address is required, and it is not. validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ - #TODO: - #def set_created_by - # self.created_by = User.current if User.current - #end - def self.for_user(user, options = {}, is_admin = false) - - # TODO: thought i should reverse keys for descending, but that didn't work. look into whether that should be tweaked, and whether it works okay with pagination (seems to now...) - options[:user_id] = user.id options[:is_admin] = is_admin @@ -74,41 +43,24 @@ class Ticket < CouchRest::Model::Base @selection.tickets end - #def self.tickets_by_commenter(user_id)#, options = {}) - # Ticket.includes_post_by_and_updated_at.startkey([user_id, 0]).endkey([user_id, Time.now]) - #end - def is_creator_validated? !!created_by end -=begin - def set_code #let's not use this---can use same show url - # ruby 1.9 provides url-safe option---this is not necessarily url-safe - self.code = SecureRandom.hex(8) if !is_creator_validated? - end -=end - - def set_email self.email = nil if self.email == "" - # in controller set to be current users email if that exists end def set_regarding_user self.regarding_user = nil if self.regarding_user == "" end - #not saving with close and reopen, as we will save in update when they are called. - #TODO: not sure if we should bother with these: def close self.is_open = false - #save end def reopen self.is_open = true - #save end def commenters @@ -118,20 +70,21 @@ class Ticket < CouchRest::Model::Base if user = User.find(comment.posted_by) commenters << user.login if user and !commenters.include?(user.login) else - commenters << 'unknown user' if !commenters.include?('unknown user') #todo don't hardcode string 'unknown user' + commenters << 'unknown user' if !commenters.include?('unknown user') end else - commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') #todo don't hardcode string 'unauthenticated user' + commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') end end commenters.join(', ') end + # + # update comments. User should be set by controller. + # def comments_attributes=(attributes) - if attributes # could be empty as we will empty if nothing was typed in - comment = TicketComment.new(attributes.values.first) #TicketComment.new(attributes) - #comment.posted_by = User.current.id if User.current #we want to avoid User.current, and current_user won't work here. instead will set in tickets_controller - # what about: comment.posted_by = self.updated_by (will need to add ticket.updated_by) + if attributes + comment = TicketComment.new(attributes.values.first) comment.posted_at = Time.now comments << comment end @@ -144,11 +97,5 @@ class Ticket < CouchRest::Model::Base def regarding_user_actual_user User.find_by_login(self.regarding_user) end -=begin - def validate - if email_address and not email_address.strip =~ RFC822::EmailAddress - errors.add 'email', 'contains an invalid address' - end - end -=end + end -- cgit v1.2.3 From cb10067ef5db7ed88356159ffa99902f877860e6 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:21:04 -0700 Subject: fixed security vulnerability with ticket searching --- help/app/models/ticket.rb | 5 +---- help/app/models/ticket_selection.rb | 41 ++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb index 09bc64d..8066d0d 100644 --- a/help/app/models/ticket.rb +++ b/help/app/models/ticket.rb @@ -35,10 +35,7 @@ class Ticket < CouchRest::Model::Base validates :title, :presence => true validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ - def self.for_user(user, options = {}, is_admin = false) - options[:user_id] = user.id - options[:is_admin] = is_admin - + def self.search(options = {}) @selection = TicketSelection.new(options) @selection.tickets end diff --git a/help/app/models/ticket_selection.rb b/help/app/models/ticket_selection.rb index bebe5fc..74d5b78 100644 --- a/help/app/models/ticket_selection.rb +++ b/help/app/models/ticket_selection.rb @@ -1,10 +1,20 @@ class TicketSelection + # + # supported options: + # + # user_id: id of the user (uuid string) + # open_status: open | closed | all + # sort_order: updated_at_desc | updated_at_asc | created_at_desc | created_at_asc + # admin_status: mine | all + # is_admin: true | false + # def initialize(options = {}) - @options = options - @options[:open_status] ||= 'open' - @options[:sort_order] ||= 'updated_at_desc' - + @user_id = options[:user_id].gsub /[^a-z0-9]/, '' + @open_status = allow options[:open_status], 'open', 'closed', 'all' + @sort_order = allow options[:sort_order], 'updated_at_desc', 'updated_at_asc', 'created_at_desc', 'created_at_asc' + @admin_status = allow options[:admin_status], 'mine', 'all' + @is_admin = allow options[:is_admin], false, true end def tickets @@ -13,25 +23,32 @@ class TicketSelection protected + def allow(source, *allowed) + if allowed.include?(source) + source + else + allowed.first + end + end def finder_method method = 'by_' method += 'includes_post_by_and_' if only_mine? - method += 'is_open_and_' if @options[:open_status] != 'all' - method += @options[:sort_order].sub(/_(de|a)sc$/, '') + method += 'is_open_and_' if @open_status != 'all' + method += @sort_order.sub(/_(de|a)sc$/, '') end def startkey startkeys = [] - startkeys << @options[:user_id] if only_mine? - startkeys << (@options[:open_status] == 'open') if @options[:open_status] != 'all' + startkeys << @user_id if only_mine? + startkeys << (@open_status == 'open') if @open_status != 'all' startkeys << 0 - startkeys = startkeys.join if startkeys.length == 1 #want string not array if just one thing in array + startkeys = startkeys.join if startkeys.length == 1 # want string not array if just one thing in array startkeys end def endkey - endtime = Time.now + 2.days #TODO. this obviously isn't ideal + endtime = Time.now + 2.days # TODO. this obviously isn't ideal if self.startkey.is_a?(Array) endkeys = self.startkey endkeys.pop @@ -43,12 +60,12 @@ class TicketSelection def order # we have defined the ascending method to return the view itself: - (@options[:sort_order].end_with? 'desc') ? 'descending' : 'ascending' + (@sort_order.end_with? 'desc') ? 'descending' : 'ascending' end def only_mine? - !@options[:is_admin] or (@options[:admin_status] == 'mine') + !@is_admin || @admin_status == 'mine' end end -- cgit v1.2.3 From 738a6c5576992e665821c76ad720a58edd228b28 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:33:09 -0700 Subject: fix user typeahead --- users/app/assets/javascripts/users.js | 4 ++-- users/app/controllers/v1/users_controller.rb | 12 +++++++++++- users/app/views/users/index.html.haml | 13 ++++++------- users/config/routes.rb | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js index eed1961..1d05692 100644 --- a/users/app/assets/javascripts/users.js +++ b/users/app/assets/javascripts/users.js @@ -10,7 +10,7 @@ }; poll_users = function(query, process) { - return $.get("/users.json", { + return $.get("/1/users.json", { query: query }).done(process); }; @@ -66,7 +66,7 @@ $('#new_session').submit(srp.login); $('#update_login_and_password').submit(prevent_default); $('#update_login_and_password').submit(srp.update); - return $('.user.typeahead').typeahead({ + return $('#user-typeahead').typeahead({ source: poll_users }); }); diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e7516bc..e117fc7 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -2,11 +2,21 @@ module V1 class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token - before_filter :authorize, :only => [:update] before_filter :fetch_user, :only => [:update] + before_filter :authorize, :only => [:update] + before_filter :authorize_admin, :only => [:index] respond_to :json + def index + if params[:query] + @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + respond_with @users.map(&:login).sort + else + render :json => {'error' => 'query required', 'status' => :unprocessable_entity} + end + end + def create @user = User.create(params[:user]) respond_with @user # return ID instead? diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 254e177..fc1001e 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -2,13 +2,12 @@ = form_tag users_path, :method => :get, :class => "form-search" do .input-append - = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off - %button.btn{:type => :submit} Search + = text_field_tag :query, params[:query], :id => 'user-typeahead', :class => "search-query", :autocomplete => :off + %button.btn{:type => :submit}= t(:search) -%table.table.table-hover +%table.table.table-striped %tr - %th Login - %th Created - %th Action + %th= t(:username) + %th= t(:created) + %th= t(:updated) = render @users.all - diff --git a/users/config/routes.rb b/users/config/routes.rb index 9eff2a1..693ae7a 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update, :destroy] + resources :users, :only => [:create, :update, :destroy, :index] end get "login" => "sessions#new", :as => "login" -- cgit v1.2.3 From 7569f58c656fd2c274e49da6f366b9ef7138e961 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:06 -0700 Subject: users - make a nice overview page (well, nice enough) and better users index/search. --- users/app/controllers/users_controller.rb | 21 ++++++++------------- users/app/views/overviews/show.html.haml | 27 +++++++++++++++------------ users/app/views/users/_user.html.haml | 12 +++--------- users/config/locales/en.yml | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 09622b3..98294b9 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -3,22 +3,24 @@ # class UsersController < UsersBaseController - before_filter :authorize, :only => [:show, :edit, :update, :destroy] before_filter :fetch_user, :only => [:show, :edit, :update, :destroy] - #before_filter :authorize_self, :only => [:update] before_filter :authorize_admin, :only => [:index] - respond_to :json + respond_to :html def index if params[:query] - @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + if @user = User.find_by_login(params[:query]) + redirect_to user_overview_url(@user) + return + else + @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + end else @users = User.by_created_at.descending end - @users = @users.limit(APP_CONFIG[:pagination_size]) - #respond_with @users.map(&:login).sort + @users = @users.limit(100) end def new @@ -52,11 +54,4 @@ class UsersController < UsersBaseController end end - protected - - #def authorize_self - # # have already checked that authorized - # access_denied unless (@user == current_user) - #end - end diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml index eda9899..b8ad814 100644 --- a/users/app/views/overviews/show.html.haml +++ b/users/app/views/overviews/show.html.haml @@ -1,15 +1,18 @@ -%p - Username: - = @user.login +.overview -%p - User since: - = @user.created_at + %h2.first= t(:overview_welcome, :username => @user.login) -%p - Last update: - = @user.updated_at + - if admin? + %p + = t(:created) + = @user.created_at + %br + = t(:updated) + = @user.updated_at -%p - Quota: - N/A \ No newline at end of file + %p= t(:overview_intro) + + %ul.unstyled + %li= icon('user') + link_to(t(:overview_account), edit_user_path(@user)) + %li= icon('envelope') + link_to(t(:overview_email), edit_user_email_settings_path(@user)) + %li= icon('question-sign') + link_to(t(:overview_tickets), user_tickets_path(@user)) diff --git a/users/app/views/users/_user.html.haml b/users/app/views/users/_user.html.haml index ca03d34..990d9cf 100644 --- a/users/app/views/users/_user.html.haml +++ b/users/app/views/users/_user.html.haml @@ -1,10 +1,4 @@ %tr - %td= link_to user.login, user - %td= time_ago_in_words(user.created_at) + " ago" - %td - = link_to edit_user_path(user), :class => "btn btn-mini btn-primary" do - %i.icon-edit.icon-white - Edit - = link_to user_path(user), :method => :delete, :class => "btn btn-danger btn-mini" do - %i.icon-remove.icon-white - Remove + %td= link_to user.login, user_overview_path(user) + %td= l(user.created_at, :format => :short) + %td= l(user.updated_at, :format => :short) diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 63ac692..b880887 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -29,6 +29,20 @@ en: advanced_options: "Advanced Options" not_authorized: "Sorry, but you are not authorized to perform that action." not_authorized_login: "Please log in to perform that action." + search: "Search" + + # + # overview + # + overview_welcome: "Welcome %{username}." + overview_intro: "From this user control panel, you can:" + overview_tickets: "Create and check support tickets." + overview_email: "Modify email settings." + overview_account: "Change your password or delete your account." + + # + # rails + # activemodel: models: user: -- cgit v1.2.3 From 65fed45ce918011dd3e563b114651d434fadb23c Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:29 -0700 Subject: test - we allow updating of username via api now --- users/test/integration/api/account_flow_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb index 1698105..2e45367 100644 --- a/users/test/integration/api/account_flow_test.rb +++ b/users/test/integration/api/account_flow_test.rb @@ -88,10 +88,11 @@ class AccountFlowTest < RackTest server_auth = @srp.authenticate(self) test_public_key = 'asdlfkjslfdkjasd' original_login = @user.login - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => 'failed_login_name'}, :format => :json + new_login = 'zaph' + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => new_login}, :format => :json @user.reload assert_equal test_public_key, @user.public_key - assert_equal original_login, @user.login + assert_equal new_login, @user.login # eventually probably want to remove most of this into a non-integration functional test # should not overwrite public key: put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:blee => :blah}, :format => :json -- cgit v1.2.3 From c96f3544c5e7289eb4157981cc9f680d689d861f Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:35:49 -0700 Subject: help - fix ticket navigation & links (use @user, not user). --- app/views/layouts/_header.html.haml | 6 ++++-- app/views/layouts/_navigation.html.haml | 8 ++++---- app/views/layouts/application.html.haml | 2 +- help/app/views/tickets/_order-nav.html.haml | 5 ----- help/app/views/tickets/_status-nav.html.haml | 10 ---------- help/app/views/tickets/_table-nav.html.haml | 4 ---- help/app/views/tickets/_tabs.html.haml | 23 +++++++++++++++++++++++ help/app/views/tickets/index.html.haml | 2 +- help/app/views/tickets/new.html.haml | 15 +++++++++++---- 9 files changed, 44 insertions(+), 31 deletions(-) delete mode 100644 help/app/views/tickets/_order-nav.html.haml delete mode 100644 help/app/views/tickets/_status-nav.html.haml delete mode 100644 help/app/views/tickets/_table-nav.html.haml create mode 100644 help/app/views/tickets/_tabs.html.haml diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 854ab40..b459545 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -4,6 +4,8 @@ = link_to t(:users), users_path %li{:class => ("active" if controller?('tickets') && !params[:user_id])} = link_to t(:tickets), tickets_path -- if user && @show_navigation + %li + = link_to t(:logout), logout_path, :method => :delete +- if @user && @show_navigation .user_heading - = user.email_address + = @user.email_address diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index cbe6d3a..b42c1fe 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,6 +1,6 @@ %ul.nav.sidenav - = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) - = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) - = link_to_navigation t(:email_settings), edit_user_email_settings_path(user), :active => controller?(:email_settings) - = link_to_navigation t(:support_tickets), auto_tickets_path(user), :active => controller?(:tickets) + = link_to_navigation t(:overview), user_overview_path(@user), :active => controller?(:overviews) + = link_to_navigation t(:account_settings), edit_user_path(@user), :active => controller?(:users) + = link_to_navigation t(:email_settings), edit_user_email_settings_path(@user), :active => controller?(:email_settings) + = link_to_navigation t(:support_tickets), auto_tickets_path(@user), :active => controller?(:tickets) = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index db612b7..d5adca9 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,4 +1,4 @@ -- @show_navigation = true if @show_navigation.nil? +- @show_navigation = true if @show_navigation.nil? && logged_in? !!! %html %head diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml deleted file mode 100644 index b235350..0000000 --- a/help/app/views/tickets/_order-nav.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} - %li{:class=> ("active" if search_order.start_with? 'created_at' )} - = link_to_order('created') - %li{:class=> ("active" if search_order.start_with? 'updated_at' )} - = link_to_order('updated') diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml deleted file mode 100644 index 8e51497..0000000 --- a/help/app/views/tickets/_status-nav.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%ul.nav.nav-tabs - - if logged_in? - %li{:class => ("active" if search_status == 'open')} - = link_to_status 'open' - %li{:class => ("active" if search_status == 'closed')} - = link_to_status 'closed' - %li{:class => ("active" if search_status == 'all')} - = link_to_status 'all' - %li{:class => ("active" if action?(:new))} - = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml deleted file mode 100644 index 45ebfb2..0000000 --- a/help/app/views/tickets/_table-nav.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- unless action?(:new) - = render 'tickets/order-nav' -= render 'tickets/status-nav' - diff --git a/help/app/views/tickets/_tabs.html.haml b/help/app/views/tickets/_tabs.html.haml new file mode 100644 index 0000000..b7b5d3a --- /dev/null +++ b/help/app/views/tickets/_tabs.html.haml @@ -0,0 +1,23 @@ +-# +-# SORT ORDER TABS +-# +- unless action?(:new) + %ul.nav.nav-pills.pull-right.slim + %li{:class=> ("active" if search_order.start_with? 'created_at')} + = link_to_order('created') + %li{:class=> ("active" if search_order.start_with? 'updated_at')} + = link_to_order('updated') + +-# +-# STATUS FILTER TABS +-# +%ul.nav.nav-tabs + - if logged_in? + %li{:class => ("active" if search_status == 'open')} + = link_to_status 'open' + %li{:class => ("active" if search_status == 'closed')} + = link_to_status 'closed' + %li{:class => ("active" if search_status == 'all')} + = link_to_status 'all' + %li{:class => ("active" if action?(:new))} + = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index 1b32dc1..c02a326 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,6 +1,6 @@ - @show_navigation = !params[:user_id].nil? -= render 'tickets/table-nav' += render 'tickets/tabs' %table.table.table-striped.table-bordered %thead diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 04b091c..4d35659 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,13 +1,20 @@ - @show_navigation = !params[:user_id].nil? -= render 'tickets/table-nav' += render 'tickets/tabs' + +- if admin? && @user + - email = @user.email_address + - regarding = @user.login +- elsif logged_in? + - email = current_user.email_address + - regarding = current_user.login = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| = hidden_ticket_fields = f.input :title, :label => t(:subject) - - if user - = f.input :email, input_html: {value: user.email_address} - = f.input :regarding_user, input_html: {value: user.login} + - if logged_in? + = f.input :email, input_html: {value: email} + = f.input :regarding_user, input_html: {value: regarding} - else = f.input :email = f.input :regarding_user -- cgit v1.2.3 From 4b6c22acb24c140860eac3ca567673ec14c3c308 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:36:08 -0700 Subject: minor changes to css and home page. --- app/assets/stylesheets/leap.scss | 8 ++++++++ app/views/home/index.html.haml | 7 +------ core/app/helpers/core_helper.rb | 13 +++++++++++++ core/app/helpers/snippet_helper.rb | 11 ----------- 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 core/app/helpers/core_helper.rb delete mode 100644 core/app/helpers/snippet_helper.rb diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 792aa3c..6268b3b 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -184,3 +184,11 @@ input, textarea { } } } + +// +// USERS +// + +.overview li { + padding: 6px 0; +} \ No newline at end of file diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 9da66a1..8c90436 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -9,9 +9,4 @@ .row-fluid %hr %p - Try to fetch a - = link_to "cert", cert_path - - %p - Create a - = link_to "ticket", new_ticket_path + = link_to "fetch a cert", cert_path diff --git a/core/app/helpers/core_helper.rb b/core/app/helpers/core_helper.rb new file mode 100644 index 0000000..a496144 --- /dev/null +++ b/core/app/helpers/core_helper.rb @@ -0,0 +1,13 @@ +# +# Misc. helpers needed throughout. +# +module CoreHelper + + # + # insert common buttons (download, login, etc) + # + def home_page_buttons + render 'common/home_page_buttons' + end + +end \ No newline at end of file diff --git a/core/app/helpers/snippet_helper.rb b/core/app/helpers/snippet_helper.rb deleted file mode 100644 index 6fee454..0000000 --- a/core/app/helpers/snippet_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# -# various html snippets we use throughout. -# - -module SnippetHelper - - def home_page_buttons - render 'common/home_page_buttons' - end - -end \ No newline at end of file -- cgit v1.2.3 From ab2aafa74ea98c4a7af65b87ee32487883e702c1 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:45:41 -0700 Subject: allow forms with blank email forward. --- users/app/controllers/email_settings_controller.rb | 9 ++++++++- users/app/models/user.rb | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb index 0261b47..f7d85be 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -8,7 +8,7 @@ class EmailSettingsController < UsersBaseController end def update - @user.attributes = params[:user] + @user.attributes = cleanup_params(params[:user]) if @user.changed? if @user.save flash[:notice] = t(:changes_saved) @@ -31,4 +31,11 @@ class EmailSettingsController < UsersBaseController redirect_to edit_user_email_settings_url(@user) end + def cleanup_params(user) + if !user['email_forward'].nil? && user['email_forward'].empty? + user.delete('email_forward') # don't allow "" as an email forward + end + user + end + end diff --git a/users/app/models/user.rb b/users/app/models/user.rb index 5c849f0..3459520 100644 --- a/users/app/models/user.rb +++ b/users/app/models/user.rb @@ -42,6 +42,7 @@ class User < CouchRest::Model::Base :format => { :with => /.{8}.*/, :message => "needs to be at least 8 characters long" } validates :email_forward, + :allow_blank => true, :format => { :with => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/, :message => "needs to be a valid email address"} timestamps! -- cgit v1.2.3 From ba4b11f9357d02a82ab1360d1db009fca0ba993a Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 02:44:11 -0700 Subject: user tests -- user update has been moved entirely to api controller, so fix tests to reflect this. --- users/app/controllers/users_controller.rb | 5 -- users/app/controllers/v1/users_controller.rb | 1 - users/config/routes.rb | 2 +- users/test/functional/users_controller_test.rb | 65 +-------------------- users/test/functional/v1/users_controller_test.rb | 70 +++++++++++++++++++++++ users/test/support/auth_test_helper.rb | 16 ++++-- 6 files changed, 84 insertions(+), 75 deletions(-) create mode 100644 users/test/functional/v1/users_controller_test.rb diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 98294b9..6664bd7 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -27,11 +27,6 @@ class UsersController < UsersBaseController @user = User.new end - def create - @user = User.create(params[:user]) - respond_with @user - end - def show end diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e117fc7..fda56f2 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -23,7 +23,6 @@ module V1 end def update - @user = User.find_by_param(params[:id]) @user.update_attributes params[:user] if @user.valid? flash[:notice] = t(:user_updated_successfully) diff --git a/users/config/routes.rb b/users/config/routes.rb index 693ae7a..b6d583e 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -13,7 +13,7 @@ Rails.application.routes.draw do resources :sessions, :only => [:new, :create, :update] get "signup" => "users#new", :as => "signup" - resources :users do + resources :users, :except => [:create, :update] do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ diff --git a/users/test/functional/users_controller_test.rb b/users/test/functional/users_controller_test.rb index fd8869a..92a5f6c 100644 --- a/users/test/functional/users_controller_test.rb +++ b/users/test/functional/users_controller_test.rb @@ -79,33 +79,6 @@ class UsersControllerTest < ActionController::TestCase assert_redirected_to users_path end - test "should create new user" do - user_attribs = record_attributes_for :user - user = User.new(user_attribs) - User.expects(:create).with(user_attribs).returns(user) - - - post :create, :user => user_attribs, :format => :json - - - assert_nil session[:user_id] - assert_json_response user - assert_response :success - end - - test "should redirect to signup form on failed attempt" do - user_attribs = record_attributes_for :user - user_attribs.slice!('login') - user = User.new(user_attribs) - assert !user.valid? - User.expects(:create).with(user_attribs).returns(user) - - post :create, :user => user_attribs, :format => :json - - assert_json_error user.errors.messages - assert_response 422 - end - test "should get edit view" do user = find_record :user @@ -115,34 +88,6 @@ class UsersControllerTest < ActionController::TestCase assert_equal user, assigns[:user] end - test "user can change settings" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - user.expects(:attributes=).with(changed_attribs) - user.expects(:changed?).returns(true) - user.expects(:save).returns(true) - - login user - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_equal user, assigns[:user] - assert_response 204 - assert_equal " ", @response.body - end - - # Eventually, admin will be able to update some user fields - test "admin cannot update user" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - - login :is_admin? => true - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_response :redirect - assert_access_denied - - end - test "admin can destroy user" do user = find_record :user user.expects(:destroy) @@ -162,7 +107,7 @@ class UsersControllerTest < ActionController::TestCase delete :destroy, :id => @current_user.id assert_response :redirect - assert_redirected_to login_path + assert_redirected_to root_path end test "non-admin can't destroy user" do @@ -189,14 +134,6 @@ class UsersControllerTest < ActionController::TestCase assert_access_denied end - test "admin can autocomplete users" do - login :is_admin? => true - get :index, :format => :json - - assert_response :success - assert assigns(:users) - end - test "admin can search users" do login :is_admin? => true get :index, :query => "a" diff --git a/users/test/functional/v1/users_controller_test.rb b/users/test/functional/v1/users_controller_test.rb new file mode 100644 index 0000000..0d44e50 --- /dev/null +++ b/users/test/functional/v1/users_controller_test.rb @@ -0,0 +1,70 @@ +require 'test_helper' + +class V1::UsersControllerTest < ActionController::TestCase + + test "user can change settings" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login user + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + assert_equal " ", @response.body + end + + test "admin can update user" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login :is_admin? => true + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + end + + test "user cannot update other user" do + user = find_record :user + login + put :update, :user => record_attributes_for(:user_with_settings), :id => user.id, :format => :json + assert_access_denied + end + + test "should create new user" do + user_attribs = record_attributes_for :user + user = User.new(user_attribs) + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_nil session[:user_id] + assert_json_response user + assert_response :success + end + + test "should redirect to signup form on failed attempt" do + user_attribs = record_attributes_for :user + user_attribs.slice!('login') + user = User.new(user_attribs) + assert !user.valid? + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_json_error user.errors.messages + assert_response 422 + end + + test "admin can autocomplete users" do + login :is_admin? => true + get :index, :query => 'a', :format => :json + + assert_response :success + assert assigns(:users) + end + +end diff --git a/users/test/support/auth_test_helper.rb b/users/test/support/auth_test_helper.rb index c0fcf3a..555b5db 100644 --- a/users/test/support/auth_test_helper.rb +++ b/users/test/support/auth_test_helper.rb @@ -20,10 +20,18 @@ module AuthTestHelper def assert_access_denied(denied = true, logged_in = true) if denied - assert_equal({:alert => "Not authorized"}, flash.to_hash) - # todo: eventually probably eliminate separate conditions - assert_redirected_to login_path if !logged_in - assert_redirected_to root_path if logged_in + if @response.content_type == 'application/json' + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + else + if logged_in + assert_equal({:alert => I18n.t(:not_authorized)}, flash.to_hash) + assert_redirected_to root_url + else + assert_equal({:alert => I18n.t(:not_authorized_login)}, flash.to_hash) + assert_redirected_to login_url + end + end else assert flash[:alert].blank? end -- cgit v1.2.3 From 74ec83bab0c04fe43c1b000cb40576b1b8e3f3e9 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:37:44 -0700 Subject: fix ticket tests, get :admin_user factory to work. --- help/test/functional/tickets_controller_test.rb | 13 +++++++------ users/test/factories.rb | 4 +++- users/test/support/stub_record_helper.rb | 9 ++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/help/test/functional/tickets_controller_test.rb b/help/test/functional/tickets_controller_test.rb index f8627d8..6479ba4 100644 --- a/help/test/functional/tickets_controller_test.rb +++ b/help/test/functional/tickets_controller_test.rb @@ -181,23 +181,24 @@ class TicketsControllerTest < ActionController::TestCase test "admin_status mine vs all" do testticket = FactoryGirl.create :ticket + user = find_record :user login :is_admin? => true, :email => nil - get :index, {:admin_status => "all", :open_status => "open"} + get :index, {:open_status => "open"} assert assigns(:all_tickets).include?(testticket) - get :index, {:admin_status => "mine", :open_status => "open"} + get :index, {:user_id => user.id, :open_status => "open"} assert !assigns(:all_tickets).include?(testticket) testticket.destroy end test "commenting on a ticket adds to tickets that are mine" do testticket = FactoryGirl.create :ticket - login :is_admin? => true, :email => nil - - get :index, {:admin_status => "mine", :open_status => "open"} + user = find_record :admin_user + login user + get :index, {:user_id => user.id, :open_status => "open"} assert_difference('assigns[:all_tickets].count') do put :update, :id => testticket.id, :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}}} - get :index, {:admin_status => "mine", :open_status => "open"} + get :index, {:user_id => user.id, :open_status => "open"} end assert assigns(:all_tickets).include?(assigns(:ticket)) diff --git a/users/test/factories.rb b/users/test/factories.rb index 6b094bd..777704b 100644 --- a/users/test/factories.rb +++ b/users/test/factories.rb @@ -13,7 +13,9 @@ FactoryGirl.define do end factory :admin_user do - is_admin? true + after(:build) do |admin| + admin.stubs(:is_admin?).returns(true) + end end end end diff --git a/users/test/support/stub_record_helper.rb b/users/test/support/stub_record_helper.rb index 168a827..8aa1973 100644 --- a/users/test/support/stub_record_helper.rb +++ b/users/test/support/stub_record_helper.rb @@ -1,15 +1,18 @@ module StubRecordHelper - # Will expect find_by_param or find_by_id to be called on klass and + # + # We will stub find_by_param or find_by_id to be called on klass and # return the record given. + # # If no record is given but a hash or nil will create a stub based on # that instead and returns the stub. + # def find_record(factory, attribs_hash = {}) - attribs_hash.reverse_merge!(:id => Random.rand(10000).to_s) + attribs_hash = attribs_hash.reverse_merge(:id => Random.rand(10000).to_s) record = stub_record factory, attribs_hash klass = record.class finder = klass.respond_to?(:find_by_param) ? :find_by_param : :find - klass.expects(finder).with(record.to_param.to_s).returns(record) + klass.stubs(finder).with(record.to_param.to_s).returns(record) return record end -- cgit v1.2.3 From 603c8ee05987cfc25747d99b786b49de6bfe0b89 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:38:00 -0700 Subject: remove empty readme files --- users/README.rdoc | 3 --- users/Readme.md | 0 2 files changed, 3 deletions(-) delete mode 100644 users/README.rdoc delete mode 100644 users/Readme.md diff --git a/users/README.rdoc b/users/README.rdoc deleted file mode 100644 index 9fb44c1..0000000 --- a/users/README.rdoc +++ /dev/null @@ -1,3 +0,0 @@ -= LeapWebUsers - -This project rocks and uses MIT-LICENSE. \ No newline at end of file diff --git a/users/Readme.md b/users/Readme.md deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3 From 26018b4f88d7dc49f3710ac9ccd761791553dfc6 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:39:11 -0700 Subject: add 'blue' to admins in dev mode. --- config/defaults.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/defaults.yml b/config/defaults.yml index 6317082..54c5a23 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -16,7 +16,7 @@ cert_options: &cert_options development: <<: *dev_ca <<: *cert_options - admins: [admin, admin2] + admins: [blue, admin, admin2] domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' pagination_size: 30 -- cgit v1.2.3 From 3f51128e24e1ca3247169066aa6a03090df98dd6 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:26:35 -0700 Subject: start of new ui - css changes, layout changes, navigation changes. --- app/assets/stylesheets/application.scss | 15 ++---- app/assets/stylesheets/leap.scss | 65 +++++++++++++++++++++++ app/helpers/application_helper.rb | 17 ++++++ app/helpers/navigation_helper.rb | 82 +++++++++++++++++++++++++++++ app/views/home/_home_text.html.haml | 3 ++ app/views/home/index.html.haml | 23 ++++---- app/views/layouts/_footer.html.haml | 0 app/views/layouts/_header.html.haml | 3 ++ app/views/layouts/_masthead.html.haml | 4 ++ app/views/layouts/_masthead_large.html.haml | 3 ++ app/views/layouts/_navigation.html.haml | 17 ++++-- app/views/layouts/application.html.haml | 30 +++++++---- config/defaults.yml | 4 +- config/locales/en.yml | 7 +++ 14 files changed, 238 insertions(+), 35 deletions(-) create mode 100644 app/assets/stylesheets/leap.scss create mode 100644 app/helpers/navigation_helper.rb create mode 100644 app/views/home/_home_text.html.haml create mode 100644 app/views/layouts/_footer.html.haml create mode 100644 app/views/layouts/_header.html.haml create mode 100644 app/views/layouts/_masthead.html.haml create mode 100644 app/views/layouts/_masthead_large.html.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 25e854e..5a5e900 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,7 +1,7 @@ // // import custom scss, content to be set in deployment. // -@import "tail"; +@import "head"; // First import journal variables @import "bootswatch/cerulean/variables"; @@ -10,17 +10,12 @@ // import bootstrap. // @import "bootstrap"; -body { padding-top: 60px; } - @import "bootstrap-responsive"; -table.table-hover .btn { - opacity: 0; -} -table.table-hover tr:hover .btn { - opacity: 1; -} -@import "bootstrap-editable"; +// +// LEAP web app specific overrides +// +@import "leap"; // And finally bootswatch style itself @import "bootswatch/cerulean/bootswatch"; diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss new file mode 100644 index 0000000..42638eb --- /dev/null +++ b/app/assets/stylesheets/leap.scss @@ -0,0 +1,65 @@ + +table.table-hover .btn { + opacity: 0; +} +table.table-hover tr:hover .btn { + opacity: 1; +} + +.debug { + outline: 1px solid red; +} + +// +// Icons +// + + +// force a black icon, even if bootstrap thinks differently +.icon-black { + background-image: url(/assets/glyphicons-halflings.png) !important; +} + +// +// Typography +// + +.first { + margin-top: 0; + padding-top: 0; +} + +// +// Boring default masthead +// + +#masthead { + background: #eee; + margin-bottom: 10px; + border-bottom: 1px solid #e6e6e6; + .title { + padding: 20px; + font-size: 1.25em; + } + .sitename { + font-weight: bold; + } +} + +// +// Side Navigation +// + +.sidenav { + @extend .nav-tabs; + @extend .nav-stacked; + box-shadow: 0 2px 4px rgba(0,0,0,.1); + li.active { + a, a:hover { + background-color: $blueDark; + color: $white; + border-color: darken($blueDark, 10%); + cursor: pointer; + } + } +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..db70109 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,19 @@ module ApplicationHelper + + # + # markup for bootstrap icon + # + # http://twitter.github.io/bootstrap/base-css.html#icons + # + def icon(name, color=nil) + if color.nil? + color_class = nil + elsif color == :black + color_class = 'icon-black' + elsif color == :white + color_class = 'icon-white' + end + " ".html_safe + end + end diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb new file mode 100644 index 0000000..19cb934 --- /dev/null +++ b/app/helpers/navigation_helper.rb @@ -0,0 +1,82 @@ +module NavigationHelper + + # + # used to create a side navigation link. + # + # Signature is the same as link_to, except it accepts an :active value in the html_options + # + def link_to_navigation(*args) + if args.last.is_a? Hash + html_options = args.pop.dup + active_class = html_options.delete(:active) ? 'active' : nil + html_options[:class] = [html_options[:class], active_class].join(' ') + args << html_options + else + active_class = nil + end + content_tag :li, :class => active_class do + link_to(*args) + end + end + + # + # returns true if params[:action] matches one of the args. + # + def action?(*actions) + actions.detect do |action| + if action.is_a? String + action == action_string + elsif action.is_a? Symbol + if action == :none + action_string == nil + else + action == action_symbol + end + end + end + end + + # + # returns true if params[:controller] matches one of the args. + # + # for example: + # controller?(:me, :home) + # controller?('groups/') <-- matches any controller in namespace 'groups' + # + def controller?(*controllers) + controllers.each do |cntr| + if cntr.is_a? String + if cntr.ends_with?('/') + return true if controller_string.starts_with?(cntr.chop) + end + return true if cntr == controller_string + elsif cntr.is_a? Symbol + return true if cntr == controller_symbol + end + end + return false + end + + private + + def controller_string + @controller_string ||= params[:controller].to_s.gsub(/^\//, '') + end + + def controller_symbol + @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym + end + + def action_string + params[:action] + end + + def action_symbol + @action_symbol ||= if params[:action].present? + params[:action].to_sym + else + nil + end + end + +end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml new file mode 100644 index 0000000..1055091 --- /dev/null +++ b/app/views/home/_home_text.html.haml @@ -0,0 +1,3 @@ +Welcome to the LEAP web application. + +For more information, visit #{link_to('leap.se', 'https://leap.se')} \ No newline at end of file diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index c02dcad..0b3bbf9 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,11 +1,16 @@ -Try to fetch a -= link_to "cert", cert_path +.row-fluid + .span8 + = render 'home_text' + .span4 + = render '/login_or_signup' -%p -Create a -= link_to "ticket", new_ticket_path +- if Rails.env == 'development' + .row-fluid + %hr + %p + Try to fetch a + = link_to "cert", cert_path -- if logged_in? - %p - See all - = link_to "tickets", tickets_path + %p + Create a + = link_to "ticket", new_ticket_path diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml new file mode 100644 index 0000000..e69de29 diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml new file mode 100644 index 0000000..aa4054b --- /dev/null +++ b/app/views/layouts/_header.html.haml @@ -0,0 +1,3 @@ +- if user + %strong.user_address + = user.email_address diff --git a/app/views/layouts/_masthead.html.haml b/app/views/layouts/_masthead.html.haml new file mode 100644 index 0000000..280f2c2 --- /dev/null +++ b/app/views/layouts/_masthead.html.haml @@ -0,0 +1,4 @@ +.title + %span.sitename + = APP_CONFIG[:domain] + = t(:user_control_panel) \ No newline at end of file diff --git a/app/views/layouts/_masthead_large.html.haml b/app/views/layouts/_masthead_large.html.haml new file mode 100644 index 0000000..6bb1943 --- /dev/null +++ b/app/views/layouts/_masthead_large.html.haml @@ -0,0 +1,3 @@ +.title + %span.sitename + = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index b75eed7..7cd0f38 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,6 +1,13 @@ -= link_to "Leap Web", root_path, :class => 'brand' -%ul.nav - // = render '/tickets/nav' +//= link_to "Leap Web", root_path, :class => 'brand' +//%ul.nav +// // = render '/tickets/nav' +// +//%ul.nav.pull-right +// = render '/sessions/nav' -%ul.nav.pull-right - = render '/sessions/nav' +%ul.nav.sidenav + = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) + = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) + =# link_to_navigation t(:email_settings), edit_email_path(user), :active => controller?(:emails) + = link_to_navigation t(:support_tickets), tickets_path, :active => controller?(:tickets) + = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e6d22f0..719d699 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -9,15 +9,27 @@ = csrf_meta_tags = yield(:head) %body - %header.navbar.navbar-fixed-top - %nav.navbar-inner - .container - = render 'layouts/navigation' - #main{:role => "main"} - .container - .content - .row + #masthead + - if logged_in? + = render 'layouts/masthead' + - else + = render 'layouts/masthead_large' + #main + .container-fluid + - if logged_in? + .row-fluid .span12 + = render 'layouts/header' + .row-fluid + .span2 + = render 'layouts/navigation' + .span10 = render 'layouts/messages' = yield - %footer + - else + .row-fluid + .span12 + = render 'layouts/messages' + = yield + #footer + = render 'layouts/footer' diff --git a/config/defaults.yml b/config/defaults.yml index f3b92c0..25537fe 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -17,7 +17,7 @@ development: <<: *dev_ca <<: *cert_options admins: [admin, admin2] - domain: develop.me + domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' test: @@ -30,4 +30,4 @@ test: production: <<: *cert_options admins: [] - domain: deploy.me + domain: example.net diff --git a/config/locales/en.yml b/config/locales/en.yml index fc61c31..40cdb4a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -4,3 +4,10 @@ en: hello: "Hello world" no_such_thing: "No such %{thing}." + + overview: "Overview" + user_control_panel: "user control panel" + + created: "Created" + updated: "Updated" + -- cgit v1.2.3 From 7d58f640e89a89a4767e59883b864afcd4e9dad4 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:01 -0700 Subject: new ui - ticket navigation --- help/app/helpers/tickets_helper.rb | 20 ++++++++++++++++---- help/app/views/tickets/_order-nav.html.haml | 2 +- help/app/views/tickets/_status-nav.html.haml | 2 ++ help/app/views/tickets/_table-nav.html.haml | 9 ++++----- help/app/views/tickets/index.html.haml | 23 +++++++++-------------- help/app/views/tickets/new.html.haml | 25 ++++++++++++++++--------- help/config/locales/en.yml | 5 +++++ 7 files changed, 53 insertions(+), 33 deletions(-) diff --git a/help/app/helpers/tickets_helper.rb b/help/app/helpers/tickets_helper.rb index bd2c069..8b4ff71 100644 --- a/help/app/helpers/tickets_helper.rb +++ b/help/app/helpers/tickets_helper.rb @@ -1,7 +1,7 @@ module TicketsHelper def status - params[:open_status] || 'open' + params[:open_status] end def admin @@ -14,8 +14,14 @@ module TicketsHelper end def link_to_status(new_status) - label = new_status + ' issues' - link_to label, :open_status => new_status, :admin_status => admin, :sort_order => order + if new_status == "open" + label = t(:open_tickets) + elsif new_status == "closed" + label = t(:closed_tickets) + elsif new_status == "all" + label = t(:all_tickets) + end + link_to label, tickets_path(:open_status => new_status, :admin_status => admin, :sort_order => order) end def link_to_order(order_field) @@ -35,8 +41,14 @@ module TicketsHelper direction = 'desc' end + if order_field == 'updated' + label = t(:updated) + elsif order_field == 'created' + label = t(:created) + end + link_to :sort_order => order_field + '_at_' + direction, :open_status => status, :admin_status => admin do - arrow + order_field + ' at' + arrow + label end end diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml index 9e8bcee..a2ddb72 100644 --- a/help/app/views/tickets/_order-nav.html.haml +++ b/help/app/views/tickets/_order-nav.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-pills.pull-right +%ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} %li{:class=> ("active" if order.start_with? 'created_at' )} = link_to_order('created') %li{:class=> ("active" if order.start_with? 'updated_at' )} diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index 69f4248..e1dca84 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -5,3 +5,5 @@ = link_to_status 'closed' %li{:class => ("active" if status == 'all')} = link_to_status 'all' + %li{:class => ("active" if action?(:new))} + = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index 635b59b..45ebfb2 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,5 +1,4 @@ -.row - .span6 - = render 'tickets/status-nav' - .span4 - = render 'tickets/order-nav' +- unless action?(:new) + = render 'tickets/order-nav' += render 'tickets/status-nav' + diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index 23a503d..a3cbfcf 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,17 +1,12 @@ -%h1 tickets index +- if admin? + = render 'tickets/admin-nav' -Create a -= link_to "new ticket", new_ticket_path += render 'tickets/table-nav' + +%table.table-striped.table-bordered.table-hover + //{:style => "width:100%;"} + %tbody + = render @tickets.all += paginate @tickets -= #%div{"data-pjax-container" => ""} # not sure how to get this working right -.row - .span2 - - if admin? - = render 'tickets/admin-nav' - .span10 - = render 'tickets/table-nav' - %table.table-striped.table-bordered.table-hover{:style => "width:100%;"} - %tbody - = render @tickets.all - = paginate @tickets diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 1aa689b..5442910 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,10 +1,17 @@ -.span12 - %h2=t :new_ticket - = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| - = f.input :title - = f.input :email if !current_user #hmm--might authenticated users want to submit an alternate email? + +//%h2.first= t :new_ticket + += render 'tickets/table-nav' + += simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| + = f.input :title + - if user + = f.input :email, input_html: {value: user.email_address} + = f.input :regarding_user, input_html: {value: user.login} + - else + = f.input :email = f.input :regarding_user - = render :partial => 'new_comment', :locals => {:f => f} - .form-actions - = f.button :submit, :class => 'btn-primary' - = link_to t(:cancel), tickets_path, :class => :btn + = render :partial => 'new_comment', :locals => {:f => f} + .form-actions + = f.button :submit, :class => 'btn-primary' + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 4ea662a..2835e4e 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -1,2 +1,7 @@ en: access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" + support_tickets: "Support Tickets" + all_tickets: "All Tickets" + open_tickets: "Open Tickets" + closed_tickets: "Closed Tickets" + new_ticket: "New Ticket" \ No newline at end of file -- cgit v1.2.3 From d00fe5bded29ad816bb70caa31414f86c69aaa53 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:30 -0700 Subject: add link to simple_form to the docs --- DEVELOP.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/DEVELOP.md b/DEVELOP.md index 9548774..e19b827 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -1,5 +1,11 @@ # Development # +## Hacking ## + +Some tips on modifying the views: + +* Many of the forms use [simple_form gem](https://github.com/plataformatec/simple_form) + ## Engines ## Leap Web consists of different Engines. They live in their own subdirectory and are included through bundler via their path. This way changes to the engines immediately affect the server as if they were in the main `app` directory. @@ -37,7 +43,7 @@ require File.expand_path('../../lib/leap_web/version.rb', __FILE__) # ... Gem::Specification.new do |s| # ... - s.add_dependency "rails" + s.add_dependency "rails" s.add_dependency "leap_web_core", LeapWeb::Version end ``` -- cgit v1.2.3 From e58fd0550b4a29fac9d52dc8a78d04333ccc8c06 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:55 -0700 Subject: new ui - initial user changes --- .../app/controllers/account_settings_controller.rb | 0 users/app/controllers/email_settings_controller.rb | 0 users/app/controllers/overviews_controller.rb | 9 ++++++++ users/app/controllers/users_base_controller.rb | 18 ++++++++++++++++ users/app/helpers/users_helper.rb | 2 +- users/app/views/_login_or_signup.html.haml | 25 ++++++++++++++++++++++ users/app/views/emails/edit.html.haml | 5 +++++ users/app/views/overviews/show.html.haml | 15 +++++++++++++ users/app/views/sessions/_new.html.haml | 7 ++++++ users/app/views/sessions/new.html.haml | 2 +- users/app/views/users/_login_field.html.haml | 2 +- users/app/views/users/_new.html.haml | 7 ++++++ users/app/views/users/_password_fields.html.haml | 4 ++-- users/app/views/users/edit.html.haml | 20 +++-------------- users/app/views/users/new.html.haml | 5 ++--- users/config/locales/en.yml | 17 +++++++++------ users/config/routes.rb | 3 +++ 17 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 users/app/controllers/account_settings_controller.rb create mode 100644 users/app/controllers/email_settings_controller.rb create mode 100644 users/app/controllers/overviews_controller.rb create mode 100644 users/app/controllers/users_base_controller.rb create mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/emails/edit.html.haml create mode 100644 users/app/views/overviews/show.html.haml create mode 100644 users/app/views/sessions/_new.html.haml create mode 100644 users/app/views/users/_new.html.haml diff --git a/users/app/controllers/account_settings_controller.rb b/users/app/controllers/account_settings_controller.rb new file mode 100644 index 0000000..e69de29 diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb new file mode 100644 index 0000000..e69de29 diff --git a/users/app/controllers/overviews_controller.rb b/users/app/controllers/overviews_controller.rb new file mode 100644 index 0000000..52ce267 --- /dev/null +++ b/users/app/controllers/overviews_controller.rb @@ -0,0 +1,9 @@ +class OverviewsController < UsersBaseController + + before_filter :authorize + before_filter :fetch_user + + def show + end + +end diff --git a/users/app/controllers/users_base_controller.rb b/users/app/controllers/users_base_controller.rb new file mode 100644 index 0000000..dc2fa16 --- /dev/null +++ b/users/app/controllers/users_base_controller.rb @@ -0,0 +1,18 @@ +# +# common base class for all user related controllers +# + +class UsersBaseController < ApplicationController + + protected + + def fetch_user + @user = User.find_by_param(params[:user_id] || params[:id]) + if !@user && admin? + redirect_to users_url, :alert => t(:no_such_thing, :thing => 'user') + elsif !admin? && @user != current_user + access_denied + end + end + +end diff --git a/users/app/helpers/users_helper.rb b/users/app/helpers/users_helper.rb index 9feae62..559b3f7 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -24,7 +24,7 @@ module UsersHelper end def user_form_html_classes(options) - classes = %W/form-horizontal user form/ + classes = %W/user form/ classes << options[:legend] classes << (@user.new_record? ? 'new' : 'edit') classes.compact diff --git a/users/app/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml new file mode 100644 index 0000000..b353526 --- /dev/null +++ b/users/app/views/_login_or_signup.html.haml @@ -0,0 +1,25 @@ +// +// displays a little widget to login or sign up +// + +%ul.nav.nav-tabs + %li.active + %a{:href => ''}= t(:login) + %li + = link_to t(:signup), new_user_path + += render 'sessions/new' + +// +// this is nice, but it doesn't work because both forms have the same names for fields. +// +// %ul.nav.nav-tabs +// %li.active +// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) +// %li +// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) +// .tab-content +// #login.tab-pane.active +// = render 'sessions/new' +// #signup.tab-pane +// = render 'users/new' diff --git a/users/app/views/emails/edit.html.haml b/users/app/views/emails/edit.html.haml new file mode 100644 index 0000000..b44b569 --- /dev/null +++ b/users/app/views/emails/edit.html.haml @@ -0,0 +1,5 @@ + + += user_form_with 'public_key_field', :legend => :public_key += user_form_with 'email_forward_field', :legend => :forward_email += user_form_with 'email_aliases', :legend => :add_email_alias diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml new file mode 100644 index 0000000..eda9899 --- /dev/null +++ b/users/app/views/overviews/show.html.haml @@ -0,0 +1,15 @@ +%p + Username: + = @user.login + +%p + User since: + = @user.created_at + +%p + Last update: + = @user.updated_at + +%p + Quota: + N/A \ No newline at end of file diff --git a/users/app/views/sessions/_new.html.haml b/users/app/views/sessions/_new.html.haml new file mode 100644 index 0000000..640fec5 --- /dev/null +++ b/users/app/views/sessions/_new.html.haml @@ -0,0 +1,7 @@ +- @session ||= Session.new += simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| + = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } + = f.input :password, :required => false, :input_html => { :id => :srp_password } + .form-actions + = f.button :submit, :value => t(:login), :class => 'btn-primary' + // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 6743407..960919a 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -6,4 +6,4 @@ = f.input :login, :input_html => { :id => :srp_username } = f.input :password, :required => true, :input_html => { :id => :srp_password } = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn \ No newline at end of file + = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml index 8ab36c3..e58c36f 100644 --- a/users/app/views/users/_login_field.html.haml +++ b/users/app/views/users/_login_field.html.haml @@ -1 +1 @@ -= f.input :login, :input_html => { :id => :srp_username } += f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } diff --git a/users/app/views/users/_new.html.haml b/users/app/views/users/_new.html.haml new file mode 100644 index 0000000..3d0f2ac --- /dev/null +++ b/users/app/views/users/_new.html.haml @@ -0,0 +1,7 @@ +- @user ||= User.new += user_form do |f| + = render :partial => 'users/login_field', :locals => {:f => f} + = render :partial => 'users/password_fields', :locals => {:f => f} + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' + = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml index 47b7b07..7b3358d 100644 --- a/users/app/views/users/_password_fields.html.haml +++ b/users/app/views/users/_password_fields.html.haml @@ -1,2 +1,2 @@ -= f.input :password, :required => true, :validate => true, :input_html => { :id => :srp_password } -= f.input :password_confirmation, :required => true, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } += f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } += f.input :password_confirmation, :required => false, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index 97bd48d..4e70d69 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,17 +1,3 @@ -.span8.offset2 - %h2=t :settings - - tabs = [] - - content_for :account do - = user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user - = render 'cancel_account' - - tabs << :account - - if @user == current_user - - content_for :email do - %legend=t :email_address - =t :associated_email - = render @user.email_address, :as => :span - = user_form_with 'public_key_field', :legend => :public_key - = user_form_with 'email_forward_field', :legend => :forward_email - = user_form_with 'email_aliases', :legend => :add_email_alias - - tabs << :email - = render 'tabs/tabs', :tabs => tabs += user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user += render 'cancel_account' + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index 80482b2..7d29de2 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -5,8 +5,7 @@ %legend= t(:signup_message) = render :partial => 'login_field', :locals => {:f => f} = render :partial => 'password_fields', :locals => {:f => f} - .pull-right - = f.button :submit, :class => 'btn-primary' + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' = link_to t(:cancel), root_url, :class => :btn - .clearfix diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 32d183b..3c42b55 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -1,9 +1,14 @@ en: - none: "None." - signup: "Sign up" + email_settings: "Email Settings" + account_settings: "Account Settings" + logout: "Logout" + none: "None" + signup: "Sign Up" signup_message: "Please create an account." cancel: "Cancel" - login: "Login" + login: "Log In" + username: "Username" + password: "Password" login_message: "Please login with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." @@ -20,7 +25,7 @@ en: user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored PGP key" + use_ascii_key: "Use ASCII-armored OpenPGP key" can_retype_old_password: "Retype your old password if you would like to keep that" associated_email: "The associated email address is" cookie_disabled_warning: "You have cookies disabled. You will not be able to login until you enable cookies." @@ -28,7 +33,7 @@ en: activemodel: models: - user: + user: one: User other: "%{count} Users" simple_form: @@ -42,4 +47,4 @@ en: placeholders: user: email_forward: "my_other_email@domain.net" - + diff --git a/users/config/routes.rb b/users/config/routes.rb index 9a9a40e..d07cda9 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -14,6 +14,9 @@ Rails.application.routes.draw do get "signup" => "users#new", :as => "signup" resources :users do + resource :overview, :only => [:show] + resource :email_settings, :only => [:edit, :update] + resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From 8393058ac15d72be702a6de481d6129aed4bbef3 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:33:19 -0700 Subject: new ui for tickets --- app/assets/stylesheets/leap.scss | 73 ++++++++++++-- core/config/initializers/simple_form_bootstrap.rb | 12 +++ help/README.md | 1 + help/Readme.md | 0 help/app/controllers/tickets_controller.rb | 109 +++++++++++---------- help/app/views/tickets/_admin-nav.html.haml | 10 +- help/app/views/tickets/_comment.html.haml | 34 +++---- help/app/views/tickets/_edit_form.html.haml | 46 +++++++++ help/app/views/tickets/_new_comment.html.haml | 4 - help/app/views/tickets/_new_comment_form.html.haml | 13 +++ help/app/views/tickets/_table-nav.html.haml | 3 + help/app/views/tickets/_ticket.html.haml | 20 +--- help/app/views/tickets/_ticket_data.html.haml | 35 ------- help/app/views/tickets/index.html.haml | 21 ++-- help/app/views/tickets/new.html.haml | 10 +- help/app/views/tickets/show.html.haml | 26 ++--- help/config/locales/en.yml | 12 ++- 17 files changed, 261 insertions(+), 168 deletions(-) create mode 100644 help/README.md delete mode 100644 help/Readme.md create mode 100644 help/app/views/tickets/_edit_form.html.haml delete mode 100644 help/app/views/tickets/_new_comment.html.haml create mode 100644 help/app/views/tickets/_new_comment_form.html.haml delete mode 100644 help/app/views/tickets/_ticket_data.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 42638eb..6b44986 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -6,27 +6,80 @@ table.table-hover tr:hover .btn { opacity: 1; } +.ticket { + td.user { + white-space: nowrap; + } + td.comment { + width: 100%; + } +} + +// +// UTILITY +// + .debug { outline: 1px solid red; } +.full-width { + width: 100%; +} + +.slim { + margin: 0; +} + +.first { + margin-top: 0; + padding-top: 0; +} + // -// Icons +// Typography // +input.large { + font-size: $baseFontSize * 1.25; + line-height: $baseLineHeight * 1.5; +} -// force a black icon, even if bootstrap thinks differently -.icon-black { - background-image: url(/assets/glyphicons-halflings.png) !important; +// +// FORMS +// + +// +// Sometimes we really want full width controls, but this flies in the face of +// what bootstrap does for control sizes, so we have to step on bootstrap's +// toes a bit to make this work. +// +input, textarea { + &.full-width { + height: inherit; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + } } // -// Typography +// Labels // -.first { - margin-top: 0; - padding-top: 0; +.label-clear { + background-color: $white; + text-shadow: none; + color: $black; +} + +// +// Icons +// + +// force a black icon, even if bootstrap thinks differently +.icon-black { + background-image: url(/assets/glyphicons-halflings.png) !important; } // @@ -56,9 +109,9 @@ table.table-hover tr:hover .btn { box-shadow: 0 2px 4px rgba(0,0,0,.1); li.active { a, a:hover { - background-color: $blueDark; + background-color: $linkColor; color: $white; - border-color: darken($blueDark, 10%); + border-color: darken($linkColor, 0%); cursor: pointer; } } diff --git a/core/config/initializers/simple_form_bootstrap.rb b/core/config/initializers/simple_form_bootstrap.rb index 1a22967..c949f5e 100644 --- a/core/config/initializers/simple_form_bootstrap.rb +++ b/core/config/initializers/simple_form_bootstrap.rb @@ -37,6 +37,18 @@ SimpleForm.setup do |config| end end + # + # when you don't want any bootstrap "control-group" or "controls" wrappers. + # + config.wrappers :none, :tag => 'div', :error_class => 'error' do |b| + b.use :html5 + b.use :placeholder + b.use :label + b.use :input + b.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + b.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } + end + # Wrappers for forms and inputs using the Twitter Bootstrap toolkit. # Check the Bootstrap docs (http://twitter.github.com/bootstrap) # to learn about the different styles for forms and inputs, diff --git a/help/README.md b/help/README.md new file mode 100644 index 0000000..c9573e6 --- /dev/null +++ b/help/README.md @@ -0,0 +1 @@ +Implements a simple, clean, and easy to use help ticketing system. \ No newline at end of file diff --git a/help/Readme.md b/help/Readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index 6562048..d478da9 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -3,10 +3,9 @@ class TicketsController < ApplicationController respond_to :html, :json #has_scope :open, :type => boolean - before_filter :set_strings - before_filter :authorize, :only => [:index] before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method + before_filter :set_title def new @ticket = Ticket.new @@ -20,61 +19,68 @@ class TicketsController < ApplicationController @ticket.created_by = current_user.id if logged_in? @ticket.email = current_user.email_address if logged_in? and current_user.email_address - flash[:notice] = 'Ticket was successfully created.' if @ticket.save + if @ticket.save + flash[:notice] = t(:thing_was_successfully_created, :thing => t(:ticket)) + end # cannot set this until ticket has been saved, as @ticket.id will not be set - flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) if !logged_in? and flash[:notice] + if !logged_in? and flash[:notice] + flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) + end respond_with(@ticket) - - end - -=begin - def edit - @ticket.comments.build - # build ticket comments? end -=end def show @comment = TicketComment.new if !@ticket - redirect_to tickets_path, :alert => "No such ticket" + redirect_to tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) return end end def update + if params[:commit] == t(:close) + @ticket.is_open = false + @ticket.save + redirect_to tickets_path + elsif params[:commit] == t(:open) + @ticket.is_open = true + @ticket.save + redirect_to @ticket + else + @ticket.attributes = cleanup_ticket_params(params[:ticket]) - if params[:post] #currently changes to title or is_open status - @ticket.attributes = params[:post] - # TODO: do we want to keep the history of title changes? one possibility was adding a comment that said something like 'user changed the title from a to b' + if params[:commit] == t(:reply_and_close) + @ticket.close + should_redirect = true + else + should_redirect = !logged_in? + end - else - params[:ticket][:comments_attributes] = nil if params[:ticket][:comments_attributes].values.first[:body].blank? #unset comments hash if no new comment was typed - @ticket.attributes = params[:ticket] #this will call comments_attributes= - @ticket.close if params[:commit] == @reply_close_str #this overrides is_open selection - # what if there is an update and no new comment? Confirm that there is a new comment to update posted_by: - @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) if @ticket.comments_changed? #protecting posted_by isn't working, so this should protect it. - end - if @ticket.changed? and @ticket.save - flash[:notice] = 'Ticket was successfully updated.' - if @ticket.is_open || !logged_in? - respond_with @ticket - else #for closed tickets with authenticated users, redirect to index. - redirect_to tickets_path + if @ticket.comments_changed? + @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) end - else - #redirect_to [:show, @ticket] # - flash[:alert] = 'Ticket has not been changed' - redirect_to @ticket - #respond_with(@ticket) # why does this go to edit?? redirect??? - end + if @ticket.changed? + if @ticket.save + flash[:notice] = t(:changes_saved) + if should_redirect + redirect_to tickets_path + else + redirect_to @ticket + end + else + respond_with @ticket + end + else + redirect_to @ticket + end + end end def index @all_tickets = Ticket.for_user(current_user, params, admin?) #for tests, useful to have as separate variable - @tickets = @all_tickets.page(params[:page]).per(10) + @tickets = @all_tickets.page(params[:page]).per(APP_CONFIG[:pagination_size]) end def destroy @@ -83,15 +89,26 @@ class TicketsController < ApplicationController redirect_to tickets_path end + protected + + def set_title + @title = t(:tickets) + end + private - def ticket_access? - @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by)) + # unset comments hash if no new comment was typed + def cleanup_ticket_params(ticket) + if ticket && ticket[:comments_attributes] + if ticket[:comments_attributes].values.first[:body].blank? + ticket[:comments_attributes] = nil + end + end + return ticket end - def set_strings - @post_reply_str = 'Post reply' #t :post_reply - @reply_close_str = 'Reply and close' #t :reply_and_close + def ticket_access? + @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by)) end def fetch_ticket @@ -102,13 +119,5 @@ class TicketsController < ApplicationController end access_denied unless ticket_access? end - # not using now, as we are using comment_attributes= from the Ticket model -=begin - def add_comment - comment = TicketComment.new(params[:comment]) - comment.posted_by = User.current.id if User.current #could be nil - comment.posted_at = Time.now # TODO: it seems strange to have this here, and not in model - @ticket.comments << comment - end -=end + end diff --git a/help/app/views/tickets/_admin-nav.html.haml b/help/app/views/tickets/_admin-nav.html.haml index 0e45c40..3e65e44 100644 --- a/help/app/views/tickets/_admin-nav.html.haml +++ b/help/app/views/tickets/_admin-nav.html.haml @@ -1,5 +1,5 @@ -%ul.nav.nav-pills.nav-stacked - %li{:class => ("active" if admin == 'mine')} - = link_to 'tickets i admin', {:admin_status => 'mine', :open_status => status, :sort_order => order} - %li{:class => ("active" if admin == 'all')} - = link_to 'all tickets', {:admin_status => 'all', :open_status => status, :sort_order => order} +.btn-group + %span.btn.disabled= t(:admin) + ':' + = link_to t(:my_tickets), {:admin_status => 'mine', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'mine')].join(' ') + = link_to t(:all_tickets), {:admin_status => 'all', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'all')].join(' ') +%br \ No newline at end of file diff --git a/help/app/views/tickets/_comment.html.haml b/help/app/views/tickets/_comment.html.haml index 501ceec..c02246c 100644 --- a/help/app/views/tickets/_comment.html.haml +++ b/help/app/views/tickets/_comment.html.haml @@ -1,20 +1,20 @@ -- # style is super ugly but just for now - if admin? or !comment.private # only show comment if user is admin or comment is not private %tr - %td - - if comment.posted_by_user - %b - = 'Posted by' + (comment.posted_by_user.is_admin? ? ' admin' : '') + ':' - = comment.posted_by_user.login - - else - %b - Unauthenticated post + %td.user + %div + %strong + - if comment.posted_by_user + = comment.posted_by_user.login + - else + = t(:unknown) + %div= comment.posted_at.to_s(:short) + - if comment.posted_by_user.is_admin? + %div + %span.label.label-inverse + = t(:admin) - if comment.private - (Private comment) - .pull-right - %b - Posted at: - = comment.posted_at.to_s(:short) - %br - = comment.body - + %div + %span.label.label-important + = t(:private) + %td.comment + = comment.body \ No newline at end of file diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml new file mode 100644 index 0000000..3d1d879 --- /dev/null +++ b/help/app/views/tickets/_edit_form.html.haml @@ -0,0 +1,46 @@ +- # created by user link +- if @ticket.created_by_user + - created_by = link_to(@ticket.created_by_user.login, user_overview_path(@ticket.created_by_user)) +- else + - created_by = t(:anonymous) + +- # regarding user link +- if admin? + - if @ticket.regarding_user_actual_user + - regarding_user_link = link_to @ticket.regarding_user_actual_user.login, user_overview_path(@ticket.regarding_user_actual_user) + - else + - regarding_user_link = "(#{t(:unknown)})" +- else + - regarding_user_link = '' + += form_for @ticket do |f| + %p.first + - if @ticket.is_open? + %span.label.label-info= t(:open) + - else + %span.label.label-success= t(:closed) + %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe + = t(:subject) + %br + = f.text_field :title, :class => 'large full-width' + .row-fluid + .span4 + %div= t(:status) + = f.select :is_open, [[t(:open), "true"], [t(:closed), "false"]] + .span4 + %div= t(:email) + = f.text_field :email + .span4 + %div + = t(:regarding) + = regarding_user_link + = f.text_field :regarding_user + = f.submit t(:save), :class => 'btn' + - if @ticket.is_open? + = f.submit t(:close), :class => 'btn' + =# button_to t(:close), {:post => {:is_open => false}}, :method => :put, :class => 'btn' + - else + = f.submit t(:open), :class => 'btn' + =# button_to t(:open), {:post => {:is_open => true}}, :method => :put, :class => 'btn' + + diff --git a/help/app/views/tickets/_new_comment.html.haml b/help/app/views/tickets/_new_comment.html.haml deleted file mode 100644 index 96388ea..0000000 --- a/help/app/views/tickets/_new_comment.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -= f.simple_fields_for :comments, @comment do |c| - = c.input :body, :label => 'Comment', :as => :text, :input_html => {:class => "span9", :rows=>4} - - if admin? - = c.input :private, :as => :boolean, :label => false, :inline_label => true diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml new file mode 100644 index 0000000..b273503 --- /dev/null +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -0,0 +1,13 @@ +-# +-# for posting a new comment to an existing ticket. +-# += simple_form_for @ticket, :html => {:class => 'slim'} do |f| + = f.simple_fields_for :comments, @comment, :wrapper => :none, :html => {:class => 'slim'} do |c| + = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} + - if admin? + = c.input :private, :as => :boolean, :label => false, :inline_label => true + = f.button :submit, t(:post_reply), :class => 'btn-primary' + - if @ticket.is_open + = f.button :submit, t(:reply_and_close) + = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index 45ebfb2..a5cf8be 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,3 +1,6 @@ +- if admin? + = render 'tickets/admin-nav' + - unless action?(:new) = render 'tickets/order-nav' = render 'tickets/status-nav' diff --git a/help/app/views/tickets/_ticket.html.haml b/help/app/views/tickets/_ticket.html.haml index 7b37652..9a1e899 100644 --- a/help/app/views/tickets/_ticket.html.haml +++ b/help/app/views/tickets/_ticket.html.haml @@ -1,17 +1,5 @@ -- updated_at_text = 'updated: ' + ticket.updated_at.to_s(:long) %tr - %td - %b - = link_to ticket.title, ticket - - if params[:controller] == 'tickets' - %br - %small - created: - = ticket.created_at.to_s(:long) - = updated_at_text - %small.pull-right - comments by: - = ticket.commenters - - else - %small - = updated_at_text \ No newline at end of file + %td= link_to ticket.title, ticket + %td= link_to ticket.created_at.to_s(:short), ticket + %td= link_to ticket.updated_at.to_s(:short), ticket + %td= ticket.commenters diff --git a/help/app/views/tickets/_ticket_data.html.haml b/help/app/views/tickets/_ticket_data.html.haml deleted file mode 100644 index 6a1a896..0000000 --- a/help/app/views/tickets/_ticket_data.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -.spam12 - %b - Created by: - - if @ticket.created_by_user - = link_to @ticket.created_by_user.login, user_path(@ticket.created_by_user) - - else - Unauthenticated ticket creator - - if @ticket.regarding_user - %b - Regarding user: - - if admin? - - if @ticket.regarding_user_actual_user - = link_to @ticket.regarding_user_actual_user.login, user_path(@ticket.regarding_user_actual_user) - - else - = @ticket.regarding_user + ' (no such user)' - - else # a non-admin is viewing the ticket, so they shouldn't see confirmation of whether the regarding_user exists or not. - = @ticket.regarding_user - - if @ticket.email - %b - email: - = @ticket.email - %b - Created at: - = @ticket.created_at.to_s(:short) - %b - Updated at: - = @ticket.updated_at.to_s(:short) - %b - = "Status:" - - if @ticket.is_open - = 'open' - = button_to 'Close', {:post => {:is_open => false}}, :method => :put, :class => 'btn btn-small' - - else - = 'closed' - = button_to 'Open', {:post => {:is_open => true}}, :method => :put, :class => 'btn btn-small' diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index a3cbfcf..f4597a7 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,12 +1,17 @@ -- if admin? - = render 'tickets/admin-nav' - = render 'tickets/table-nav' -%table.table-striped.table-bordered.table-hover - //{:style => "width:100%;"} +%table.table.table-striped.table-bordered + %thead + %tr + %th= t(:subject) + %th= t(:created) + %th= t(:updated) + %th= t(:voices) %tbody - = render @tickets.all -= paginate @tickets - + - if @tickets.any? + = render @tickets.all + - else + %tr + %td{:colspan=>4}= t(:none) += paginate @tickets diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 5442910..acb9537 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,17 +1,17 @@ - -//%h2.first= t :new_ticket - = render 'tickets/table-nav' = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| - = f.input :title + = f.input :title, :label => t(:subject) - if user = f.input :email, input_html: {value: user.email_address} = f.input :regarding_user, input_html: {value: user.login} - else = f.input :email = f.input :regarding_user - = render :partial => 'new_comment', :locals => {:f => f} + = f.simple_fields_for :comments, @comment do |c| + = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5} + - if admin? + = c.input :private, :as => :boolean, :label => false, :inline_label => true .form-actions = f.button :submit, :class => 'btn-primary' = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/show.html.haml b/help/app/views/tickets/show.html.haml index a69048b..ddd4e9f 100644 --- a/help/app/views/tickets/show.html.haml +++ b/help/app/views/tickets/show.html.haml @@ -1,18 +1,10 @@ -.spam12 - %h2 - %a#title.editable.editable-click{"data-name" => "title", "data-resource" => "post", "data-type" => "text", "data-url" => ticket_path(@ticket.id), "data-pk" => @ticket.id, :href => "#"} - = @ticket.title - = render 'tickets/ticket_data' - %table.table-striped.table-bordered.table-hover{:style => "width:100%;"} +.ticket + = render 'tickets/edit_form' + %table.table.table-striped.table-bordered %tbody - = render(:partial => "comment", :collection => @ticket.comments) - = #render @ticket.comments should work if view is in /app/views/comments/_comment - - = simple_form_for @ticket, :html => {:class => 'form-horizontal'} do |f| # don't need validations so long as this is so simple - = render :partial => 'new_comment', :locals => {:f => f} - .span10.offset3 - = f.button :submit, @post_reply_str, :class => 'btn-primary' - - if @ticket.is_open - = f.button :submit, @reply_close_str - = link_to t(:Destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? - = link_to t(:cancel), tickets_path, :class => :btn + = render :partial => 'tickets/comment', :collection => @ticket.comments + %tr + %td.user + = logged_in? ? current_user.login : t(:anonymous) + %td.comment + = render 'tickets/new_comment_form' \ No newline at end of file diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 2835e4e..901cd76 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -2,6 +2,16 @@ en: access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" support_tickets: "Support Tickets" all_tickets: "All Tickets" + my_tickets: "My Tickets" open_tickets: "Open Tickets" closed_tickets: "Closed Tickets" - new_ticket: "New Ticket" \ No newline at end of file + new_ticket: "New Ticket" + tickets: "Tickets" + subject: "Subject" + destroy: "Destroy" + open: "Open" + closed: "Closed" + close: "Close" + post_reply: "Post Reply" + reply_and_close: "Reply and Close" + description: "Description" \ No newline at end of file -- cgit v1.2.3 From 1157caf42ebd9ccfd25c455115abfa79bcf90e03 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:34:11 -0700 Subject: remove gem bootstrap-editable --- app/assets/javascripts/application.js | 4 ++-- ui_dependencies.rb | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 049a392..ad4dbbf 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,8 +14,8 @@ //= require jquery_ujs //= require srp //= require bootstrap -//= require bootstrap-editable -//= require bootstrap-editable-rails +//# require bootstrap-editable +//# require bootstrap-editable-rails //= require rails.validations //= require rails.validations.simple_form diff --git a/ui_dependencies.rb b/ui_dependencies.rb index b24eef1..2cfd851 100644 --- a/ui_dependencies.rb +++ b/ui_dependencies.rb @@ -4,10 +4,16 @@ gem "jquery-rails" gem "simple_form" gem 'client_side_validations' gem 'client_side_validations-simple_form' -gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be issues with 0.14.0 when using couchrest -gem 'bootstrap-editable-rails', "~>0.0.4" gem "bootswatch-rails", "~> 0.5.0" +gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be + # issues with 0.14.0 when using couchrest + +gem 'rails-i18n' # locale files for built-in validation messages and times + # https://github.com/svenfuchs/rails-i18n + # for a list of keys: + # https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml + group :assets do gem "haml-rails", "~> 0.3.4" gem "sass-rails", "~> 3.2.5" -- cgit v1.2.3 From 93d55912c5965b2214c337b95c2480db16793e12 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:34:27 -0700 Subject: set pagination size via config file --- config/defaults.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/defaults.yml b/config/defaults.yml index 25537fe..6317082 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -19,6 +19,7 @@ development: admins: [admin, admin2] domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' + pagination_size: 30 test: <<: *dev_ca @@ -26,8 +27,10 @@ test: admins: [admin, admin2] domain: test.me secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' + pagination_size: 30 production: <<: *cert_options admins: [] domain: example.net + pagination_size: 30 \ No newline at end of file -- cgit v1.2.3 From e37d1b1d621530dbec7b5b3b7ed17c24a48a727b Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:35:22 -0700 Subject: i18n - added a few strongs to app, fixed language at english for now. --- config/initializers/i18n.rb | 2 ++ config/locales/en.yml | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 config/initializers/i18n.rb diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb new file mode 100644 index 0000000..574d169 --- /dev/null +++ b/config/initializers/i18n.rb @@ -0,0 +1,2 @@ + +I18n.available_locales = ['en'] diff --git a/config/locales/en.yml b/config/locales/en.yml index 40cdb4a..f4e35f2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -9,5 +9,14 @@ en: user_control_panel: "user control panel" created: "Created" + created_by_on: "Created by %{user} on %{time}" updated: "Updated" + none: "None" + unknown: "Unknown" + admin: "Admin" + anonymous: "Anonymous" + save: "Save" + + changes_saved: "Changes saved successfully." + thing_was_successfully_created: "%{thing} was successfully created." \ No newline at end of file -- cgit v1.2.3 From 1dcec6ed912b075f5bdaa069bb5725b0ff06fe41 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:02 -0700 Subject: added html_title helper - use @title to set page title. --- app/helpers/application_helper.rb | 13 +++++++++++++ app/views/layouts/application.html.haml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index db70109..a236a0a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,5 +1,18 @@ module ApplicationHelper + # + # determine title for the page + # + def html_title + if content_for?(:title) + yield(:title) + elsif @title + [@title, ' - ', APP_CONFIG[:domain]].join + else + APP_CONFIG[:domain] + end + end + # # markup for bootstrap icon # diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 719d699..71364fc 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -2,7 +2,7 @@ %html %head %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"} - %title= content_for?(:title) ? yield(:title) : "Leap Web" + %title= html_title %meta{:content => content_for?(:description) ? yield(:description) : "Leap Web", :name => "description"} = stylesheet_link_tag "application", :media => "all" = javascript_include_tag "application" -- cgit v1.2.3 From 93999b107fff7275970012c3f12c6877d2b16d6e Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:16 -0700 Subject: redirect to overview if authenticated --- app/controllers/home_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 4e1983a..120541e 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,6 +1,9 @@ class HomeController < ApplicationController def index + if logged_in? + redirect_to user_overview_url(current_user) + end debugger if params[:debug] end end -- cgit v1.2.3 From 27073d1fb5fd2e42abe3adf46e958be2e618ab41 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:36:32 -0700 Subject: style kaminari pagination to work with bootstrap --- core/app/views/kaminari/_first_page.html.haml | 9 +++++++++ core/app/views/kaminari/_gap.html.haml | 8 ++++++++ core/app/views/kaminari/_last_page.html.haml | 9 +++++++++ core/app/views/kaminari/_next_page.html.haml | 12 ++++++++++++ core/app/views/kaminari/_page.html.haml | 14 ++++++++++++++ core/app/views/kaminari/_paginator.html.haml | 19 +++++++++++++++++++ core/app/views/kaminari/_prev_page.html.haml | 12 ++++++++++++ 7 files changed, 83 insertions(+) create mode 100644 core/app/views/kaminari/_first_page.html.haml create mode 100644 core/app/views/kaminari/_gap.html.haml create mode 100644 core/app/views/kaminari/_last_page.html.haml create mode 100644 core/app/views/kaminari/_next_page.html.haml create mode 100644 core/app/views/kaminari/_page.html.haml create mode 100644 core/app/views/kaminari/_paginator.html.haml create mode 100644 core/app/views/kaminari/_prev_page.html.haml diff --git a/core/app/views/kaminari/_first_page.html.haml b/core/app/views/kaminari/_first_page.html.haml new file mode 100644 index 0000000..34436e3 --- /dev/null +++ b/core/app/views/kaminari/_first_page.html.haml @@ -0,0 +1,9 @@ +-# Link to the "First" page +-# available local variables +-# url: url to the first page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li + = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote diff --git a/core/app/views/kaminari/_gap.html.haml b/core/app/views/kaminari/_gap.html.haml new file mode 100644 index 0000000..51de678 --- /dev/null +++ b/core/app/views/kaminari/_gap.html.haml @@ -0,0 +1,8 @@ +-# Non-link tag that stands for skipped pages... +-# available local variables +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li.disabled + = raw(t 'views.pagination.truncate') diff --git a/core/app/views/kaminari/_last_page.html.haml b/core/app/views/kaminari/_last_page.html.haml new file mode 100644 index 0000000..c90433c --- /dev/null +++ b/core/app/views/kaminari/_last_page.html.haml @@ -0,0 +1,9 @@ +-# Link to the "Last" page +-# available local variables +-# url: url to the last page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +%li + = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote} diff --git a/core/app/views/kaminari/_next_page.html.haml b/core/app/views/kaminari/_next_page.html.haml new file mode 100644 index 0000000..ea6cab2 --- /dev/null +++ b/core/app/views/kaminari/_next_page.html.haml @@ -0,0 +1,12 @@ +-# Link to the "Next" page +-# available local variables +-# url: url to the next page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +- if current_page.last? + %li.disabled + %span= raw(t 'views.pagination.next') +- else + %li= link_to(raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote) diff --git a/core/app/views/kaminari/_page.html.haml b/core/app/views/kaminari/_page.html.haml new file mode 100644 index 0000000..2f2f142 --- /dev/null +++ b/core/app/views/kaminari/_page.html.haml @@ -0,0 +1,14 @@ +-# Link showing page number +-# available local variables +-# page: a page object for "this" page +-# url: url to this page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote + +- if page.current? + %li.active + %span= page +- else + %li= link_to(page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil}) diff --git a/core/app/views/kaminari/_paginator.html.haml b/core/app/views/kaminari/_paginator.html.haml new file mode 100644 index 0000000..79c5b92 --- /dev/null +++ b/core/app/views/kaminari/_paginator.html.haml @@ -0,0 +1,19 @@ +-# The container tag +-# available local variables +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +-# paginator: the paginator that renders the pagination tags inside += paginator.render do + .pagination + %ul + -#= first_page_tag unless current_page.first? + = prev_page_tag #unless current_page.first? + - each_page do |page| + - if page.left_outer? || page.right_outer? || page.inside_window? + = page_tag page + - elsif !page.was_truncated? + = gap_tag + = next_page_tag #unless current_page.last? + -#= last_page_tag unless current_page.last? diff --git a/core/app/views/kaminari/_prev_page.html.haml b/core/app/views/kaminari/_prev_page.html.haml new file mode 100644 index 0000000..d274bf4 --- /dev/null +++ b/core/app/views/kaminari/_prev_page.html.haml @@ -0,0 +1,12 @@ +-# Link to the "Previous" page +-# available local variables +-# url: url to the previous page +-# current_page: a page object for the currently displayed page +-# num_pages: total number of pages +-# per_page: number of items to fetch per page +-# remote: data-remote +- if current_page.first? + %li.disabled + %span= raw(t 'views.pagination.previous') +- else + %li= link_to(raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote) -- cgit v1.2.3 From 2e4ebdb84a464cf2ee902eb6e9bc955d77bafa73 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:37:04 -0700 Subject: add commented out code of how redirect should work with Warden, although I can't get it working. --- users/app/controllers/sessions_controller.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/users/app/controllers/sessions_controller.rb b/users/app/controllers/sessions_controller.rb index 01ecff6..d6c455b 100644 --- a/users/app/controllers/sessions_controller.rb +++ b/users/app/controllers/sessions_controller.rb @@ -22,4 +22,15 @@ class SessionsController < ApplicationController logout redirect_to root_path end + + # + # this is a bad hack, but user_overview_url(user) is not available + # also, this doesn't work because the redirect happens as a PUT. no idea why. + # + #Warden::Manager.after_authentication do |user, auth, opts| + # response = Rack::Response.new + # response.redirect "/users/#{user.id}/overview" + # throw :warden, response.finish + #end + end -- cgit v1.2.3 From 38544a07de7988eee91343c1491dae1e08ce5034 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:12:54 -0700 Subject: added 'thin' and 'quiet_assets' gems to make development mode much nicer. --- common_dependencies.rb | 2 ++ config/application.rb | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/common_dependencies.rb b/common_dependencies.rb index 1650fee..63c3710 100644 --- a/common_dependencies.rb +++ b/common_dependencies.rb @@ -7,5 +7,7 @@ end group :test, :development do gem 'faker' gem 'factory_girl_rails' + gem 'thin' + gem 'quiet_assets' end diff --git a/config/application.rb b/config/application.rb index 957bb0d..5e52c7b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -59,11 +59,18 @@ module LeapWeb # parameters by using an attr_accessible or attr_protected declaration. # config.active_record.whitelist_attributes = true + ## + ## ASSETS + ## + # Enable the asset pipeline config.assets.enabled = true config.assets.initialize_on_precompile = false # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' + + # Set to false in order to see asset requests in the log + config.quiet_assets = true end end -- cgit v1.2.3 From d121373b7c21a29e47708e8b67aeb964202e52c5 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:14:45 -0700 Subject: fix several issues with tickets: js error, when to redirect, navigation, localization. --- help/app/assets/javascripts/tickets.js | 8 +++--- help/app/controllers/tickets_controller.rb | 30 +++++++++++++++------- help/app/views/tickets/_comment.html.haml | 4 +-- help/app/views/tickets/_edit_form.html.haml | 10 +++----- help/app/views/tickets/_new_comment_form.html.haml | 5 ++-- help/app/views/tickets/_status-nav.html.haml | 13 +++++----- help/app/views/tickets/new.html.haml | 3 ++- help/config/locales/en.yml | 9 +++++-- help/leap_web_help.gemspec | 2 +- 9 files changed, 50 insertions(+), 34 deletions(-) diff --git a/help/app/assets/javascripts/tickets.js b/help/app/assets/javascripts/tickets.js index 5376a6e..bf7965c 100644 --- a/help/app/assets/javascripts/tickets.js +++ b/help/app/assets/javascripts/tickets.js @@ -1,4 +1,4 @@ -$(document).ready(function () { - $.fn.editable.defaults.mode = 'inline'; - $('#title').editable(); -}); \ No newline at end of file +//$(document).ready(function () { +// $.fn.editable.defaults.mode = 'inline'; +// $('#title').editable(); +//}); \ No newline at end of file diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index d478da9..3be7d10 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -42,19 +42,18 @@ class TicketsController < ApplicationController if params[:commit] == t(:close) @ticket.is_open = false @ticket.save - redirect_to tickets_path + redirect_to_tickets elsif params[:commit] == t(:open) @ticket.is_open = true @ticket.save redirect_to @ticket + elsif params[:commit] == t(:cancel) + redirect_to_tickets else @ticket.attributes = cleanup_ticket_params(params[:ticket]) if params[:commit] == t(:reply_and_close) @ticket.close - should_redirect = true - else - should_redirect = !logged_in? end if @ticket.comments_changed? @@ -64,11 +63,7 @@ class TicketsController < ApplicationController if @ticket.changed? if @ticket.save flash[:notice] = t(:changes_saved) - if should_redirect - redirect_to tickets_path - else - redirect_to @ticket - end + redirect_to_tickets else respond_with @ticket end @@ -97,6 +92,23 @@ class TicketsController < ApplicationController private + # + # redirects to ticket index, if appropriate. + # otherwise, just redirects to @ticket + # + def redirect_to_tickets + if logged_in? + if params[:commit] == t(:reply_and_close) + redirect_to tickets_url + else + redirect_to @ticket + end + else + # if we are not logged in, there is no index to view + redirect_to @ticket + end + end + # unset comments hash if no new comment was typed def cleanup_ticket_params(ticket) if ticket && ticket[:comments_attributes] diff --git a/help/app/views/tickets/_comment.html.haml b/help/app/views/tickets/_comment.html.haml index c02246c..4252eee 100644 --- a/help/app/views/tickets/_comment.html.haml +++ b/help/app/views/tickets/_comment.html.haml @@ -6,9 +6,9 @@ - if comment.posted_by_user = comment.posted_by_user.login - else - = t(:unknown) + = t(:anonymous) %div= comment.posted_at.to_s(:short) - - if comment.posted_by_user.is_admin? + - if comment.posted_by_user && comment.posted_by_user.is_admin? %div %span.label.label-inverse = t(:admin) diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 3d1d879..151d6f1 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -20,8 +20,7 @@ - else %span.label.label-success= t(:closed) %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe - = t(:subject) - %br + %div= t(:subject) = f.text_field :title, :class => 'large full-width' .row-fluid .span4 @@ -32,15 +31,14 @@ = f.text_field :email .span4 %div - = t(:regarding) + = t(:regarding_account) = regarding_user_link = f.text_field :regarding_user = f.submit t(:save), :class => 'btn' - if @ticket.is_open? = f.submit t(:close), :class => 'btn' - =# button_to t(:close), {:post => {:is_open => false}}, :method => :put, :class => 'btn' - else = f.submit t(:open), :class => 'btn' - =# button_to t(:open), {:post => {:is_open => true}}, :method => :put, :class => 'btn' - + - if admin? + = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn' diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml index b273503..de54259 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -7,7 +7,6 @@ - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true = f.button :submit, t(:post_reply), :class => 'btn-primary' - - if @ticket.is_open + - if logged_in? && @ticket.is_open = f.button :submit, t(:reply_and_close) - = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin? - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index e1dca84..c8279ed 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -1,9 +1,10 @@ %ul.nav.nav-tabs - %li{:class => ("active" if status == 'open')} - = link_to_status 'open' - %li{:class => ("active" if status == 'closed')} - = link_to_status 'closed' - %li{:class => ("active" if status == 'all')} - = link_to_status 'all' + - if logged_in? + %li{:class => ("active" if status == 'open')} + = link_to_status 'open' + %li{:class => ("active" if status == 'closed')} + = link_to_status 'closed' + %li{:class => ("active" if status == 'all')} + = link_to_status 'all' %li{:class => ("active" if action?(:new))} = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index acb9537..7d3f76c 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -14,4 +14,5 @@ = c.input :private, :as => :boolean, :label => false, :inline_label => true .form-actions = f.button :submit, :class => 'btn-primary' - = link_to t(:cancel), tickets_path, :class => :btn + - if logged_in? + = link_to t(:cancel), tickets_path, :class => :btn diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 901cd76..79e745f 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -1,5 +1,8 @@ en: - access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history" + access_ticket_text: > + You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. + Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to + remove it from the browser history. support_tickets: "Support Tickets" all_tickets: "All Tickets" my_tickets: "My Tickets" @@ -14,4 +17,6 @@ en: close: "Close" post_reply: "Post Reply" reply_and_close: "Reply and Close" - description: "Description" \ No newline at end of file + description: "Description" + ticket: "Ticket" + regarding_account: "Regarding Account" \ No newline at end of file diff --git a/help/leap_web_help.gemspec b/help/leap_web_help.gemspec index 09827dc..4914694 100644 --- a/help/leap_web_help.gemspec +++ b/help/leap_web_help.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.summary = "Help Desk for LeapWeb" s.description = "Managing Tickets for a Leap provider" - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] + s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"] s.test_files = Dir["test/**/*"] s.add_dependency "leap_web_core", LeapWeb::VERSION -- cgit v1.2.3 From e5a37b4ed76df8aec6131789e7361ed6efa3394b Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:18:28 -0700 Subject: new home page --- app/assets/stylesheets/leap.scss | 22 ++++++ app/helpers/navigation_helper.rb | 82 ---------------------- app/views/home/_home_text.html.haml | 7 +- app/views/home/index.html.haml | 12 ++-- core/app/helpers/navigation_helper.rb | 82 ++++++++++++++++++++++ core/app/helpers/snippet_helper.rb | 11 +++ core/app/views/common/_home_page_buttons.html.haml | 18 +++++ 7 files changed, 145 insertions(+), 89 deletions(-) delete mode 100644 app/helpers/navigation_helper.rb create mode 100644 core/app/helpers/navigation_helper.rb create mode 100644 core/app/helpers/snippet_helper.rb create mode 100644 core/app/views/common/_home_page_buttons.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 6b44986..a7d6261 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -45,6 +45,10 @@ input.large { line-height: $baseLineHeight * 1.5; } +.p { + @extend p; +} + // // FORMS // @@ -99,6 +103,24 @@ input, textarea { } } +.home-buttons { + .span6 { + margin-bottom: 20px; + } + div { + a { + width: 10em; + margin-bottom: 4px; + display: block; + } + .info { + } + span { + } + } +} + + // // Side Navigation // diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb deleted file mode 100644 index 19cb934..0000000 --- a/app/helpers/navigation_helper.rb +++ /dev/null @@ -1,82 +0,0 @@ -module NavigationHelper - - # - # used to create a side navigation link. - # - # Signature is the same as link_to, except it accepts an :active value in the html_options - # - def link_to_navigation(*args) - if args.last.is_a? Hash - html_options = args.pop.dup - active_class = html_options.delete(:active) ? 'active' : nil - html_options[:class] = [html_options[:class], active_class].join(' ') - args << html_options - else - active_class = nil - end - content_tag :li, :class => active_class do - link_to(*args) - end - end - - # - # returns true if params[:action] matches one of the args. - # - def action?(*actions) - actions.detect do |action| - if action.is_a? String - action == action_string - elsif action.is_a? Symbol - if action == :none - action_string == nil - else - action == action_symbol - end - end - end - end - - # - # returns true if params[:controller] matches one of the args. - # - # for example: - # controller?(:me, :home) - # controller?('groups/') <-- matches any controller in namespace 'groups' - # - def controller?(*controllers) - controllers.each do |cntr| - if cntr.is_a? String - if cntr.ends_with?('/') - return true if controller_string.starts_with?(cntr.chop) - end - return true if cntr == controller_string - elsif cntr.is_a? Symbol - return true if cntr == controller_symbol - end - end - return false - end - - private - - def controller_string - @controller_string ||= params[:controller].to_s.gsub(/^\//, '') - end - - def controller_symbol - @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym - end - - def action_string - params[:action] - end - - def action_symbol - @action_symbol ||= if params[:action].present? - params[:action].to_sym - else - nil - end - end - -end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml index 1055091..4de4b5e 100644 --- a/app/views/home/_home_text.html.haml +++ b/app/views/home/_home_text.html.haml @@ -1,3 +1,6 @@ -Welcome to the LEAP web application. +%h1= t(:welcome, :provider => APP_CONFIG[:domain]) -For more information, visit #{link_to('leap.se', 'https://leap.se')} \ No newline at end of file +%p + We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). + += home_page_buttons diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 0b3bbf9..96a3aee 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,8 +1,10 @@ -.row-fluid - .span8 - = render 'home_text' - .span4 - = render '/login_or_signup' +/ .row-fluid +/ .span8 +/ = render 'home_text' +/ .span4 +/ = render '/login_or_signup' + += render 'home_text' - if Rails.env == 'development' .row-fluid diff --git a/core/app/helpers/navigation_helper.rb b/core/app/helpers/navigation_helper.rb new file mode 100644 index 0000000..19cb934 --- /dev/null +++ b/core/app/helpers/navigation_helper.rb @@ -0,0 +1,82 @@ +module NavigationHelper + + # + # used to create a side navigation link. + # + # Signature is the same as link_to, except it accepts an :active value in the html_options + # + def link_to_navigation(*args) + if args.last.is_a? Hash + html_options = args.pop.dup + active_class = html_options.delete(:active) ? 'active' : nil + html_options[:class] = [html_options[:class], active_class].join(' ') + args << html_options + else + active_class = nil + end + content_tag :li, :class => active_class do + link_to(*args) + end + end + + # + # returns true if params[:action] matches one of the args. + # + def action?(*actions) + actions.detect do |action| + if action.is_a? String + action == action_string + elsif action.is_a? Symbol + if action == :none + action_string == nil + else + action == action_symbol + end + end + end + end + + # + # returns true if params[:controller] matches one of the args. + # + # for example: + # controller?(:me, :home) + # controller?('groups/') <-- matches any controller in namespace 'groups' + # + def controller?(*controllers) + controllers.each do |cntr| + if cntr.is_a? String + if cntr.ends_with?('/') + return true if controller_string.starts_with?(cntr.chop) + end + return true if cntr == controller_string + elsif cntr.is_a? Symbol + return true if cntr == controller_symbol + end + end + return false + end + + private + + def controller_string + @controller_string ||= params[:controller].to_s.gsub(/^\//, '') + end + + def controller_symbol + @controller_symbol ||= params[:controller].gsub(/^\//,'').gsub('/','_').to_sym + end + + def action_string + params[:action] + end + + def action_symbol + @action_symbol ||= if params[:action].present? + params[:action].to_sym + else + nil + end + end + +end diff --git a/core/app/helpers/snippet_helper.rb b/core/app/helpers/snippet_helper.rb new file mode 100644 index 0000000..6fee454 --- /dev/null +++ b/core/app/helpers/snippet_helper.rb @@ -0,0 +1,11 @@ +# +# various html snippets we use throughout. +# + +module SnippetHelper + + def home_page_buttons + render 'common/home_page_buttons' + end + +end \ No newline at end of file diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml new file mode 100644 index 0000000..ed70ff7 --- /dev/null +++ b/core/app/views/common/_home_page_buttons.html.haml @@ -0,0 +1,18 @@ +- link_class = 'btn' +- icon_color = :black + +.home-buttons + .row-fluid.first + .login.span6 + %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => link_class) + %span.info= t(:login_info) + .signup.span6 + %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => link_class) + %span.info= t(:signup_info) + .row-fluid.second + .download.span6 + %span.link= link_to(icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => link_class) + %span.info= t(:download_client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe + .help.span6 + %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => link_class) + %span.info= t(:help_info) -- cgit v1.2.3 From 7d2163263c8e5af7f4d7a2d40cd55eefac188e58 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 23 Jun 2013 22:21:55 -0700 Subject: moved app locales to core gem. --- config/locales/en.yml | 21 --------------------- core/config/locales/en.yml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 core/config/locales/en.yml diff --git a/config/locales/en.yml b/config/locales/en.yml index f4e35f2..63f1c3e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,22 +1 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. - en: - hello: "Hello world" - no_such_thing: "No such %{thing}." - - overview: "Overview" - user_control_panel: "user control panel" - - created: "Created" - created_by_on: "Created by %{user} on %{time}" - updated: "Updated" - - none: "None" - unknown: "Unknown" - admin: "Admin" - anonymous: "Anonymous" - save: "Save" - - changes_saved: "Changes saved successfully." - thing_was_successfully_created: "%{thing} was successfully created." \ No newline at end of file diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml new file mode 100644 index 0000000..24a2a13 --- /dev/null +++ b/core/config/locales/en.yml @@ -0,0 +1,25 @@ +en: + no_such_thing: "No such %{thing}." + thing_was_successfully_created: "%{thing} was successfully created." + + overview: "Overview" + user_control_panel: "user control panel" + + created: "Created" + created_by_on: "Created by %{user} on %{time}" + updated: "Updated" + + none: "None" + unknown: "Unknown" + admin: "Admin" + anonymous: "Anonymous" + save: "Save" + changes_saved: "Changes saved successfully." + + download_client: "Download LEAP" + download_client_info: "The LEAP application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." + login_info: "Log in to change your account settings, create support tickets, and manage payments." + signup_info: "Sign up for a new user account via this website (it is better if you use the LEAP application to sign up, but this website works too)." + welcome: "Welcome to %{provider}." + get_help: "Get Help" + help_info: "Can't login? Create a new support ticket anonymously." \ No newline at end of file -- cgit v1.2.3 From 4863ce5e78d880f1ca8a1874cd03022afb061f4a Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 28 Jun 2013 20:38:14 -0700 Subject: new layout for the home buttons --- app/assets/stylesheets/leap.scss | 112 +++++++++++++-------- app/controllers/application_controller.rb | 12 +++ app/helpers/application_helper.rb | 8 ++ app/views/home/_home_text.html.haml | 6 -- app/views/home/index.html.haml | 11 +- app/views/layouts/_masthead_large.html.haml | 3 - app/views/layouts/_masthead_noauth.html.haml | 3 + app/views/layouts/_messages.html.haml | 2 +- app/views/layouts/application.html.haml | 4 +- core/app/views/common/_home_page_buttons.html.haml | 23 +++-- public/img/32/arrow-down.png | Bin 0 -> 453 bytes 11 files changed, 114 insertions(+), 70 deletions(-) delete mode 100644 app/views/home/_home_text.html.haml delete mode 100644 app/views/layouts/_masthead_large.html.haml create mode 100644 app/views/layouts/_masthead_noauth.html.haml create mode 100644 public/img/32/arrow-down.png diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index a7d6261..577d211 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -1,27 +1,24 @@ +// +// LAYOUT +// -table.table-hover .btn { - opacity: 0; -} -table.table-hover tr:hover .btn { - opacity: 1; -} - -.ticket { - td.user { - white-space: nowrap; - } - td.comment { - width: 100%; - } +// This is a trick to be able to use bootstrap fluid layout and also have a max-width. +// It is like having your cake and eating it too. +#main { + *zoom: 1; + margin-left: auto; + margin-right: auto; + width: 1000px; + max-width: 100%; } // // UTILITY // -.debug { - outline: 1px solid red; -} +//.debug { +// outline: 1px solid red; +//} .full-width { width: 100%; @@ -36,8 +33,35 @@ table.table-hover tr:hover .btn { padding-top: 0; } +.last { + margin-bottom: 0; + padding-bottom: 0; +} + // -// Typography +// ICONS +// + +[class^="big-icon-"], +[class*=" big-icon-"] { + display: inline-block; + width: 32px; + height: 32px; + @include ie7-restore-right-whitespace(); + line-height: 32px; + vertical-align: middle; + //background-image: $iconSpritePath; + //background-position: 14px 14px; + background-repeat: no-repeat; + margin-top: 1px; +} + +.big-icon-arrow-down { + background-image: url(/img/32/arrow-down.png) +} + +// +// TYPOGRAPHY // input.large { @@ -50,7 +74,7 @@ input.large { } // -// FORMS +// BOOSTRAP TWEAKS // // @@ -67,27 +91,33 @@ input, textarea { } } -// -// Labels -// - +// like a label, but with no background .label-clear { background-color: $white; text-shadow: none; color: $black; } -// -// Icons -// - // force a black icon, even if bootstrap thinks differently .icon-black { background-image: url(/assets/glyphicons-halflings.png) !important; } // -// Boring default masthead +// TICKETS +// + +.ticket { + td.user { + white-space: nowrap; + } + td.comment { + width: 100%; + } +} + +// +// BORING DEFAULT MASTHEAD // #masthead { @@ -104,25 +134,25 @@ input, textarea { } .home-buttons { - .span6 { - margin-bottom: 20px; + text-align: center; + .first { + margin: 20px 0; } - div { - a { - width: 10em; - margin-bottom: 4px; - display: block; - } - .info { - } - span { + .download { + a.btn { + width: 14em; } } + a.btn { + font-weight: bold; + width: 11em; + margin: 10px auto; + display: block; + } } - // -// Side Navigation +// SIDE NAVIGATION // .sidenav { diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 06b245a..62d9df2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,4 +3,16 @@ class ApplicationController < ActionController::Base ActiveSupport.run_load_hooks(:application_controller, self) + protected + + # + # Allows us to pass through bold text to flash messages. See format_flash() for where this is reversed. + # + # TODO: move to core + # + def bold(str) + "[b]#{str}[/b]" + end + helper_method :bold + end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a236a0a..1e79990 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -29,4 +29,12 @@ module ApplicationHelper " ".html_safe end + def big_icon(name, color=nil) + " ".html_safe + end + + def format_flash(msg) + html_escape(msg).gsub('[b]', '').gsub('[/b]', '').html_safe + end + end diff --git a/app/views/home/_home_text.html.haml b/app/views/home/_home_text.html.haml deleted file mode 100644 index 4de4b5e..0000000 --- a/app/views/home/_home_text.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%h1= t(:welcome, :provider => APP_CONFIG[:domain]) - -%p - We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). - -= home_page_buttons diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 96a3aee..9da66a1 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,10 +1,9 @@ -/ .row-fluid -/ .span8 -/ = render 'home_text' -/ .span4 -/ = render '/login_or_signup' +%h1= t(:welcome, :provider => APP_CONFIG[:domain]) -= render 'home_text' +%p + We provide secure communication services, including encrypted internet, email (coming soon), and chat (coming later). + += home_page_buttons - if Rails.env == 'development' .row-fluid diff --git a/app/views/layouts/_masthead_large.html.haml b/app/views/layouts/_masthead_large.html.haml deleted file mode 100644 index 6bb1943..0000000 --- a/app/views/layouts/_masthead_large.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -.title - %span.sitename - = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_masthead_noauth.html.haml b/app/views/layouts/_masthead_noauth.html.haml new file mode 100644 index 0000000..6bb1943 --- /dev/null +++ b/app/views/layouts/_masthead_noauth.html.haml @@ -0,0 +1,3 @@ +.title + %span.sitename + = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/_messages.html.haml b/app/views/layouts/_messages.html.haml index 80e34d4..a3bbbac 100644 --- a/app/views/layouts/_messages.html.haml +++ b/app/views/layouts/_messages.html.haml @@ -2,4 +2,4 @@ - if msg.is_a?(String) %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} %a.close{"data-dismiss" => "alert"} × - = content_tag :div, msg, :id => "flash_#{name}" + = content_tag :div, format_flash(msg), :id => "flash_#{name}" diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 71364fc..e185f26 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -12,8 +12,8 @@ #masthead - if logged_in? = render 'layouts/masthead' - - else - = render 'layouts/masthead_large' + - elsif params[:controller] != 'home' + = render 'layouts/masthead_noauth' #main .container-fluid - if logged_in? diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml index ed70ff7..82a5cc2 100644 --- a/core/app/views/common/_home_page_buttons.html.haml +++ b/core/app/views/common/_home_page_buttons.html.haml @@ -1,18 +1,19 @@ -- link_class = 'btn' - icon_color = :black .home-buttons .row-fluid.first - .login.span6 - %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => link_class) - %span.info= t(:login_info) - .signup.span6 - %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => link_class) - %span.info= t(:signup_info) - .row-fluid.second + .span3 .download.span6 - %span.link= link_to(icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => link_class) + %span.link= link_to(big_icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => 'btn btn-large') %span.info= t(:download_client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe - .help.span6 - %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => link_class) + .span3 + .row-fluid.second + .login.span4 + %span.link= link_to(icon('ok-sign', icon_color) + t(:login), new_session_path, :class => 'btn') + %span.info= t(:login_info) + .signup.span4 + %span.link= link_to(icon('user', icon_color) + t(:signup), new_user_path, :class => 'btn') + %span.info= t(:signup_info) + .help.span4 + %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), "/tickets/new", :class => 'btn') %span.info= t(:help_info) diff --git a/public/img/32/arrow-down.png b/public/img/32/arrow-down.png new file mode 100644 index 0000000..3b16e6d Binary files /dev/null and b/public/img/32/arrow-down.png differ -- cgit v1.2.3 From e996432cbd50f4dadaae0ff62ac3f286ab125b1f Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:11:23 -0700 Subject: add js to report all errors to the user, not just ones related to field validation. --- app/assets/javascripts/application.js | 3 +- core/app/assets/javascripts/leap.js | 7 ++ users/app/assets/javascripts/users.js | 74 ++++++++++++++++++++++ users/app/assets/javascripts/users.js.coffee | 46 -------------- .../controller_extension/authentication.rb | 15 ++++- 5 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 core/app/assets/javascripts/leap.js create mode 100644 users/app/assets/javascripts/users.js delete mode 100644 users/app/assets/javascripts/users.js.coffee diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ad4dbbf..cd90934 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,11 +14,10 @@ //= require jquery_ujs //= require srp //= require bootstrap -//# require bootstrap-editable -//# require bootstrap-editable-rails //= require rails.validations //= require rails.validations.simple_form +//= require leap //= require tickets //= require users diff --git a/core/app/assets/javascripts/leap.js b/core/app/assets/javascripts/leap.js new file mode 100644 index 0000000..94e602d --- /dev/null +++ b/core/app/assets/javascripts/leap.js @@ -0,0 +1,7 @@ + +// +// add a bootstrap alert to the page via javascript. +// +function alert_message(msg) { + $('#messages').append('
×'+msg+'
'); +} diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js new file mode 100644 index 0000000..eed1961 --- /dev/null +++ b/users/app/assets/javascripts/users.js @@ -0,0 +1,74 @@ +(function() { + // + // LOCAL FUNCTIONS + // + + var poll_users, prevent_default, form_failed, form_passed; + + prevent_default = function(event) { + return event.preventDefault(); + }; + + poll_users = function(query, process) { + return $.get("/users.json", { + query: query + }).done(process); + }; + + // + // PUBLIC FUNCTIONS + // + + srp.session = new srp.Session(); + + srp.signedUp = function() { + return srp.login(); + }; + + srp.loggedIn = function() { + return window.location = '/'; + }; + + srp.updated = function() { + return window.location = '/users/' + srp.session.id(); + }; + + // + // if a json request returns an error, this function gets called and + // decorates the appropriate fields with the error messages. + // + srp.error = function(message) { + var element, error, field; + if ($.isPlainObject(message) && message.errors) { + for (field in message.errors) { + error = message.errors[field]; + element = $('form input[name$="[' + field + ']"]'); + if (!element) { + next; + } + element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false); + } + } else if (message.error) { + alert_message(message.error); + } else { + alert_message(JSON.stringify(message)); + } + }; + + // + // INIT + // + + $(document).ready(function() { + $('#new_user').submit(prevent_default); + $('#new_user').submit(srp.signup); + $('#new_session').submit(prevent_default); + $('#new_session').submit(srp.login); + $('#update_login_and_password').submit(prevent_default); + $('#update_login_and_password').submit(srp.update); + return $('.user.typeahead').typeahead({ + source: poll_users + }); + }); + +}).call(this); diff --git a/users/app/assets/javascripts/users.js.coffee b/users/app/assets/javascripts/users.js.coffee deleted file mode 100644 index 955556c..0000000 --- a/users/app/assets/javascripts/users.js.coffee +++ /dev/null @@ -1,46 +0,0 @@ -preventDefault = (event) -> - event.preventDefault() - -srp.session = new srp.Session() -srp.signedUp = -> - srp.login() - -srp.loggedIn = -> - window.location = '/' - -#// TODO: not sure this is what we want. -srp.updated = -> - window.location = '/' - -srp.error = (message) -> - if $.isPlainObject(message) && message.errors - for field, error of message.errors - element = $('form input[name$="['+field+']"]') - next unless element - element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false) - else - alert(message) - -pollUsers = (query, process) -> - $.get( "/users.json", query: query).done(process) - -followLocationHash = -> - location = window.location.hash - if location - href_select = 'a[href="' + location + '"]' - link = $(href_select) - link.tab('show') if link - -$(document).ready -> - followLocationHash() - $('#new_user').submit preventDefault - $('#new_user').submit srp.signup - $('#new_session').submit preventDefault - $('#new_session').submit srp.login - $('.user.form.update_login_and_password').submit srp.update - $('.user.form.update_login_and_password').submit preventDefault - $('.user.typeahead').typeahead({source: pollUsers}); - $('a[data-toggle="tab"]').on('shown', -> - $(ClientSideValidations.selectors.forms).validate() - ) - diff --git a/users/app/controllers/controller_extension/authentication.rb b/users/app/controllers/controller_extension/authentication.rb index f0a6564..72df7a7 100644 --- a/users/app/controllers/controller_extension/authentication.rb +++ b/users/app/controllers/controller_extension/authentication.rb @@ -38,9 +38,18 @@ module ControllerExtension::Authentication end def access_denied - # TODO: should we redirect to the root_url in either case, and have the root_url include the login screen (and also ability to create unauthenticated tickets) when no user is logged in? - redirect_to login_url, :alert => "Not authorized" if !logged_in? - redirect_to root_url, :alert => "Not authorized" if logged_in? + respond_to do |format| + format.html do + if logged_in? + redirect_to root_url, :alert => t(:not_authorized) + else + redirect_to login_url, :alert => t(:not_authorized_login) + end + end + format.json do + render :json => {'error' => t(:not_authorized)}, status: :unprocessable_entity + end + end end def admin? -- cgit v1.2.3 From fa7b7425e7c53282472c1c9ce1cdc7272f55cfd4 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:17:44 -0700 Subject: users engine changes - rewrite of the views, separate email settings to a separate controller, make users_controller html only and v1/users_controller json only. --- users/app/controllers/email_aliases_controller.rb | 18 ++----- users/app/controllers/email_settings_controller.rb | 34 ++++++++++++ users/app/controllers/users_controller.rb | 54 ++++--------------- users/app/controllers/v1/users_controller.rb | 9 ++-- users/app/helpers/users_helper.rb | 36 +------------ users/app/views/_login_or_signup.html.haml | 25 --------- users/app/views/email_settings/edit.html.haml | 38 ++++++++++++++ users/app/views/emails/_email.html.haml | 2 +- users/app/views/emails/edit.html.haml | 5 -- users/app/views/sessions/_admin_nav.html.haml | 6 --- users/app/views/sessions/_nav.html.haml | 13 ----- users/app/views/sessions/_new.html.haml | 7 --- users/app/views/sessions/new.html.haml | 13 ++--- users/app/views/users/_cancel_account.html.haml | 9 ---- users/app/views/users/_edit.html.haml | 37 +++++++++++++ users/app/views/users/_email_aliases.html.haml | 6 --- users/app/views/users/_email_field.html.haml | 1 - .../app/views/users/_email_forward_field.html.haml | 1 - users/app/views/users/_form.html.haml | 11 ---- users/app/views/users/_legend_and_submit.html.haml | 4 -- .../users/_login_and_password_fields.html.haml | 2 - users/app/views/users/_login_field.html.haml | 1 - users/app/views/users/_password_fields.html.haml | 2 - users/app/views/users/_public_key_field.html.haml | 1 - users/app/views/users/edit.html.haml | 7 ++- users/app/views/users/index.html.haml | 31 +++++------ users/app/views/users/new.html.haml | 20 ++++--- users/app/views/users/show.html.haml | 61 ++++++++++++---------- users/config/locales/en.yml | 35 ++++++------- users/config/routes.rb | 3 +- 30 files changed, 224 insertions(+), 268 deletions(-) delete mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/email_settings/edit.html.haml delete mode 100644 users/app/views/emails/edit.html.haml delete mode 100644 users/app/views/sessions/_admin_nav.html.haml delete mode 100644 users/app/views/sessions/_nav.html.haml delete mode 100644 users/app/views/sessions/_new.html.haml delete mode 100644 users/app/views/users/_cancel_account.html.haml create mode 100644 users/app/views/users/_edit.html.haml delete mode 100644 users/app/views/users/_email_aliases.html.haml delete mode 100644 users/app/views/users/_email_field.html.haml delete mode 100644 users/app/views/users/_email_forward_field.html.haml delete mode 100644 users/app/views/users/_form.html.haml delete mode 100644 users/app/views/users/_legend_and_submit.html.haml delete mode 100644 users/app/views/users/_login_and_password_fields.html.haml delete mode 100644 users/app/views/users/_login_field.html.haml delete mode 100644 users/app/views/users/_password_fields.html.haml delete mode 100644 users/app/views/users/_public_key_field.html.haml diff --git a/users/app/controllers/email_aliases_controller.rb b/users/app/controllers/email_aliases_controller.rb index 3b0d5ac..4628a7f 100644 --- a/users/app/controllers/email_aliases_controller.rb +++ b/users/app/controllers/email_aliases_controller.rb @@ -1,20 +1,12 @@ -class EmailAliasesController < ApplicationController - +class EmailAliasesController < UsersBaseController before_filter :fetch_user - respond_to :html - def destroy @alias = @user.email_aliases.delete(params[:id]) - @user.save - flash[:notice] = t(:email_alias_destroyed_successfully, :alias => @alias) - redirect_to edit_user_path(@user, :anchor => :email) + if @user.save + flash[:notice] = t(:email_alias_destroyed_successfully, :alias => bold(@alias)) + end + redirect_to edit_user_email_settings_path(@user) end - protected - - def fetch_user - @user = User.find_by_param(params[:user_id]) - access_denied unless admin? or (@user == current_user) - end end diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb index e69de29..0261b47 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -0,0 +1,34 @@ +class EmailSettingsController < UsersBaseController + + before_filter :authorize + before_filter :fetch_user + + def edit + @email_alias = LocalEmail.new + end + + def update + @user.attributes = params[:user] + if @user.changed? + if @user.save + flash[:notice] = t(:changes_saved) + redirect + else + if @user.email_aliases.last && !@user.email_aliases.last.valid? + # display bad alias in text field: + @email_alias = @user.email_aliases.pop + end + render 'email_settings/edit' + end + else + redirect + end + end + + private + + def redirect + redirect_to edit_user_email_settings_url(@user) + end + +end diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 38a69e3..0dbf641 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -1,12 +1,14 @@ -class UsersController < ApplicationController +# +# This is an HTML-only controller. For the JSON-only controller, see v1/users_controller.rb +# - before_filter :authorize, :only => [:show, :edit, :destroy, :update] +class UsersController < UsersBaseController + + before_filter :authorize, :only => [:show, :edit, :update, :destroy] before_filter :fetch_user, :only => [:show, :edit, :update, :destroy] - before_filter :authorize_self, :only => [:update] - before_filter :set_anchor, :only => [:edit, :update] before_filter :authorize_admin, :only => [:index] - respond_to :json, :html + respond_to :html def index if params[:query] @@ -14,8 +16,7 @@ class UsersController < ApplicationController else @users = User.by_created_at.descending end - @users = @users.limit(10) - respond_with @users.map(&:login).sort + @users = @users.limit(APP_CONFIG[:pagination_size]) end def new @@ -27,48 +28,15 @@ class UsersController < ApplicationController respond_with @user end - def edit - @email_alias = LocalEmail.new + def show end - def update - @user.attributes = params[:user] - if @user.changed? and @user.save - flash[:notice] = t(:user_updated_successfully) - elsif @user.email_aliases.last and !@user.email_aliases.last.valid? - @email_alias = @user.email_aliases.pop - end - respond_with @user, :location => edit_user_path(@user, :anchor => @anchor) + def edit end def destroy @user.destroy - redirect_to admin? ? users_path : root_path + redirect_to admin? ? users_path : login_path end - protected - - def fetch_user - # authorize filter has been checked first, so won't get here unless authenticated - @user = User.find_by_param(params[:id]) - if !@user and admin? - redirect_to users_path, :alert => t(:no_such_thing, :thing => 'user') - return - end - access_denied unless admin? or (@user == current_user) - end - - def authorize_self - # have already checked that authorized - access_denied unless (@user == current_user) - end - - def set_anchor - @anchor = email_settings? ? :email : :account - end - - def email_settings? - params[:user] && - params[:user].keys.detect{|key| key.index('email')} - end end diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index 617bd4b..e7516bc 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -1,8 +1,9 @@ module V1 - class UsersController < ApplicationController + class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token before_filter :authorize, :only => [:update] + before_filter :fetch_user, :only => [:update] respond_to :json @@ -12,9 +13,11 @@ module V1 end def update - # For now, only allow public key to be updated via the API. Eventually we might want to store in a config what attributes can be updated via the API. @user = User.find_by_param(params[:id]) - @user.update_attributes params[:user].slice(:public_key) if params[:user].respond_to?(:slice) + @user.update_attributes params[:user] + if @user.valid? + flash[:notice] = t(:user_updated_successfully) + end respond_with @user end diff --git a/users/app/helpers/users_helper.rb b/users/app/helpers/users_helper.rb index 559b3f7..f56faab 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -1,39 +1,7 @@ module UsersHelper - def user_form_with(partial, options = {}) - user_form(options) do |f| - options[:f] = f - render :partial => partial, - :layout => 'legend_and_submit', - :locals => options - end - end - - def user_form(options = {}) - simple_form_for @user, - :html => user_form_html_options(options), - :validate => true do |f| - yield f - end - end - - def user_form_html_options(options) - { :class => user_form_html_classes(options).join(" "), - :id => dom_id(@user, options[:legend]) - } - end - - def user_form_html_classes(options) - classes = %W/user form/ - classes << options[:legend] - classes << (@user.new_record? ? 'new' : 'edit') - classes.compact - end - - def user_field(field) - value = @user.send(field) - value = value.to_s(:long) if field.end_with? '_at' - value || 'not set' + def user_form_class(*classes) + (classes + ['user', 'form', (@user.new_record? ? 'new' : 'edit')]).compact.join(' ') end def wrapped(item, options = {}) diff --git a/users/app/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml deleted file mode 100644 index b353526..0000000 --- a/users/app/views/_login_or_signup.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -// -// displays a little widget to login or sign up -// - -%ul.nav.nav-tabs - %li.active - %a{:href => ''}= t(:login) - %li - = link_to t(:signup), new_user_path - -= render 'sessions/new' - -// -// this is nice, but it doesn't work because both forms have the same names for fields. -// -// %ul.nav.nav-tabs -// %li.active -// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) -// %li -// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) -// .tab-content -// #login.tab-pane.active -// = render 'sessions/new' -// #signup.tab-pane -// = render 'users/new' diff --git a/users/app/views/email_settings/edit.html.haml b/users/app/views/email_settings/edit.html.haml new file mode 100644 index 0000000..7757a31 --- /dev/null +++ b/users/app/views/email_settings/edit.html.haml @@ -0,0 +1,38 @@ +- form_options = {:url => user_email_settings_path(@user), :html => {:class => 'form-horizontal'}, :validate => true} +- alias_error_class = @email_alias.username && !@email_alias.valid? ? 'error' : '' + +- content_for :head do + :css + table.aliases tr:first-child td { + border-top: none; + } + += simple_form_for @user, form_options.dup do |f| + %legend= t(:email_aliases) + .control-group + %label.control-label= t(:current_aliases) + .controls + %table.table.table-condensed.no-header.slim.aliases + - if @user.email_aliases.any? + - @user.email_aliases.each do |email| + %tr + %td= email + %td= link_to(icon(:remove) + t(:remove), user_email_alias_path(@user, email), :method => :delete) + - else + %tr + %td{:colspan=>2}= t(:none) + .control-group{:class => alias_error_class} + %label.control-label= t(:add_email_alias) + .controls + = f.simple_fields_for :email_aliases, @email_alias do |e| + .input-append + = e.input_field :username + = e.submit t(:add), :class => 'btn' + = e.error :username + += simple_form_for @user, form_options do |f| + %legend= t(:advanced_options) + = f.input :email_forward + = f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "full-width", :rows => 4} + .form-actions + = f.submit t(:save), :class => 'btn btn-primary' diff --git a/users/app/views/emails/_email.html.haml b/users/app/views/emails/_email.html.haml index c81b396..ea59cec 100644 --- a/users/app/views/emails/_email.html.haml +++ b/users/app/views/emails/_email.html.haml @@ -3,4 +3,4 @@ - if local_assigns[:with].try(:include?, :delete) = link_to(user_email_alias_path(@user, email), :method => :delete) do %i.icon-remove -.clearfix + diff --git a/users/app/views/emails/edit.html.haml b/users/app/views/emails/edit.html.haml deleted file mode 100644 index b44b569..0000000 --- a/users/app/views/emails/edit.html.haml +++ /dev/null @@ -1,5 +0,0 @@ - - -= user_form_with 'public_key_field', :legend => :public_key -= user_form_with 'email_forward_field', :legend => :forward_email -= user_form_with 'email_aliases', :legend => :add_email_alias diff --git a/users/app/views/sessions/_admin_nav.html.haml b/users/app/views/sessions/_admin_nav.html.haml deleted file mode 100644 index 14dfbdc..0000000 --- a/users/app/views/sessions/_admin_nav.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%a#admin-menu{"data-toggle" => "dropdown", :role => :button} - Admin -%ul.dropdown-menu{:role => "menu", "aria-labelledby" => "admin-menu"} - %li - = link_to Ticket.model_name.human(:count => ""), tickets_path, {:tabindex => -1} - = link_to User.model_name.human(:count => ""), users_path, {:tabindex => -1} diff --git a/users/app/views/sessions/_nav.html.haml b/users/app/views/sessions/_nav.html.haml deleted file mode 100644 index ac85bb5..0000000 --- a/users/app/views/sessions/_nav.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- if logged_in? - - if admin? - %li.dropdown - = render 'sessions/admin_nav' - %li - = link_to current_user.login, edit_user_path(current_user) - %li - = link_to t(:logout), logout_path, :method => :delete -- else - %li - = link_to t(:login), login_path - %li - = link_to t(:signup), signup_path diff --git a/users/app/views/sessions/_new.html.haml b/users/app/views/sessions/_new.html.haml deleted file mode 100644 index 640fec5..0000000 --- a/users/app/views/sessions/_new.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- @session ||= Session.new -= simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| - = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } - = f.input :password, :required => false, :input_html => { :id => :srp_password } - .form-actions - = f.button :submit, :value => t(:login), :class => 'btn-primary' - // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 960919a..c915968 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -1,9 +1,10 @@ -.span8.offset2 +.span1 +.span9 = render :partial => 'users/warnings' %h2=t :login = simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| - %legend=t :login_message - = f.input :login, :input_html => { :id => :srp_username } - = f.input :password, :required => true, :input_html => { :id => :srp_password } - = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn + = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } + = f.input :password, :required => false, :input_html => { :id => :srp_password } + .form-actions + = f.button :submit, :value => t(:login), :class => 'btn-primary' + = link_to t(:cancel), root_path, :class => 'btn' diff --git a/users/app/views/users/_cancel_account.html.haml b/users/app/views/users/_cancel_account.html.haml deleted file mode 100644 index c5ab36a..0000000 --- a/users/app/views/users/_cancel_account.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%legend - - if @user == current_user - =t :cancel_account - %small You will not be able to login anymore. - - else - =t :admin_cancel_account, :username => @user.login -= link_to user_path(@user), :method => :delete, :confirm => t(:confirm_question), :class => "btn btn-danger" do - %i.icon-remove.icon-white - =t :remove_account diff --git a/users/app/views/users/_edit.html.haml b/users/app/views/users/_edit.html.haml new file mode 100644 index 0000000..adee8a4 --- /dev/null +++ b/users/app/views/users/_edit.html.haml @@ -0,0 +1,37 @@ +-# +-# edit user form, used by both show and edit actions. +-# + +-# +-# CHANGE PASSWORD +-# +-# * everything about this form is handled with javascript. So take care when changing any ids. +-# * the login is required when changing the password because it is used as part of the salt when calculating the password verifier. +-# however, we don't want the user to change their login without generating a new key, so we hide the ui for this +-# (although it works perfectly fine to change username if the field was visible). +-# +- form_options = {:url => '/not-used', :html => {:class => user_form_class('form-horizontal'), :id => 'update_login_and_password'}, :validate => true} += simple_form_for @user, form_options do |f| + %legend= t(:change_password) + = hidden_field_tag 'user_param', @user.to_param + .hidden + = f.input :login, :label => t(:username), :required => false, :input_html => {:id => :srp_username} + = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } + = f.input :password_confirmation, :required => false, :input_html => { :id => :srp_password_confirmation } + .control-group + .controls + = f.submit t(:save), :class => 'btn btn-primary' + +-# +-# DESTROY ACCOUNT +-# + +%legend + - if @user == current_user + = t(:destroy_my_account) + - else + = t(:admin_destroy_account, :username => @user.login) +%p= t(:destroy_account_info) += link_to user_path(@user), :method => :delete, :confirm => t(:are_you_sure), :class => "btn btn-danger" do + %i.icon-remove.icon-white + = t(:destroy_my_account) diff --git a/users/app/views/users/_email_aliases.html.haml b/users/app/views/users/_email_aliases.html.haml deleted file mode 100644 index 6e32700..0000000 --- a/users/app/views/users/_email_aliases.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.span6 - %ul.unstyled - = render @user.email_aliases, :as => :li, :with => [:delete] -.clearfix -= f.simple_fields_for :email_aliases, @email_alias do |e| - = e.input :username, :placeholder => "alias" diff --git a/users/app/views/users/_email_field.html.haml b/users/app/views/users/_email_field.html.haml deleted file mode 100644 index edf62c9..0000000 --- a/users/app/views/users/_email_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :email, :placeholder => "me@#{APP_CONFIG[:domain]}" diff --git a/users/app/views/users/_email_forward_field.html.haml b/users/app/views/users/_email_forward_field.html.haml deleted file mode 100644 index 049428f..0000000 --- a/users/app/views/users/_email_forward_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :email_forward diff --git a/users/app/views/users/_form.html.haml b/users/app/views/users/_form.html.haml deleted file mode 100644 index cb51175..0000000 --- a/users/app/views/users/_form.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- only = local_assigns[:only] -- html = {:class => 'form-horizontal user form ' + (@user.new_record? ? 'new' : 'edit')} -= simple_form_for @user, :validate => true, :format => :json, :html => html do |f| - %legend - = t(only || :signup_message) - = yield - .pull-right - = f.button :submit - - unless only - = link_to t(:cancel), root_url, :class => :btn - .clearfix diff --git a/users/app/views/users/_legend_and_submit.html.haml b/users/app/views/users/_legend_and_submit.html.haml deleted file mode 100644 index 6fc0e4a..0000000 --- a/users/app/views/users/_legend_and_submit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%legend= t(legend) -=yield -.pull-right= f.button :submit, :value => t(legend) -.clearfix diff --git a/users/app/views/users/_login_and_password_fields.html.haml b/users/app/views/users/_login_and_password_fields.html.haml deleted file mode 100644 index 0baefc7..0000000 --- a/users/app/views/users/_login_and_password_fields.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= render :partial => 'login_field', :locals => {:f => f} -= render :partial => 'password_fields', :locals => {:f => f, :password_confirmation_hint => t(:can_retype_old_password)} \ No newline at end of file diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml deleted file mode 100644 index e58c36f..0000000 --- a/users/app/views/users/_login_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml deleted file mode 100644 index 7b3358d..0000000 --- a/users/app/views/users/_password_fields.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } -= f.input :password_confirmation, :required => false, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } diff --git a/users/app/views/users/_public_key_field.html.haml b/users/app/views/users/_public_key_field.html.haml deleted file mode 100644 index af88cbd..0000000 --- a/users/app/views/users/_public_key_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "span5", :rows => 20} # will want to tweak this to be wide enough (maybe smaller text?) diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index 4e70d69..f06df44 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,3 +1,6 @@ -= user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user -= render 'cancel_account' += render 'edit' + + +=# user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user +=# render 'cancel_account' diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 9e6a179..254e177 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -1,17 +1,14 @@ -.page-header - %h1= User.model_name.human(:count =>User.count) -.row - .span8 - %h2= params[:query] ? "Users starting with '#{params[:query]}'" : "Last users who signed up" - %table.table.table-hover - %tr - %th Login - %th Created - %th Action - = render @users.all - .span4 - %h4 Find user - = form_tag users_path, :method => :get, :class => "form-search" do - .input-append - = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off - %button.btn{:type => :submit} Search +- @show_navigation = false + += form_tag users_path, :method => :get, :class => "form-search" do + .input-append + = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off + %button.btn{:type => :submit} Search + +%table.table.table-hover + %tr + %th Login + %th Created + %th Action + = render @users.all + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index 7d29de2..f8d14b5 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -1,11 +1,19 @@ -.span8.offset2 +-# +-# This form is handled entirely by javascript, so take care when changing element ids. +-# + +- form_options = {:url => '/not-used', :html => {:id => 'new_user', :class => user_form_class('form-horizontal')}, :validate => true} + +.span1 +.span9 = render :partial => 'warnings' %h2=t :signup - = user_form do |f| + = simple_form_for(@user, form_options) do |f| %legend= t(:signup_message) - = render :partial => 'login_field', :locals => {:f => f} - = render :partial => 'password_fields', :locals => {:f => f} + = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } + = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } + = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } .form-actions - = f.button :submit, :value => t(:signup), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn + = f.button :submit, :value => t(:signup), :class => 'btn btn-primary' + = link_to t(:cancel), root_url, :class => 'btn' diff --git a/users/app/views/users/show.html.haml b/users/app/views/users/show.html.haml index 056ed57..dc5e015 100644 --- a/users/app/views/users/show.html.haml +++ b/users/app/views/users/show.html.haml @@ -1,31 +1,34 @@ -.span8.offset1 - %h2= @user.login - .small - = link_to 'edit', edit_user_path(@user) - %dl.offset1 - - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward'] - - fields.each do |field| += render 'edit' + +-# + .span8.offset1 + %h2= @user.login + .small + = link_to 'edit', edit_user_path(@user) + %dl.offset1 + - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward'] + - fields.each do |field| + %dt + = field.titleize + %dd + = user_field(field) %dt - = field.titleize + =t :email_aliases %dd - = user_field(field) - %dt - =t :email_aliases - %dd - - aliases = @user.email_aliases - - if aliases.present? - %ul.pull-left.unstyled - = render aliases - - else - =t :none - .clearfix - %dt - =t :most_recently_updated_tickets - %dd - - tix = @user.most_recent_tickets - - if tix.present? - %table - %tbody - = render @user.most_recent_tickets - - else - =t :none \ No newline at end of file + - aliases = @user.email_aliases + - if aliases.present? + %ul.pull-left.unstyled + = render aliases + - else + =t :none + .clearfix + %dt + =t :most_recently_updated_tickets + %dd + - tix = @user.most_recent_tickets + - if tix.present? + %table + %tbody + = render @user.most_recent_tickets + - else + =t :none \ No newline at end of file diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 3c42b55..63ac692 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -9,28 +9,26 @@ en: login: "Log In" username: "Username" password: "Password" - login_message: "Please login with your account." + change_password: "Change Password" + login_message: "Please log in with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." update_login_and_password: "Update Login and Password" - cancel_account: "Cancel your account" - remove_account: "Remove Account" - admin_cancel_account: "Cancel the account %{username}" + destroy_my_account: "Destroy my account" + destroy_account_info: "This will permanently destroy your account and all the data associated with it. Proceed with caution!" + admin_destroy_account: "Destroy the account %{username}" set_email_address: "Set email address" - forward_email: "Forward email" - email_aliases: "Email aliases" + forward_email: "Forward Email" + email_aliases: "Email Aliases" public_key: "Public Key" - add_email_alias: "Add email alias" - confirm_question: "Are you sure?" + add_email_alias: "Add Email Alias" user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." - email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored OpenPGP key" - can_retype_old_password: "Retype your old password if you would like to keep that" - associated_email: "The associated email address is" - cookie_disabled_warning: "You have cookies disabled. You will not be able to login until you enable cookies." - js_required: "We are sorry, but this doesn't work without javascript enabled. This is for security reasons." - + email_alias_destroyed_successfully: "Removed email alias %{alias}." + use_ascii_key: "OpenPGP public key. Do not change this value unless you know what you are doing." + advanced_options: "Advanced Options" + not_authorized: "Sorry, but you are not authorized to perform that action." + not_authorized_login: "Please log in to perform that action." activemodel: models: user: @@ -39,11 +37,12 @@ en: simple_form: labels: user: - email_forward: "Email forward" + email_forward: "Email Forward" hints: user: - email_forward: "Forward all emails to this address" - email: "Your leap web email address" + email_forward: > + Forward all email messages to this address. Messages will be encrypted before being forwarded. + This is an option for advanced users who are familar with OpenPGP. placeholders: user: email_forward: "my_other_email@domain.net" diff --git a/users/config/routes.rb b/users/config/routes.rb index d07cda9..9eff2a1 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update] + resources :users, :only => [:create, :update, :destroy] end get "login" => "sessions#new", :as => "login" @@ -16,7 +16,6 @@ Rails.application.routes.draw do resources :users do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] - resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From b8c44acfa5b1fbc8b35e812bd6c23aa6d824c4b1 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:19:38 -0700 Subject: cleaned up application layout and some minor css. --- app/assets/stylesheets/leap.scss | 13 ++++++++++--- app/views/layouts/_content.html.haml | 19 +++++++++++++++++++ app/views/layouts/_header.html.haml | 10 ++++++++-- app/views/layouts/_messages.html.haml | 11 ++++++----- app/views/layouts/application.html.haml | 14 +++----------- 5 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 app/views/layouts/_content.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 577d211..4a3ca03 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -38,6 +38,10 @@ padding-bottom: 0; } +.hidden { + display: none; +} + // // ICONS // @@ -50,8 +54,6 @@ @include ie7-restore-right-whitespace(); line-height: 32px; vertical-align: middle; - //background-image: $iconSpritePath; - //background-position: 14px 14px; background-repeat: no-repeat; margin-top: 1px; } @@ -74,7 +76,7 @@ input.large { } // -// BOOSTRAP TWEAKS +// BOOTSTRAP TWEAKS // // @@ -155,6 +157,11 @@ input, textarea { // SIDE NAVIGATION // +.user_heading { + margin: 1em 0; + font-weight: bold; +} + .sidenav { @extend .nav-tabs; @extend .nav-stacked; diff --git a/app/views/layouts/_content.html.haml b/app/views/layouts/_content.html.haml new file mode 100644 index 0000000..19af627 --- /dev/null +++ b/app/views/layouts/_content.html.haml @@ -0,0 +1,19 @@ +-# +-# Partial for displaying the page content. This is the only place that content should be displayed. +-# + +- if content_for?(:content) + - content = yield(:content) +- else + - content = yield + +- if @show_navigation + .span2 + = render 'layouts/navigation' + .span10 + = render 'layouts/messages' + = content +- else + .span12 + = render 'layouts/messages' + = content diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index aa4054b..854ab40 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -1,3 +1,9 @@ -- if user - %strong.user_address +- if admin? + %ul.nav.nav-tabs + %li{:class => ("active" if controller?('users', 'email_settings', 'overviews') || params[:user_id])} + = link_to t(:users), users_path + %li{:class => ("active" if controller?('tickets') && !params[:user_id])} + = link_to t(:tickets), tickets_path +- if user && @show_navigation + .user_heading = user.email_address diff --git a/app/views/layouts/_messages.html.haml b/app/views/layouts/_messages.html.haml index a3bbbac..7ff985f 100644 --- a/app/views/layouts/_messages.html.haml +++ b/app/views/layouts/_messages.html.haml @@ -1,5 +1,6 @@ -- flash.each do |name, msg| - - if msg.is_a?(String) - %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} - %a.close{"data-dismiss" => "alert"} × - = content_tag :div, format_flash(msg), :id => "flash_#{name}" +#messages + - flash.each do |name, msg| + - if msg.is_a?(String) + %div{:class => "alert alert-#{name == :notice ? "success" : "error"}"} + %a.close{"data-dismiss" => "alert"} × + = content_tag :div, format_flash(msg), :id => "flash_#{name}" diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index e185f26..db612b7 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,3 +1,4 @@ +- @show_navigation = true if @show_navigation.nil? !!! %html %head @@ -20,16 +21,7 @@ .row-fluid .span12 = render 'layouts/header' - .row-fluid - .span2 - = render 'layouts/navigation' - .span10 - = render 'layouts/messages' - = yield - - else - .row-fluid - .span12 - = render 'layouts/messages' - = yield + .row-fluid + = render 'layouts/content' #footer = render 'layouts/footer' -- cgit v1.2.3 From 179a6457d4e56052664a6895bb9ab5b721b57352 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:19:56 -0700 Subject: added strings to core en.yml --- core/config/locales/en.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index 24a2a13..38724ca 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -14,12 +14,16 @@ en: admin: "Admin" anonymous: "Anonymous" save: "Save" + add: "Add" + remove: "Remove" changes_saved: "Changes saved successfully." + are_you_sure: "Are you sure? This change cannot be undone." - download_client: "Download LEAP" - download_client_info: "The LEAP application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." + download_client: "Download Bitmask" + download_client_info: "The Bitmask application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android." login_info: "Log in to change your account settings, create support tickets, and manage payments." - signup_info: "Sign up for a new user account via this website (it is better if you use the LEAP application to sign up, but this website works too)." + signup_info: "Sign up for a new user account via this website (it is better if you use the Bitmask application to sign up, but this website works too)." welcome: "Welcome to %{provider}." get_help: "Get Help" - help_info: "Can't login? Create a new support ticket anonymously." \ No newline at end of file + help_info: "Can't login? Create a new support ticket anonymously." + example_email: 'user@domain.org' -- cgit v1.2.3 From 0cd386e0144601f5478f90bbdb401d55c019c828 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:11:10 -0700 Subject: better ticket view navigation: tickets are now either global in scope (for admins) or stay as a nested resource for a particular user (for normal users and when you visit the tickets list of a particular user). --- app/assets/stylesheets/leap.scss | 9 ++++ app/views/layouts/_navigation.html.haml | 11 +---- help/app/controllers/tickets_controller.rb | 41 ++++++++++++----- help/app/helpers/auto_tickets_path_helper.rb | 51 ++++++++++++++++++++++ help/app/helpers/tickets_helper.rb | 41 ++++++++++++----- help/app/views/tickets/_admin-nav.html.haml | 5 --- help/app/views/tickets/_edit_form.html.haml | 3 +- help/app/views/tickets/_new_comment_form.html.haml | 3 +- help/app/views/tickets/_order-nav.html.haml | 4 +- help/app/views/tickets/_status-nav.html.haml | 8 ++-- help/app/views/tickets/_table-nav.html.haml | 3 -- help/app/views/tickets/_ticket.html.haml | 7 +-- help/app/views/tickets/index.html.haml | 2 + help/app/views/tickets/new.html.haml | 7 ++- help/app/views/tickets/show.html.haml | 2 + help/config/routes.rb | 7 +-- 16 files changed, 152 insertions(+), 52 deletions(-) create mode 100644 help/app/helpers/auto_tickets_path_helper.rb delete mode 100644 help/app/views/tickets/_admin-nav.html.haml diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 4a3ca03..792aa3c 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -105,6 +105,15 @@ input, textarea { background-image: url(/assets/glyphicons-halflings.png) !important; } +// override stupid bootstrap behavior of making the active tab appear non-clickable +// and links not being underline +.nav-tabs > li > a:hover, .sidenav > li > a:hover { + text-decoration: underline; +} +.nav-tabs > .active > a:hover { + cursor: pointer; +} + // // TICKETS // diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index 7cd0f38..cbe6d3a 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,13 +1,6 @@ -//= link_to "Leap Web", root_path, :class => 'brand' -//%ul.nav -// // = render '/tickets/nav' -// -//%ul.nav.pull-right -// = render '/sessions/nav' - %ul.nav.sidenav = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) - =# link_to_navigation t(:email_settings), edit_email_path(user), :active => controller?(:emails) - = link_to_navigation t(:support_tickets), tickets_path, :active => controller?(:tickets) + = link_to_navigation t(:email_settings), edit_user_email_settings_path(user), :active => controller?(:email_settings) + = link_to_navigation t(:support_tickets), auto_tickets_path(user), :active => controller?(:tickets) = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index 3be7d10..6fc4024 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -1,10 +1,12 @@ class TicketsController < ApplicationController + include AutoTicketsPathHelper respond_to :html, :json #has_scope :open, :type => boolean before_filter :authorize, :only => [:index] before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method + before_filter :fetch_user before_filter :set_title def new @@ -27,13 +29,13 @@ class TicketsController < ApplicationController if !logged_in? and flash[:notice] flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) end - respond_with(@ticket) + respond_with(@ticket, :location => auto_ticket_path(@ticket)) end def show @comment = TicketComment.new if !@ticket - redirect_to tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) + redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket)) return end end @@ -46,7 +48,7 @@ class TicketsController < ApplicationController elsif params[:commit] == t(:open) @ticket.is_open = true @ticket.save - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) elsif params[:commit] == t(:cancel) redirect_to_tickets else @@ -68,20 +70,20 @@ class TicketsController < ApplicationController respond_with @ticket end else - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end end end def index - @all_tickets = Ticket.for_user(current_user, params, admin?) #for tests, useful to have as separate variable + @all_tickets = Ticket.search(search_options(params)) @tickets = @all_tickets.page(params[:page]).per(APP_CONFIG[:pagination_size]) end def destroy # should we allow non-admins to delete their own tickets? i don't think necessary. @ticket.destroy if admin? - redirect_to tickets_path + redirect_to auto_tickets_path end protected @@ -99,17 +101,19 @@ class TicketsController < ApplicationController def redirect_to_tickets if logged_in? if params[:commit] == t(:reply_and_close) - redirect_to tickets_url + redirect_to auto_tickets_path else - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end else # if we are not logged in, there is no index to view - redirect_to @ticket + redirect_to auto_ticket_path(@ticket) end end + # # unset comments hash if no new comment was typed + # def cleanup_ticket_params(ticket) if ticket && ticket[:comments_attributes] if ticket[:comments_attributes].values.first[:body].blank? @@ -126,10 +130,27 @@ class TicketsController < ApplicationController def fetch_ticket @ticket = Ticket.find(params[:id]) if !@ticket and admin? - redirect_to tickets_path, :alert => t(:no_such_thing, :thing => 'ticket') + redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => 'ticket') return end access_denied unless ticket_access? end + def fetch_user + if params[:user_id] + @user = User.find_by_param(params[:user_id]) + end + end + + # + # clean up params for ticket search + # + def search_options(params) + params.merge( + :admin_status => params[:user_id] ? 'mine' : 'all', + :user_id => @user ? @user.id : current_user.id, + :is_admin => admin? + ) + end + end diff --git a/help/app/helpers/auto_tickets_path_helper.rb b/help/app/helpers/auto_tickets_path_helper.rb new file mode 100644 index 0000000..bb71260 --- /dev/null +++ b/help/app/helpers/auto_tickets_path_helper.rb @@ -0,0 +1,51 @@ +# +# These "auto" forms of the normal ticket path route helpers allow us to do two things automatically: +# +# (1) include the user in the path if appropriate. +# (2) retain the sort params, if appropriate. +# +# Tickets views with a user_id are limited to that user. For admins, they don't need a user_id for any ticket action. +# +# This is available both to the views and the tickets_controller. +# +module AutoTicketsPathHelper + + protected + + def auto_tickets_path(options={}) + options = ticket_view_options.merge options + if @user + user_tickets_path(@user, options) + else + tickets_path(options) + end + end + + def auto_ticket_path(ticket, options={}) + options = ticket_view_options.merge options + if @user + user_ticket_path(@user, ticket, options) + else + ticket_path(ticket, options) + end + end + + def auto_new_ticket_path(options={}) + options = ticket_view_options.merge options + if @user + new_user_ticket_path(@user, options) + else + new_ticket_path(options) + end + end + + private + + def ticket_view_options + hsh = {} + hsh[:open_status] = params[:open_status] if params[:open_status] && !params[:open_status].empty? + hsh[:sort_order] = params[:sort_order] if params[:sort_order] && !params[:sort_order].empty? + hsh + end + +end \ No newline at end of file diff --git a/help/app/helpers/tickets_helper.rb b/help/app/helpers/tickets_helper.rb index 8b4ff71..7af50d6 100644 --- a/help/app/helpers/tickets_helper.rb +++ b/help/app/helpers/tickets_helper.rb @@ -1,18 +1,39 @@ module TicketsHelper + # + # FORM HELPERS + # - def status - params[:open_status] + # + # hidden fields that should be added to ever ticket form. + # these are use for proper redirection after successful actions. + # + def hidden_ticket_fields + haml_concat hidden_field_tag('open_status', params[:open_status]) + haml_concat hidden_field_tag('sort_order', params[:sort_order]) + haml_concat hidden_field_tag('user_id', params[:user_id]) + "" end - def admin - # do we not want this set for non-admins? the param will be viewable in the url - params[:admin_status] || 'all' + # + # PARAM HELPERS + # + + def search_status + if action?(:index) + params[:open_status] || 'open' + else + nil + end end - def order + def search_order params[:sort_order] || 'updated_at_desc' end + # + # LINK HELPERS + # + def link_to_status(new_status) if new_status == "open" label = t(:open_tickets) @@ -21,13 +42,13 @@ module TicketsHelper elsif new_status == "all" label = t(:all_tickets) end - link_to label, tickets_path(:open_status => new_status, :admin_status => admin, :sort_order => order) + link_to label, auto_tickets_path(:open_status => new_status, :sort_order => search_order) end def link_to_order(order_field) - if order.start_with?(order_field) + if search_order.start_with?(order_field) # link for currently-filtered field. Link to other direction of this field. - if order.end_with? 'asc' + if search_order.end_with? 'asc' direction = 'desc' icon_direction = 'up' else @@ -47,7 +68,7 @@ module TicketsHelper label = t(:created) end - link_to :sort_order => order_field + '_at_' + direction, :open_status => status, :admin_status => admin do + link_to auto_tickets_path(:sort_order => order_field + '_at_' + direction, :open_status => search_status) do arrow + label end end diff --git a/help/app/views/tickets/_admin-nav.html.haml b/help/app/views/tickets/_admin-nav.html.haml deleted file mode 100644 index 3e65e44..0000000 --- a/help/app/views/tickets/_admin-nav.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.btn-group - %span.btn.disabled= t(:admin) + ':' - = link_to t(:my_tickets), {:admin_status => 'mine', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'mine')].join(' ') - = link_to t(:all_tickets), {:admin_status => 'all', :open_status => status, :sort_order => order}, :class => ['btn', ("active" if admin == 'all')].join(' ') -%br \ No newline at end of file diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 151d6f1..9c981a3 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -14,6 +14,7 @@ - regarding_user_link = '' = form_for @ticket do |f| + = hidden_ticket_fields %p.first - if @ticket.is_open? %span.label.label-info= t(:open) @@ -40,5 +41,5 @@ - else = f.submit t(:open), :class => 'btn' - if admin? - = link_to t(:destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn' + = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml index de54259..ff136f3 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -2,6 +2,7 @@ -# for posting a new comment to an existing ticket. -# = simple_form_for @ticket, :html => {:class => 'slim'} do |f| + = hidden_ticket_fields = f.simple_fields_for :comments, @comment, :wrapper => :none, :html => {:class => 'slim'} do |c| = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? @@ -9,4 +10,4 @@ = f.button :submit, t(:post_reply), :class => 'btn-primary' - if logged_in? && @ticket.is_open = f.button :submit, t(:reply_and_close) - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), auto_tickets_path, :class => :btn diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml index a2ddb72..b235350 100644 --- a/help/app/views/tickets/_order-nav.html.haml +++ b/help/app/views/tickets/_order-nav.html.haml @@ -1,5 +1,5 @@ %ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} - %li{:class=> ("active" if order.start_with? 'created_at' )} + %li{:class=> ("active" if search_order.start_with? 'created_at' )} = link_to_order('created') - %li{:class=> ("active" if order.start_with? 'updated_at' )} + %li{:class=> ("active" if search_order.start_with? 'updated_at' )} = link_to_order('updated') diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml index c8279ed..8e51497 100644 --- a/help/app/views/tickets/_status-nav.html.haml +++ b/help/app/views/tickets/_status-nav.html.haml @@ -1,10 +1,10 @@ %ul.nav.nav-tabs - if logged_in? - %li{:class => ("active" if status == 'open')} + %li{:class => ("active" if search_status == 'open')} = link_to_status 'open' - %li{:class => ("active" if status == 'closed')} + %li{:class => ("active" if search_status == 'closed')} = link_to_status 'closed' - %li{:class => ("active" if status == 'all')} + %li{:class => ("active" if search_status == 'all')} = link_to_status 'all' %li{:class => ("active" if action?(:new))} - = link_to icon(:plus, :black) + t(:new_ticket), new_ticket_path + = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml index a5cf8be..45ebfb2 100644 --- a/help/app/views/tickets/_table-nav.html.haml +++ b/help/app/views/tickets/_table-nav.html.haml @@ -1,6 +1,3 @@ -- if admin? - = render 'tickets/admin-nav' - - unless action?(:new) = render 'tickets/order-nav' = render 'tickets/status-nav' diff --git a/help/app/views/tickets/_ticket.html.haml b/help/app/views/tickets/_ticket.html.haml index 9a1e899..a064c4e 100644 --- a/help/app/views/tickets/_ticket.html.haml +++ b/help/app/views/tickets/_ticket.html.haml @@ -1,5 +1,6 @@ +- url = auto_ticket_path(ticket) %tr - %td= link_to ticket.title, ticket - %td= link_to ticket.created_at.to_s(:short), ticket - %td= link_to ticket.updated_at.to_s(:short), ticket + %td= link_to ticket.title, url + %td= link_to ticket.created_at.to_s(:short), url + %td= link_to ticket.updated_at.to_s(:short), url %td= ticket.commenters diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index f4597a7..1b32dc1 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,3 +1,5 @@ +- @show_navigation = !params[:user_id].nil? + = render 'tickets/table-nav' %table.table.table-striped.table-bordered diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 7d3f76c..04b091c 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,6 +1,9 @@ +- @show_navigation = !params[:user_id].nil? + = render 'tickets/table-nav' = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| + = hidden_ticket_fields = f.input :title, :label => t(:subject) - if user = f.input :email, input_html: {value: user.email_address} @@ -15,4 +18,6 @@ .form-actions = f.button :submit, :class => 'btn-primary' - if logged_in? - = link_to t(:cancel), tickets_path, :class => :btn + = link_to t(:cancel), auto_tickets_path, :class => :btn + - else + = link_to t(:cancel), root_path, :class => 'btn' \ No newline at end of file diff --git a/help/app/views/tickets/show.html.haml b/help/app/views/tickets/show.html.haml index ddd4e9f..bfdb773 100644 --- a/help/app/views/tickets/show.html.haml +++ b/help/app/views/tickets/show.html.haml @@ -1,3 +1,5 @@ +- @show_navigation = !params[:user_id].nil? + .ticket = render 'tickets/edit_form' %table.table.table-striped.table-bordered diff --git a/help/config/routes.rb b/help/config/routes.rb index 86a9201..8f3241c 100644 --- a/help/config/routes.rb +++ b/help/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do - - resources :tickets, :only => [:new, :create, :index, :show, :update, :destroy] - #resources :ticket, :only => [:show] + resources :tickets, :except => :edit + resources :users do + resources :tickets, :except => :edit + end end -- cgit v1.2.3 From 01bba1b43129340d01132234f0cc7d673dbd6a5c Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:20:06 -0700 Subject: removed commented out code from ticket.rb --- help/app/models/ticket.rb | 101 +++++++++++----------------------------------- 1 file changed, 24 insertions(+), 77 deletions(-) diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb index 738487a..09bc64d 100644 --- a/help/app/models/ticket.rb +++ b/help/app/models/ticket.rb @@ -1,49 +1,30 @@ +# +# TODO: thought i should reverse keys for descending, but that didn't work. +# look into whether that should be tweaked, and whether it works okay with +# pagination (seems to now...) +# +# TODO: better validation of email +# +# TODO: don't hardcode strings 'unknown user' and 'unauthenticated user' +# class Ticket < CouchRest::Model::Base - #include ActiveModel::Validations - use_database "tickets" - #require 'securerandom' -=begin - title - created_at - updated_at - email_address - user - user_verified? - admins (list of admins who have commented on the ticket) - code (secret url) -=end - - #belongs_to :user #from leap_web_users. doesn't necessarily belong to a user though - property :created_by, String, :protected => true #Integer #nil unless user was authenticated for ticket creation, #THIS should not be changed after being set - property :regarding_user, String#Integer # form cannot be submitted if they type in a username w/out corresponding ID. this field can be nil. for authenticated ticket creation by non-admins, should this just automatically be set to be same as created_by? or maybe we don't use this field unless created_by is nil? - #also, both created_by and regarding_user could be nil---say user forgets username, or has general question - property :title, String - property :email, String #verify - - #property :user_verified, TrueClass, :default => false #will be true exactly when user is set - #admins - #property :code, String, :protected => true # only should be set if created_by is nil #instead we will just use couchdb ID - property :is_open, TrueClass, :default => true - property :comments, [TicketComment] + + property :created_by, String, :protected => true # nil for anonymous tickets, should never be changed + property :regarding_user, String # may be nil or valid username + property :title, String + property :email, String + property :is_open, TrueClass, :default => true + property :comments, [TicketComment] timestamps! - #before_validation :set_created_by, :set_code, :set_email, :on => :create before_validation :set_email, :set_regarding_user, :on => :create - - #named_scope :open, :conditions => {:is_open => true} #?? - design do - #TODO--clean this all up - #view :by_is_open - #view :by_created_by - view :by_updated_at view :by_created_at - #view :by_is_open_and_created_by view :by_is_open_and_created_at view :by_is_open_and_updated_at @@ -52,21 +33,9 @@ class Ticket < CouchRest::Model::Base end validates :title, :presence => true - #validates :comments, :presence => true #do we want it like this? - - - # html5 has built-in validation which isn't ideal, as it says 'please enter an email address' for invalid email addresses, which implies an email address is required, and it is not. validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ - #TODO: - #def set_created_by - # self.created_by = User.current if User.current - #end - def self.for_user(user, options = {}, is_admin = false) - - # TODO: thought i should reverse keys for descending, but that didn't work. look into whether that should be tweaked, and whether it works okay with pagination (seems to now...) - options[:user_id] = user.id options[:is_admin] = is_admin @@ -74,41 +43,24 @@ class Ticket < CouchRest::Model::Base @selection.tickets end - #def self.tickets_by_commenter(user_id)#, options = {}) - # Ticket.includes_post_by_and_updated_at.startkey([user_id, 0]).endkey([user_id, Time.now]) - #end - def is_creator_validated? !!created_by end -=begin - def set_code #let's not use this---can use same show url - # ruby 1.9 provides url-safe option---this is not necessarily url-safe - self.code = SecureRandom.hex(8) if !is_creator_validated? - end -=end - - def set_email self.email = nil if self.email == "" - # in controller set to be current users email if that exists end def set_regarding_user self.regarding_user = nil if self.regarding_user == "" end - #not saving with close and reopen, as we will save in update when they are called. - #TODO: not sure if we should bother with these: def close self.is_open = false - #save end def reopen self.is_open = true - #save end def commenters @@ -118,20 +70,21 @@ class Ticket < CouchRest::Model::Base if user = User.find(comment.posted_by) commenters << user.login if user and !commenters.include?(user.login) else - commenters << 'unknown user' if !commenters.include?('unknown user') #todo don't hardcode string 'unknown user' + commenters << 'unknown user' if !commenters.include?('unknown user') end else - commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') #todo don't hardcode string 'unauthenticated user' + commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') end end commenters.join(', ') end + # + # update comments. User should be set by controller. + # def comments_attributes=(attributes) - if attributes # could be empty as we will empty if nothing was typed in - comment = TicketComment.new(attributes.values.first) #TicketComment.new(attributes) - #comment.posted_by = User.current.id if User.current #we want to avoid User.current, and current_user won't work here. instead will set in tickets_controller - # what about: comment.posted_by = self.updated_by (will need to add ticket.updated_by) + if attributes + comment = TicketComment.new(attributes.values.first) comment.posted_at = Time.now comments << comment end @@ -144,11 +97,5 @@ class Ticket < CouchRest::Model::Base def regarding_user_actual_user User.find_by_login(self.regarding_user) end -=begin - def validate - if email_address and not email_address.strip =~ RFC822::EmailAddress - errors.add 'email', 'contains an invalid address' - end - end -=end + end -- cgit v1.2.3 From 33f55eed348769e1d14b283ec36b8f1bfc2d3c98 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 3 Jul 2013 11:21:04 -0700 Subject: fixed security vulnerability with ticket searching --- help/app/models/ticket.rb | 5 +---- help/app/models/ticket_selection.rb | 41 ++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb index 09bc64d..8066d0d 100644 --- a/help/app/models/ticket.rb +++ b/help/app/models/ticket.rb @@ -35,10 +35,7 @@ class Ticket < CouchRest::Model::Base validates :title, :presence => true validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ - def self.for_user(user, options = {}, is_admin = false) - options[:user_id] = user.id - options[:is_admin] = is_admin - + def self.search(options = {}) @selection = TicketSelection.new(options) @selection.tickets end diff --git a/help/app/models/ticket_selection.rb b/help/app/models/ticket_selection.rb index bebe5fc..74d5b78 100644 --- a/help/app/models/ticket_selection.rb +++ b/help/app/models/ticket_selection.rb @@ -1,10 +1,20 @@ class TicketSelection + # + # supported options: + # + # user_id: id of the user (uuid string) + # open_status: open | closed | all + # sort_order: updated_at_desc | updated_at_asc | created_at_desc | created_at_asc + # admin_status: mine | all + # is_admin: true | false + # def initialize(options = {}) - @options = options - @options[:open_status] ||= 'open' - @options[:sort_order] ||= 'updated_at_desc' - + @user_id = options[:user_id].gsub /[^a-z0-9]/, '' + @open_status = allow options[:open_status], 'open', 'closed', 'all' + @sort_order = allow options[:sort_order], 'updated_at_desc', 'updated_at_asc', 'created_at_desc', 'created_at_asc' + @admin_status = allow options[:admin_status], 'mine', 'all' + @is_admin = allow options[:is_admin], false, true end def tickets @@ -13,25 +23,32 @@ class TicketSelection protected + def allow(source, *allowed) + if allowed.include?(source) + source + else + allowed.first + end + end def finder_method method = 'by_' method += 'includes_post_by_and_' if only_mine? - method += 'is_open_and_' if @options[:open_status] != 'all' - method += @options[:sort_order].sub(/_(de|a)sc$/, '') + method += 'is_open_and_' if @open_status != 'all' + method += @sort_order.sub(/_(de|a)sc$/, '') end def startkey startkeys = [] - startkeys << @options[:user_id] if only_mine? - startkeys << (@options[:open_status] == 'open') if @options[:open_status] != 'all' + startkeys << @user_id if only_mine? + startkeys << (@open_status == 'open') if @open_status != 'all' startkeys << 0 - startkeys = startkeys.join if startkeys.length == 1 #want string not array if just one thing in array + startkeys = startkeys.join if startkeys.length == 1 # want string not array if just one thing in array startkeys end def endkey - endtime = Time.now + 2.days #TODO. this obviously isn't ideal + endtime = Time.now + 2.days # TODO. this obviously isn't ideal if self.startkey.is_a?(Array) endkeys = self.startkey endkeys.pop @@ -43,12 +60,12 @@ class TicketSelection def order # we have defined the ascending method to return the view itself: - (@options[:sort_order].end_with? 'desc') ? 'descending' : 'ascending' + (@sort_order.end_with? 'desc') ? 'descending' : 'ascending' end def only_mine? - !@options[:is_admin] or (@options[:admin_status] == 'mine') + !@is_admin || @admin_status == 'mine' end end -- cgit v1.2.3 From 89ad6bd802f9e57c687e8cdb8593c3984e2fbd1b Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:33:09 -0700 Subject: fix user typeahead --- users/app/assets/javascripts/users.js | 4 ++-- users/app/controllers/v1/users_controller.rb | 12 +++++++++++- users/app/views/users/index.html.haml | 13 ++++++------- users/config/routes.rb | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js index eed1961..1d05692 100644 --- a/users/app/assets/javascripts/users.js +++ b/users/app/assets/javascripts/users.js @@ -10,7 +10,7 @@ }; poll_users = function(query, process) { - return $.get("/users.json", { + return $.get("/1/users.json", { query: query }).done(process); }; @@ -66,7 +66,7 @@ $('#new_session').submit(srp.login); $('#update_login_and_password').submit(prevent_default); $('#update_login_and_password').submit(srp.update); - return $('.user.typeahead').typeahead({ + return $('#user-typeahead').typeahead({ source: poll_users }); }); diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e7516bc..e117fc7 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -2,11 +2,21 @@ module V1 class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token - before_filter :authorize, :only => [:update] before_filter :fetch_user, :only => [:update] + before_filter :authorize, :only => [:update] + before_filter :authorize_admin, :only => [:index] respond_to :json + def index + if params[:query] + @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + respond_with @users.map(&:login).sort + else + render :json => {'error' => 'query required', 'status' => :unprocessable_entity} + end + end + def create @user = User.create(params[:user]) respond_with @user # return ID instead? diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 254e177..fc1001e 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -2,13 +2,12 @@ = form_tag users_path, :method => :get, :class => "form-search" do .input-append - = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off - %button.btn{:type => :submit} Search + = text_field_tag :query, params[:query], :id => 'user-typeahead', :class => "search-query", :autocomplete => :off + %button.btn{:type => :submit}= t(:search) -%table.table.table-hover +%table.table.table-striped %tr - %th Login - %th Created - %th Action + %th= t(:username) + %th= t(:created) + %th= t(:updated) = render @users.all - diff --git a/users/config/routes.rb b/users/config/routes.rb index 9eff2a1..693ae7a 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update, :destroy] + resources :users, :only => [:create, :update, :destroy, :index] end get "login" => "sessions#new", :as => "login" -- cgit v1.2.3 From 03fc85ad20e91964267dfcdaab9e3036c5702689 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:06 -0700 Subject: users - make a nice overview page (well, nice enough) and better users index/search. --- users/app/controllers/users_controller.rb | 9 +++++++-- users/app/views/overviews/show.html.haml | 27 +++++++++++++++------------ users/app/views/users/_user.html.haml | 12 +++--------- users/config/locales/en.yml | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 0dbf641..81336be 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -12,11 +12,16 @@ class UsersController < UsersBaseController def index if params[:query] - @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + if @user = User.find_by_login(params[:query]) + redirect_to user_overview_url(@user) + return + else + @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ) + end else @users = User.by_created_at.descending end - @users = @users.limit(APP_CONFIG[:pagination_size]) + @users = @users.limit(100) end def new diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml index eda9899..b8ad814 100644 --- a/users/app/views/overviews/show.html.haml +++ b/users/app/views/overviews/show.html.haml @@ -1,15 +1,18 @@ -%p - Username: - = @user.login +.overview -%p - User since: - = @user.created_at + %h2.first= t(:overview_welcome, :username => @user.login) -%p - Last update: - = @user.updated_at + - if admin? + %p + = t(:created) + = @user.created_at + %br + = t(:updated) + = @user.updated_at -%p - Quota: - N/A \ No newline at end of file + %p= t(:overview_intro) + + %ul.unstyled + %li= icon('user') + link_to(t(:overview_account), edit_user_path(@user)) + %li= icon('envelope') + link_to(t(:overview_email), edit_user_email_settings_path(@user)) + %li= icon('question-sign') + link_to(t(:overview_tickets), user_tickets_path(@user)) diff --git a/users/app/views/users/_user.html.haml b/users/app/views/users/_user.html.haml index ca03d34..990d9cf 100644 --- a/users/app/views/users/_user.html.haml +++ b/users/app/views/users/_user.html.haml @@ -1,10 +1,4 @@ %tr - %td= link_to user.login, user - %td= time_ago_in_words(user.created_at) + " ago" - %td - = link_to edit_user_path(user), :class => "btn btn-mini btn-primary" do - %i.icon-edit.icon-white - Edit - = link_to user_path(user), :method => :delete, :class => "btn btn-danger btn-mini" do - %i.icon-remove.icon-white - Remove + %td= link_to user.login, user_overview_path(user) + %td= l(user.created_at, :format => :short) + %td= l(user.updated_at, :format => :short) diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 63ac692..b880887 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -29,6 +29,20 @@ en: advanced_options: "Advanced Options" not_authorized: "Sorry, but you are not authorized to perform that action." not_authorized_login: "Please log in to perform that action." + search: "Search" + + # + # overview + # + overview_welcome: "Welcome %{username}." + overview_intro: "From this user control panel, you can:" + overview_tickets: "Create and check support tickets." + overview_email: "Modify email settings." + overview_account: "Change your password or delete your account." + + # + # rails + # activemodel: models: user: -- cgit v1.2.3 From 2d36a6b68099af39f2bc84a32d67b83f6041ca28 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:29 -0700 Subject: test - we allow updating of username via api now --- users/test/integration/api/account_flow_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb index 1698105..2e45367 100644 --- a/users/test/integration/api/account_flow_test.rb +++ b/users/test/integration/api/account_flow_test.rb @@ -88,10 +88,11 @@ class AccountFlowTest < RackTest server_auth = @srp.authenticate(self) test_public_key = 'asdlfkjslfdkjasd' original_login = @user.login - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => 'failed_login_name'}, :format => :json + new_login = 'zaph' + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => new_login}, :format => :json @user.reload assert_equal test_public_key, @user.public_key - assert_equal original_login, @user.login + assert_equal new_login, @user.login # eventually probably want to remove most of this into a non-integration functional test # should not overwrite public key: put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:blee => :blah}, :format => :json -- cgit v1.2.3 From adacb11c8ff6395f38c3c05bea4e6d276285118f Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:35:49 -0700 Subject: help - fix ticket navigation & links (use @user, not user). --- app/views/layouts/_header.html.haml | 6 ++++-- app/views/layouts/_navigation.html.haml | 8 ++++---- app/views/layouts/application.html.haml | 2 +- help/app/views/tickets/_order-nav.html.haml | 5 ----- help/app/views/tickets/_status-nav.html.haml | 10 ---------- help/app/views/tickets/_table-nav.html.haml | 4 ---- help/app/views/tickets/_tabs.html.haml | 23 +++++++++++++++++++++++ help/app/views/tickets/index.html.haml | 2 +- help/app/views/tickets/new.html.haml | 15 +++++++++++---- 9 files changed, 44 insertions(+), 31 deletions(-) delete mode 100644 help/app/views/tickets/_order-nav.html.haml delete mode 100644 help/app/views/tickets/_status-nav.html.haml delete mode 100644 help/app/views/tickets/_table-nav.html.haml create mode 100644 help/app/views/tickets/_tabs.html.haml diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 854ab40..b459545 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -4,6 +4,8 @@ = link_to t(:users), users_path %li{:class => ("active" if controller?('tickets') && !params[:user_id])} = link_to t(:tickets), tickets_path -- if user && @show_navigation + %li + = link_to t(:logout), logout_path, :method => :delete +- if @user && @show_navigation .user_heading - = user.email_address + = @user.email_address diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index cbe6d3a..b42c1fe 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,6 +1,6 @@ %ul.nav.sidenav - = link_to_navigation t(:overview), user_overview_path(user), :active => controller?(:overviews) - = link_to_navigation t(:account_settings), edit_user_path(user), :active => controller?(:users) - = link_to_navigation t(:email_settings), edit_user_email_settings_path(user), :active => controller?(:email_settings) - = link_to_navigation t(:support_tickets), auto_tickets_path(user), :active => controller?(:tickets) + = link_to_navigation t(:overview), user_overview_path(@user), :active => controller?(:overviews) + = link_to_navigation t(:account_settings), edit_user_path(@user), :active => controller?(:users) + = link_to_navigation t(:email_settings), edit_user_email_settings_path(@user), :active => controller?(:email_settings) + = link_to_navigation t(:support_tickets), auto_tickets_path(@user), :active => controller?(:tickets) = link_to_navigation t(:logout), logout_path, :method => :delete diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index db612b7..d5adca9 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,4 +1,4 @@ -- @show_navigation = true if @show_navigation.nil? +- @show_navigation = true if @show_navigation.nil? && logged_in? !!! %html %head diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml deleted file mode 100644 index b235350..0000000 --- a/help/app/views/tickets/_order-nav.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%ul.nav.nav-pills.pull-right{:style => 'margin-bottom: 0'} - %li{:class=> ("active" if search_order.start_with? 'created_at' )} - = link_to_order('created') - %li{:class=> ("active" if search_order.start_with? 'updated_at' )} - = link_to_order('updated') diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml deleted file mode 100644 index 8e51497..0000000 --- a/help/app/views/tickets/_status-nav.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%ul.nav.nav-tabs - - if logged_in? - %li{:class => ("active" if search_status == 'open')} - = link_to_status 'open' - %li{:class => ("active" if search_status == 'closed')} - = link_to_status 'closed' - %li{:class => ("active" if search_status == 'all')} - = link_to_status 'all' - %li{:class => ("active" if action?(:new))} - = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml deleted file mode 100644 index 45ebfb2..0000000 --- a/help/app/views/tickets/_table-nav.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- unless action?(:new) - = render 'tickets/order-nav' -= render 'tickets/status-nav' - diff --git a/help/app/views/tickets/_tabs.html.haml b/help/app/views/tickets/_tabs.html.haml new file mode 100644 index 0000000..b7b5d3a --- /dev/null +++ b/help/app/views/tickets/_tabs.html.haml @@ -0,0 +1,23 @@ +-# +-# SORT ORDER TABS +-# +- unless action?(:new) + %ul.nav.nav-pills.pull-right.slim + %li{:class=> ("active" if search_order.start_with? 'created_at')} + = link_to_order('created') + %li{:class=> ("active" if search_order.start_with? 'updated_at')} + = link_to_order('updated') + +-# +-# STATUS FILTER TABS +-# +%ul.nav.nav-tabs + - if logged_in? + %li{:class => ("active" if search_status == 'open')} + = link_to_status 'open' + %li{:class => ("active" if search_status == 'closed')} + = link_to_status 'closed' + %li{:class => ("active" if search_status == 'all')} + = link_to_status 'all' + %li{:class => ("active" if action?(:new))} + = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml index 1b32dc1..c02a326 100644 --- a/help/app/views/tickets/index.html.haml +++ b/help/app/views/tickets/index.html.haml @@ -1,6 +1,6 @@ - @show_navigation = !params[:user_id].nil? -= render 'tickets/table-nav' += render 'tickets/tabs' %table.table.table-striped.table-bordered %thead diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 04b091c..4d35659 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -1,13 +1,20 @@ - @show_navigation = !params[:user_id].nil? -= render 'tickets/table-nav' += render 'tickets/tabs' + +- if admin? && @user + - email = @user.email_address + - regarding = @user.login +- elsif logged_in? + - email = current_user.email_address + - regarding = current_user.login = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| = hidden_ticket_fields = f.input :title, :label => t(:subject) - - if user - = f.input :email, input_html: {value: user.email_address} - = f.input :regarding_user, input_html: {value: user.login} + - if logged_in? + = f.input :email, input_html: {value: email} + = f.input :regarding_user, input_html: {value: regarding} - else = f.input :email = f.input :regarding_user -- cgit v1.2.3 From 40830b4b1fa33b9e26dbd500fc08b4b76b58011b Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:36:08 -0700 Subject: minor changes to css and home page. --- app/assets/stylesheets/leap.scss | 8 ++++++++ app/views/home/index.html.haml | 7 +------ core/app/helpers/core_helper.rb | 13 +++++++++++++ core/app/helpers/snippet_helper.rb | 11 ----------- 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 core/app/helpers/core_helper.rb delete mode 100644 core/app/helpers/snippet_helper.rb diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 792aa3c..6268b3b 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -184,3 +184,11 @@ input, textarea { } } } + +// +// USERS +// + +.overview li { + padding: 6px 0; +} \ No newline at end of file diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 9da66a1..8c90436 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -9,9 +9,4 @@ .row-fluid %hr %p - Try to fetch a - = link_to "cert", cert_path - - %p - Create a - = link_to "ticket", new_ticket_path + = link_to "fetch a cert", cert_path diff --git a/core/app/helpers/core_helper.rb b/core/app/helpers/core_helper.rb new file mode 100644 index 0000000..a496144 --- /dev/null +++ b/core/app/helpers/core_helper.rb @@ -0,0 +1,13 @@ +# +# Misc. helpers needed throughout. +# +module CoreHelper + + # + # insert common buttons (download, login, etc) + # + def home_page_buttons + render 'common/home_page_buttons' + end + +end \ No newline at end of file diff --git a/core/app/helpers/snippet_helper.rb b/core/app/helpers/snippet_helper.rb deleted file mode 100644 index 6fee454..0000000 --- a/core/app/helpers/snippet_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# -# various html snippets we use throughout. -# - -module SnippetHelper - - def home_page_buttons - render 'common/home_page_buttons' - end - -end \ No newline at end of file -- cgit v1.2.3 From 290d367ddb064c0aea4e0447441776fd69e29f6c Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:45:41 -0700 Subject: allow forms with blank email forward. --- users/app/controllers/email_settings_controller.rb | 9 ++++++++- users/app/models/user.rb | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb index 0261b47..f7d85be 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -8,7 +8,7 @@ class EmailSettingsController < UsersBaseController end def update - @user.attributes = params[:user] + @user.attributes = cleanup_params(params[:user]) if @user.changed? if @user.save flash[:notice] = t(:changes_saved) @@ -31,4 +31,11 @@ class EmailSettingsController < UsersBaseController redirect_to edit_user_email_settings_url(@user) end + def cleanup_params(user) + if !user['email_forward'].nil? && user['email_forward'].empty? + user.delete('email_forward') # don't allow "" as an email forward + end + user + end + end diff --git a/users/app/models/user.rb b/users/app/models/user.rb index 5c849f0..3459520 100644 --- a/users/app/models/user.rb +++ b/users/app/models/user.rb @@ -42,6 +42,7 @@ class User < CouchRest::Model::Base :format => { :with => /.{8}.*/, :message => "needs to be at least 8 characters long" } validates :email_forward, + :allow_blank => true, :format => { :with => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/, :message => "needs to be a valid email address"} timestamps! -- cgit v1.2.3 From 64bacc45ea1a023b154b07ec0790f762a79d20d5 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 02:44:11 -0700 Subject: user tests -- user update has been moved entirely to api controller, so fix tests to reflect this. --- users/app/controllers/users_controller.rb | 5 -- users/app/controllers/v1/users_controller.rb | 1 - users/config/routes.rb | 2 +- users/test/functional/users_controller_test.rb | 63 -------------------- users/test/functional/v1/users_controller_test.rb | 70 +++++++++++++++++++++++ users/test/support/auth_test_helper.rb | 16 ++++-- 6 files changed, 83 insertions(+), 74 deletions(-) create mode 100644 users/test/functional/v1/users_controller_test.rb diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 81336be..5d45db5 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -28,11 +28,6 @@ class UsersController < UsersBaseController @user = User.new end - def create - @user = User.create(params[:user]) - respond_with @user - end - def show end diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e117fc7..fda56f2 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -23,7 +23,6 @@ module V1 end def update - @user = User.find_by_param(params[:id]) @user.update_attributes params[:user] if @user.valid? flash[:notice] = t(:user_updated_successfully) diff --git a/users/config/routes.rb b/users/config/routes.rb index 693ae7a..b6d583e 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -13,7 +13,7 @@ Rails.application.routes.draw do resources :sessions, :only => [:new, :create, :update] get "signup" => "users#new", :as => "signup" - resources :users do + resources :users, :except => [:create, :update] do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ diff --git a/users/test/functional/users_controller_test.rb b/users/test/functional/users_controller_test.rb index 7f81c59..92a5f6c 100644 --- a/users/test/functional/users_controller_test.rb +++ b/users/test/functional/users_controller_test.rb @@ -79,33 +79,6 @@ class UsersControllerTest < ActionController::TestCase assert_redirected_to users_path end - test "should create new user" do - user_attribs = record_attributes_for :user - user = User.new(user_attribs) - User.expects(:create).with(user_attribs).returns(user) - - - post :create, :user => user_attribs, :format => :json - - - assert_nil session[:user_id] - assert_json_response user - assert_response :success - end - - test "should redirect to signup form on failed attempt" do - user_attribs = record_attributes_for :user - user_attribs.slice!('login') - user = User.new(user_attribs) - assert !user.valid? - User.expects(:create).with(user_attribs).returns(user) - - post :create, :user => user_attribs, :format => :json - - assert_json_error user.errors.messages - assert_response 422 - end - test "should get edit view" do user = find_record :user @@ -115,34 +88,6 @@ class UsersControllerTest < ActionController::TestCase assert_equal user, assigns[:user] end - test "user can change settings" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - user.expects(:attributes=).with(changed_attribs) - user.expects(:changed?).returns(true) - user.expects(:save).returns(true) - - login user - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_equal user, assigns[:user] - assert_response 204 - assert_equal " ", @response.body - end - - # Eventually, admin will be able to update some user fields - test "admin cannot update user" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - - login :is_admin? => true - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_response :redirect - assert_access_denied - - end - test "admin can destroy user" do user = find_record :user user.expects(:destroy) @@ -189,14 +134,6 @@ class UsersControllerTest < ActionController::TestCase assert_access_denied end - test "admin can autocomplete users" do - login :is_admin? => true - get :index, :format => :json - - assert_response :success - assert assigns(:users) - end - test "admin can search users" do login :is_admin? => true get :index, :query => "a" diff --git a/users/test/functional/v1/users_controller_test.rb b/users/test/functional/v1/users_controller_test.rb new file mode 100644 index 0000000..0d44e50 --- /dev/null +++ b/users/test/functional/v1/users_controller_test.rb @@ -0,0 +1,70 @@ +require 'test_helper' + +class V1::UsersControllerTest < ActionController::TestCase + + test "user can change settings" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login user + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + assert_equal " ", @response.body + end + + test "admin can update user" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login :is_admin? => true + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + end + + test "user cannot update other user" do + user = find_record :user + login + put :update, :user => record_attributes_for(:user_with_settings), :id => user.id, :format => :json + assert_access_denied + end + + test "should create new user" do + user_attribs = record_attributes_for :user + user = User.new(user_attribs) + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_nil session[:user_id] + assert_json_response user + assert_response :success + end + + test "should redirect to signup form on failed attempt" do + user_attribs = record_attributes_for :user + user_attribs.slice!('login') + user = User.new(user_attribs) + assert !user.valid? + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_json_error user.errors.messages + assert_response 422 + end + + test "admin can autocomplete users" do + login :is_admin? => true + get :index, :query => 'a', :format => :json + + assert_response :success + assert assigns(:users) + end + +end diff --git a/users/test/support/auth_test_helper.rb b/users/test/support/auth_test_helper.rb index c0fcf3a..555b5db 100644 --- a/users/test/support/auth_test_helper.rb +++ b/users/test/support/auth_test_helper.rb @@ -20,10 +20,18 @@ module AuthTestHelper def assert_access_denied(denied = true, logged_in = true) if denied - assert_equal({:alert => "Not authorized"}, flash.to_hash) - # todo: eventually probably eliminate separate conditions - assert_redirected_to login_path if !logged_in - assert_redirected_to root_path if logged_in + if @response.content_type == 'application/json' + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + else + if logged_in + assert_equal({:alert => I18n.t(:not_authorized)}, flash.to_hash) + assert_redirected_to root_url + else + assert_equal({:alert => I18n.t(:not_authorized_login)}, flash.to_hash) + assert_redirected_to login_url + end + end else assert flash[:alert].blank? end -- cgit v1.2.3 From 89eace3da1cba0b8dad8cc62cc88bf5ddb1faa5e Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:37:44 -0700 Subject: fix ticket tests, get :admin_user factory to work. --- help/test/functional/tickets_controller_test.rb | 13 +++++++------ users/test/factories.rb | 4 +++- users/test/support/stub_record_helper.rb | 9 ++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/help/test/functional/tickets_controller_test.rb b/help/test/functional/tickets_controller_test.rb index f8627d8..6479ba4 100644 --- a/help/test/functional/tickets_controller_test.rb +++ b/help/test/functional/tickets_controller_test.rb @@ -181,23 +181,24 @@ class TicketsControllerTest < ActionController::TestCase test "admin_status mine vs all" do testticket = FactoryGirl.create :ticket + user = find_record :user login :is_admin? => true, :email => nil - get :index, {:admin_status => "all", :open_status => "open"} + get :index, {:open_status => "open"} assert assigns(:all_tickets).include?(testticket) - get :index, {:admin_status => "mine", :open_status => "open"} + get :index, {:user_id => user.id, :open_status => "open"} assert !assigns(:all_tickets).include?(testticket) testticket.destroy end test "commenting on a ticket adds to tickets that are mine" do testticket = FactoryGirl.create :ticket - login :is_admin? => true, :email => nil - - get :index, {:admin_status => "mine", :open_status => "open"} + user = find_record :admin_user + login user + get :index, {:user_id => user.id, :open_status => "open"} assert_difference('assigns[:all_tickets].count') do put :update, :id => testticket.id, :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}}} - get :index, {:admin_status => "mine", :open_status => "open"} + get :index, {:user_id => user.id, :open_status => "open"} end assert assigns(:all_tickets).include?(assigns(:ticket)) diff --git a/users/test/factories.rb b/users/test/factories.rb index 6b094bd..777704b 100644 --- a/users/test/factories.rb +++ b/users/test/factories.rb @@ -13,7 +13,9 @@ FactoryGirl.define do end factory :admin_user do - is_admin? true + after(:build) do |admin| + admin.stubs(:is_admin?).returns(true) + end end end end diff --git a/users/test/support/stub_record_helper.rb b/users/test/support/stub_record_helper.rb index 168a827..8aa1973 100644 --- a/users/test/support/stub_record_helper.rb +++ b/users/test/support/stub_record_helper.rb @@ -1,15 +1,18 @@ module StubRecordHelper - # Will expect find_by_param or find_by_id to be called on klass and + # + # We will stub find_by_param or find_by_id to be called on klass and # return the record given. + # # If no record is given but a hash or nil will create a stub based on # that instead and returns the stub. + # def find_record(factory, attribs_hash = {}) - attribs_hash.reverse_merge!(:id => Random.rand(10000).to_s) + attribs_hash = attribs_hash.reverse_merge(:id => Random.rand(10000).to_s) record = stub_record factory, attribs_hash klass = record.class finder = klass.respond_to?(:find_by_param) ? :find_by_param : :find - klass.expects(finder).with(record.to_param.to_s).returns(record) + klass.stubs(finder).with(record.to_param.to_s).returns(record) return record end -- cgit v1.2.3 From 72db63341a9456c1b9cbd2932c58185b1638f408 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:38:00 -0700 Subject: remove empty readme files --- users/README.rdoc | 3 --- users/Readme.md | 0 2 files changed, 3 deletions(-) delete mode 100644 users/README.rdoc delete mode 100644 users/Readme.md diff --git a/users/README.rdoc b/users/README.rdoc deleted file mode 100644 index 9fb44c1..0000000 --- a/users/README.rdoc +++ /dev/null @@ -1,3 +0,0 @@ -= LeapWebUsers - -This project rocks and uses MIT-LICENSE. \ No newline at end of file diff --git a/users/Readme.md b/users/Readme.md deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3 From 7aa12e35ba7eef298bf3ca0856c7d8960d1a1789 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:39:11 -0700 Subject: add 'blue' to admins in dev mode. --- config/defaults.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/defaults.yml b/config/defaults.yml index 6317082..54c5a23 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -16,7 +16,7 @@ cert_options: &cert_options development: <<: *dev_ca <<: *cert_options - admins: [admin, admin2] + admins: [blue, admin, admin2] domain: example.org secret_token: '550df064dbc5052d9e192b324c1c5a1095c85a2195f88bd6f6829c63b74d8dffa4556494a2e8cc44345a1926be8b6cb17aa4b3f3102d826f5679c3fb57bb7100' pagination_size: 30 -- cgit v1.2.3 From 309bca0b3b2da89cce47da420c87d52e62562d95 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:18:17 -0700 Subject: remove commented out code. --- users/app/views/users/edit.html.haml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index f06df44..08e9dc3 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,6 +1 @@ -= render 'edit' - - -=# user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user -=# render 'cancel_account' - += render 'edit' \ No newline at end of file -- cgit v1.2.3 From 58dc84bb75bf38319b52c821f39fd8017b46ea77 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:23:22 -0700 Subject: fix broken users gemspec --- users/leap_web_users.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/users/leap_web_users.gemspec b/users/leap_web_users.gemspec index c57937f..013b44a 100644 --- a/users/leap_web_users.gemspec +++ b/users/leap_web_users.gemspec @@ -11,8 +11,8 @@ Gem::Specification.new do |s| s.homepage = "http://www.leap.se" s.summary = "User registration and authorization for the leap platform" s.description = "This this plugin for the leap platform provides user signup and login. It uses Secure Remote Password for the authentication." - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] + + s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile"] s.test_files = Dir["test/**/*"] s.add_dependency "leap_web_core", LeapWeb::VERSION -- cgit v1.2.3 From 0d95d40616a6b23d848d1fe69d68a14c69280674 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:26:31 -0700 Subject: redirect to root after user destroy --- users/app/controllers/users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 5d45db5..4ce970b 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -36,7 +36,7 @@ class UsersController < UsersBaseController def destroy @user.destroy - redirect_to admin? ? users_path : login_path + redirect_to admin? ? users_url : root_url end end -- cgit v1.2.3 From 76b26cc26fdb38a96e49702dc5640c91519803df Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:29:04 -0700 Subject: bootswatch is messing up with the bootstrap icons, so i am disabling it for now. --- app/assets/stylesheets/application.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 5a5e900..28206b1 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -4,7 +4,7 @@ @import "head"; // First import journal variables -@import "bootswatch/cerulean/variables"; +// @import "bootswatch/cerulean/variables"; // // import bootstrap. @@ -18,7 +18,7 @@ @import "leap"; // And finally bootswatch style itself -@import "bootswatch/cerulean/bootswatch"; +// @import "bootswatch/cerulean/bootswatch"; // // import custom scss, content to be set in deployment. -- cgit v1.2.3 From cc0ffb5511ee233574495d683178f71885a36b7e Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 5 Jul 2013 15:14:23 -0700 Subject: remove unused user views --- users/app/views/users/_new.html.haml | 7 ------- users/app/views/users/show.html.haml | 35 +---------------------------------- 2 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 users/app/views/users/_new.html.haml diff --git a/users/app/views/users/_new.html.haml b/users/app/views/users/_new.html.haml deleted file mode 100644 index 3d0f2ac..0000000 --- a/users/app/views/users/_new.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- @user ||= User.new -= user_form do |f| - = render :partial => 'users/login_field', :locals => {:f => f} - = render :partial => 'users/password_fields', :locals => {:f => f} - .form-actions - = f.button :submit, :value => t(:signup), :class => 'btn-primary' - = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/show.html.haml b/users/app/views/users/show.html.haml index dc5e015..08e9dc3 100644 --- a/users/app/views/users/show.html.haml +++ b/users/app/views/users/show.html.haml @@ -1,34 +1 @@ -= render 'edit' - --# - .span8.offset1 - %h2= @user.login - .small - = link_to 'edit', edit_user_path(@user) - %dl.offset1 - - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward'] - - fields.each do |field| - %dt - = field.titleize - %dd - = user_field(field) - %dt - =t :email_aliases - %dd - - aliases = @user.email_aliases - - if aliases.present? - %ul.pull-left.unstyled - = render aliases - - else - =t :none - .clearfix - %dt - =t :most_recently_updated_tickets - %dd - - tix = @user.most_recent_tickets - - if tix.present? - %table - %tbody - = render @user.most_recent_tickets - - else - =t :none \ No newline at end of file += render 'edit' \ No newline at end of file -- cgit v1.2.3 From b2124020f123bf7a44b21555e6aefb5699bdcc21 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 5 Jul 2013 15:14:50 -0700 Subject: use :ruby for ruby inside tickets/edit_form partial. --- help/app/views/tickets/_edit_form.html.haml | 30 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 9c981a3..9846a43 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -1,17 +1,21 @@ -- # created by user link -- if @ticket.created_by_user - - created_by = link_to(@ticket.created_by_user.login, user_overview_path(@ticket.created_by_user)) -- else - - created_by = t(:anonymous) +:ruby + # created by user link + if @ticket.created_by_user + created_by = link_to(@ticket.created_by_user.login, user_overview_path(@ticket.created_by_user)) + else + created_by = t(:anonymous) + end -- # regarding user link -- if admin? - - if @ticket.regarding_user_actual_user - - regarding_user_link = link_to @ticket.regarding_user_actual_user.login, user_overview_path(@ticket.regarding_user_actual_user) - - else - - regarding_user_link = "(#{t(:unknown)})" -- else - - regarding_user_link = '' + # regarding user link + if admin? + if @ticket.regarding_user_actual_user + regarding_user_link = link_to @ticket.regarding_user_actual_user.login, user_overview_path(@ticket.regarding_user_actual_user) + else + regarding_user_link = "(#{t(:unknown)})" + end + else + regarding_user_link = '' + end = form_for @ticket do |f| = hidden_ticket_fields -- cgit v1.2.3 From dc98ad8c6445182d60b3f1909e0260ace6fbfca5 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 5 Jul 2013 18:16:24 -0700 Subject: tickets - replace input[type=submit] tags with button[type=submit] tags --- help/app/controllers/tickets_controller.rb | 8 +++----- help/app/views/tickets/_edit_form.html.haml | 7 +++---- help/app/views/tickets/_new_comment_form.html.haml | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index 6fc4024..094612c 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -41,20 +41,18 @@ class TicketsController < ApplicationController end def update - if params[:commit] == t(:close) + if params[:commit] == 'close' @ticket.is_open = false @ticket.save redirect_to_tickets - elsif params[:commit] == t(:open) + elsif params[:commit] == 'open' @ticket.is_open = true @ticket.save redirect_to auto_ticket_path(@ticket) - elsif params[:commit] == t(:cancel) - redirect_to_tickets else @ticket.attributes = cleanup_ticket_params(params[:ticket]) - if params[:commit] == t(:reply_and_close) + if params[:commit] == 'reply_and_close' @ticket.close end diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml index 9846a43..5252c2e 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/help/app/views/tickets/_edit_form.html.haml @@ -39,11 +39,10 @@ = t(:regarding_account) = regarding_user_link = f.text_field :regarding_user - = f.submit t(:save), :class => 'btn' + = f.button t(:save), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'save' - if @ticket.is_open? - = f.submit t(:close), :class => 'btn' + = f.button t(:close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'close' - else - = f.submit t(:open), :class => 'btn' + = f.button t(:open), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'open' - if admin? = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' - diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml index ff136f3..8418e01 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/help/app/views/tickets/_new_comment_form.html.haml @@ -7,7 +7,7 @@ = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true - = f.button :submit, t(:post_reply), :class => 'btn-primary' + = f.button :button, t(:post_reply), :name => 'commit', :class => 'btn-primary', :type => 'submit', :value => 'post_reply' - if logged_in? && @ticket.is_open - = f.button :submit, t(:reply_and_close) + = f.button :button, t(:reply_and_close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'reply_and_close' = link_to t(:cancel), auto_tickets_path, :class => :btn -- cgit v1.2.3 From 84acdd9133dd30d88b42d63b08d25067e168980d Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 6 Jul 2013 17:17:35 -0700 Subject: updated srp_js submodule --- users/app/assets/javascripts/srp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/app/assets/javascripts/srp b/users/app/assets/javascripts/srp index e7a0b83..926a5d5 160000 --- a/users/app/assets/javascripts/srp +++ b/users/app/assets/javascripts/srp @@ -1 +1 @@ -Subproject commit e7a0b830b8f994316a560001a9e7397422b184b1 +Subproject commit 926a5d5960db51903e33c8496487da59f9f41242 -- cgit v1.2.3 From 7dd56114d8bf6749f140835358de4f8ebeaf81ba Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 6 Jul 2013 17:18:20 -0700 Subject: minor - i18n text edit --- core/config/locales/en.yml | 1 + help/app/views/tickets/new.html.haml | 2 +- help/config/locales/en.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index 38724ca..25b377a 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -1,6 +1,7 @@ en: no_such_thing: "No such %{thing}." thing_was_successfully_created: "%{thing} was successfully created." + create_thing: "Create %{thing}" overview: "Overview" user_control_panel: "user control panel" diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml index 4d35659..c0a343d 100644 --- a/help/app/views/tickets/new.html.haml +++ b/help/app/views/tickets/new.html.haml @@ -23,7 +23,7 @@ - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true .form-actions - = f.button :submit, :class => 'btn-primary' + = f.button :submit, :class => 'btn-primary', :value => t(:create_thing, :thing => t(:ticket)) - if logged_in? = link_to t(:cancel), auto_tickets_path, :class => :btn - else diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml index 79e745f..342adea 100644 --- a/help/config/locales/en.yml +++ b/help/config/locales/en.yml @@ -1,6 +1,6 @@ en: access_ticket_text: > - You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. + You can later access this ticket at the URL %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history. support_tickets: "Support Tickets" -- cgit v1.2.3 From 8d158d8472cd4c83ba6fa2f0e4fc080b8936f5de Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 6 Jul 2013 19:02:47 -0700 Subject: rename /img/ to /icons/ so as to not conflict with existing puppet deploy recipes. --- app/assets/stylesheets/leap.scss | 2 +- public/icons/32/arrow-down.png | Bin 0 -> 453 bytes public/img/32/arrow-down.png | Bin 453 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 public/icons/32/arrow-down.png delete mode 100644 public/img/32/arrow-down.png diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 6268b3b..9ed5a9f 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -59,7 +59,7 @@ } .big-icon-arrow-down { - background-image: url(/img/32/arrow-down.png) + background-image: url(/icons/32/arrow-down.png) } // diff --git a/public/icons/32/arrow-down.png b/public/icons/32/arrow-down.png new file mode 100644 index 0000000..3b16e6d Binary files /dev/null and b/public/icons/32/arrow-down.png differ diff --git a/public/img/32/arrow-down.png b/public/img/32/arrow-down.png deleted file mode 100644 index 3b16e6d..0000000 Binary files a/public/img/32/arrow-down.png and /dev/null differ -- cgit v1.2.3 From 315ccfa22f9747a2cd98bccec18011b62b299960 Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 6 Jul 2013 23:10:16 -0700 Subject: minor - remove masthead_noauth partial --- app/views/layouts/_masthead_noauth.html.haml | 3 --- app/views/layouts/application.html.haml | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 app/views/layouts/_masthead_noauth.html.haml diff --git a/app/views/layouts/_masthead_noauth.html.haml b/app/views/layouts/_masthead_noauth.html.haml deleted file mode 100644 index 6bb1943..0000000 --- a/app/views/layouts/_masthead_noauth.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -.title - %span.sitename - = APP_CONFIG[:domain] \ No newline at end of file diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index d5adca9..380f92d 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -11,10 +11,8 @@ = yield(:head) %body #masthead - - if logged_in? + - if params[:controller] != 'home' = render 'layouts/masthead' - - elsif params[:controller] != 'home' - = render 'layouts/masthead_noauth' #main .container-fluid - if logged_in? -- cgit v1.2.3 From 3113f8b814417a896ad5340fda88927733f8ab22 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 7 Jul 2013 00:21:54 -0700 Subject: move icon path -- it turns out /icons/ is used by apache in most default installations, so leap's icons moved to /leap-img/ --- app/assets/stylesheets/leap.scss | 2 +- public/icons/32/arrow-down.png | Bin 453 -> 0 bytes public/leap-img/32/arrow-down.png | Bin 0 -> 453 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 public/icons/32/arrow-down.png create mode 100644 public/leap-img/32/arrow-down.png diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 9ed5a9f..b382773 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -59,7 +59,7 @@ } .big-icon-arrow-down { - background-image: url(/icons/32/arrow-down.png) + background-image: url(/leap-img/32/arrow-down.png) } // diff --git a/public/icons/32/arrow-down.png b/public/icons/32/arrow-down.png deleted file mode 100644 index 3b16e6d..0000000 Binary files a/public/icons/32/arrow-down.png and /dev/null differ diff --git a/public/leap-img/32/arrow-down.png b/public/leap-img/32/arrow-down.png new file mode 100644 index 0000000..3b16e6d Binary files /dev/null and b/public/leap-img/32/arrow-down.png differ -- cgit v1.2.3