diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ace1d8c97..f1cc7dcac 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,5 @@ class ApplicationController < ActionController::Base include Pundit::Authorization - include ActivateNavigation rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized # Prevent CSRF attacks by raising an exception. diff --git a/app/controllers/concerns/activate_navigation.rb b/app/controllers/concerns/activate_navigation.rb deleted file mode 100644 index 3fd6d0464..000000000 --- a/app/controllers/concerns/activate_navigation.rb +++ /dev/null @@ -1,124 +0,0 @@ -require "active_support/concern" - -module ActivateNavigation - extend ActiveSupport::Concern - - included do - helper_method :nav_item_class - helper_method :subnav_item_class - end - - def nav_item_class(key) - initialize_nav - return 'active' if @active_nav_key == key - end - - def subnav_item_class(key) - initialize_nav - return 'active' if @active_subnav_key == key - end - - private - - def initialize_nav - return if @active_nav_key || @active_subnav_key - - @active_nav_key, subnav_map = find_first(nav_item_map) - @active_subnav_key, nop = find_first(subnav_map) - end - - def find_first(item_map) - return unless item_map.is_a?(Hash) - - item_map.find do |key, paths| - match?(paths) - end - end - - def match?(paths) - if paths.is_a?(String) - paths == request.path - - elsif paths.is_a?(Regexp) - paths =~ request.path - - elsif paths.is_a?(Array) - paths.any?{|p| match?(p) } - - elsif paths.is_a?(Hash) - find_first(paths).present? - end - end - - def nav_item_map - @nav_item_map ||= { - 'my-proposals-link' => [ - starts_with_path(Proposal), - starts_with_path(current_event, Proposal) - ], - 'event-website-link' => website_subnav_item_map, - 'event-review-proposals-link' => starts_with_path(current_event, :staff, Proposal), - 'event-selection-link' => selection_subnav_item_map, - 'event-program-link' => program_subnav_item_map, - 'event-schedule-link' => schedule_subnav_item_map, - 'event-dashboard-link' => event_subnav_item_map, - } - end - - def event_subnav_item_map - @event_subnav_item_map ||= { - 'event-staff-dashboard-link' => exact_path(current_event, :staff), - 'event-staff-info-link' => [ - exact_path(:info, current_event, :staff), - exact_path(:edit, current_event, :staff) - ], - 'event-staff-teammates-link' => exact_path(current_event, :staff, Teammate), - 'event-staff-config-link' => exact_path(:config, current_event, :staff), - 'event-staff-guidelines-link' => exact_path(current_event, :staff, :guidelines), - 'event-staff-speaker-emails-link' => starts_with_path(current_event, :staff, :speaker_email_templates), - } - end - - def website_subnav_item_map - @website_subnav_item_map ||= { - 'event-website-configuration-link' => starts_with_path(current_event, :staff, :website), - 'event-pages-link' => exact_path(current_event, :staff, Page) - } - end - - def selection_subnav_item_map - @selection_subnav_item_map ||= { - 'event-program-proposals-selection-link' => [ - starts_with_path(:selection, current_event, :staff, :program, Proposal), - # add_path(:event_staff_program_proposal, current_event, @proposal) - #How to leverage session[:prev_page] here? Considering lamdas - ], - 'event-program-bulk-finalize-link' => starts_with_path(:bulk_finalize, current_event, :staff, :program, Proposal), - 'event-program-proposals-link' => starts_with_path(current_event, :staff, :program, Proposal) - } - end - - def program_subnav_item_map - @program_subnav_item_map ||= { - 'event-program-sessions-link' => starts_with_path(current_event, :staff, ProgramSession), - 'event-program-speakers-link' => starts_with_path(current_event, :staff, :program, Speaker) - } - end - - def schedule_subnav_item_map - @schedule_subnav_item_map ||= { - 'event-schedule-time-slots-link' => exact_path(current_event, :staff, :schedule, TimeSlot), - 'event-schedule-rooms-link' => exact_path(current_event, :staff, :schedule, Room), - 'event-schedule-grid-link' => exact_path(current_event, :staff, :schedule, :grid) - } - end - - def exact_path(*args) - url_for(args << {only_path: true}) unless args.include?(nil) # don't generate the path unless all dependencies are present - end - - def starts_with_path(sym, *deps) - starts_with = exact_path(sym, *deps) - Regexp.new(Regexp.escape(starts_with) + ".*") if starts_with - end -end diff --git a/app/helpers/navbar_helper.rb b/app/helpers/navbar_helper.rb new file mode 100644 index 000000000..07265d5c6 --- /dev/null +++ b/app/helpers/navbar_helper.rb @@ -0,0 +1,63 @@ +module NavbarHelper + using Module.new { + refine NavbarHelper do + def path_for(*args) + url_for(args << {only_path: true}) + end + end + } + + NAV_ITEM_MAP = { + my_proposals: ->(pp) { [->(p) { p.start_with?(path_for(Proposal)) }, ->(p) { p.start_with?(path_for(current_event, Proposal)) }].any? { it.call(pp) } }, + event_review_proposals: ->(p) { p.start_with?(path_for(current_event, :staff, Proposal)) }, + event_selection: { + event_program_proposals_selection: ->(p) { p.start_with?(path_for(:selection, current_event, :staff, :program, Proposal)) }, + event_program_bulk_finalize: ->(p) { p.start_with?(path_for(:bulk_finalize, current_event, :staff, :program, Proposal)) }, + event_program_proposals: ->(p) { p.start_with?(path_for(current_event, :staff, :program, Proposal)) } + }, + event_program: { + event_program_sessions: ->(p) { p.start_with?(path_for(current_event, :staff, ProgramSession)) }, + event_program_speakers: ->(p) { p.start_with?(path_for(current_event, :staff, :program, Speaker)) } + }, + event_schedule: { + event_schedule_time_slots: ->(p) { p == path_for(current_event, :staff, :schedule, TimeSlot) }, + event_schedule_rooms: ->(p) { p == path_for(current_event, :staff, :schedule, Room) }, + event_schedule_grid: ->(p) { p == path_for(current_event, :staff, :schedule, :grid) } + }, + event_dashboard: { + event_staff_dashboard: ->(p) { p == path_for(current_event, :staff) }, + event_staff_info: ->(pp) { [->(p) { p == path_for(:info, current_event, :staff) }, ->(p) { p == path_for(:edit, current_event, :staff) }].any? { it.call(pp) } }, + event_staff_teammates: ->(p) { p == path_for(current_event, :staff, Teammate) }, + event_staff_config: ->(p) { p == path_for(:config, current_event, :staff) }, + event_staff_guidelines: ->(p) { p == path_for(current_event, :staff, :guidelines) }, + event_staff_speaker_emails: ->(p) { p.start_with?(path_for(current_event, :staff, :speaker_email_templates)) } + }, + event_website: { + event_website_configuration: ->(p) { p.start_with?(path_for(current_event, :staff, :website)) }, + event_pages: ->(p) { p == path_for(current_event, :staff, Page) } + } + }.freeze + + private + + def nav_item_class(key) + unless defined?(@active_nav_key) + NAV_ITEM_MAP.find do |nav_key, nav_val| + case nav_val + when Proc + @active_nav_key = nav_key if instance_exec(request.path, &nav_val) + when Hash + nav_val.find do |subnav_key, subnav_val| + @active_nav_key, @active_subnav_key = nav_key, subnav_key if instance_exec(request.path, &subnav_val) + end + end + end + end + + 'active' if @active_nav_key == key + end + + def subnav_item_class(key) + 'active' if @active_subnav_key == key + end +end diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml index 74d4117f7..1d44ddc05 100644 --- a/app/views/layouts/_navbar.html.haml +++ b/app/views/layouts/_navbar.html.haml @@ -13,35 +13,35 @@ - roles = current_user.teammates.where(event_id: current_event).pluck(:role) - if speaker_nav? - %li.nav-item{class: nav_item_class("my-proposals-link")} + %li.nav-item{class: nav_item_class(:my_proposals)} = link_to proposals_path, class: 'nav-link' do %span My Proposals - if review_nav?(roles) - %li.nav-item{class: nav_item_class("event-review-proposals-link")} + %li.nav-item{class: nav_item_class(:event_review_proposals)} = link_to event_staff_proposals_path(current_event), class: 'nav-link' do %span Review - if program_nav?(roles) - %li.nav-item{class: nav_item_class("event-selection-link")} + %li.nav-item{class: nav_item_class(:event_selection)} = link_to event_staff_program_proposals_path(current_event), class: 'nav-link' do %span Selection - %li.nav-item{class: nav_item_class("event-program-link")} + %li.nav-item{class: nav_item_class(:event_program)} = link_to event_staff_program_sessions_path(current_event), class: 'nav-link' do %span Program - if schedule_nav?(roles) - %li.nav-item{class: nav_item_class("event-schedule-link")} + %li.nav-item{class: nav_item_class(:event_schedule)} = link_to event_staff_schedule_grid_path(current_event), class: 'nav-link' do %span Schedule - if staff_nav?(roles) - %li.nav-item{class: nav_item_class("event-dashboard-link")} + %li.nav-item{class: nav_item_class(:event_dashboard)} = link_to event_staff_path(current_event), class: 'nav-link' do %span Dashboard - if !ENV['DISABLE_WEBSITE'] && website_nav? - %li.nav-item{class: nav_item_class("event-website-link")} + %li.nav-item{class: nav_item_class(:event_website)} = link_to new_or_edit_website_path, class: 'nav-link' do %span Website %sup Beta diff --git a/app/views/layouts/nav/staff/_event_subnav.html.haml b/app/views/layouts/nav/staff/_event_subnav.html.haml index e0e5b7b9c..a9daf82d9 100644 --- a/app/views/layouts/nav/staff/_event_subnav.html.haml +++ b/app/views/layouts/nav/staff/_event_subnav.html.haml @@ -2,27 +2,27 @@ .subnavbar-inner .container-fluid %ul.mainnav - %li{class: subnav_item_class("event-staff-dashboard-link")} + %li{class: subnav_item_class(:event_staff_dashboard)} = link_to event_staff_path do %i.bi.bi-speedometer2 %span Dashboard - %li{class: subnav_item_class("event-staff-info-link")} + %li{class: subnav_item_class(:event_staff_info)} = link_to info_event_staff_path do %i.bi.bi-info-circle %span Info - %li{class: subnav_item_class("event-staff-teammates-link")} + %li{class: subnav_item_class(:event_staff_teammates)} = link_to event_staff_teammates_path do %i.bi.bi-people %span Team - %li{class: subnav_item_class("event-staff-config-link")} + %li{class: subnav_item_class(:event_staff_config)} = link_to config_event_staff_path do %i.bi.bi-wrench %span Config - %li{class: subnav_item_class("event-staff-guidelines-link")} + %li{class: subnav_item_class(:event_staff_guidelines)} = link_to event_staff_guidelines_path do %i.bi.bi-list %span Guidelines - %li{class: subnav_item_class("event-staff-speaker-emails-link")} + %li{class: subnav_item_class(:event_staff_speaker_emails)} = link_to event_staff_speaker_email_templates_path do %i.bi.bi-envelope %span Speaker Emails diff --git a/app/views/layouts/nav/staff/_program_subnav.html.haml b/app/views/layouts/nav/staff/_program_subnav.html.haml index 952bd7fdb..a32067ab1 100644 --- a/app/views/layouts/nav/staff/_program_subnav.html.haml +++ b/app/views/layouts/nav/staff/_program_subnav.html.haml @@ -29,9 +29,9 @@ %span.badge= @all_waitlisted_track_count %ul.navbar-nav.ms-auto - %li.nav-item{class: subnav_item_class("event-program-sessions-link")} + %li.nav-item{class: subnav_item_class(:event_program_sessions)} = link_to event_staff_program_sessions_path, class: 'nav-link' do %span Sessions - %li.nav-item{class: subnav_item_class("event-program-speakers-link")} + %li.nav-item{class: subnav_item_class(:event_program_speakers)} = link_to event_staff_program_speakers_path, class: 'nav-link' do %span Speakers diff --git a/app/views/layouts/nav/staff/_schedule_subnav.html.haml b/app/views/layouts/nav/staff/_schedule_subnav.html.haml index 74b19d156..e7e364e86 100644 --- a/app/views/layouts/nav/staff/_schedule_subnav.html.haml +++ b/app/views/layouts/nav/staff/_schedule_subnav.html.haml @@ -6,15 +6,15 @@ %span.bi.bi-download %span Download Schedule JSON %ul.navbar-nav.ms-auto - %li.nav-item{class: subnav_item_class('event-schedule-grid-link')} + %li.nav-item{class: subnav_item_class(:event_schedule_grid)} = link_to event_staff_schedule_grid_path, class: 'nav-link' do %i.bi.bi-calendar-x %span Grid - %li.nav-item{class: subnav_item_class('event-schedule-time-slots-link')} + %li.nav-item{class: subnav_item_class(:event_schedule_time_slots)} = link_to event_staff_schedule_time_slots_path, class: 'nav-link' do %i.bi.bi-clock %span Time Slots - %li.nav-item{class: subnav_item_class('event-schedule-rooms-link')} + %li.nav-item{class: subnav_item_class(:event_schedule_rooms)} = link_to event_staff_schedule_rooms_path, class: 'nav-link' do %i.bi.bi-tag %span Rooms diff --git a/app/views/layouts/nav/staff/_selection_subnav.html.haml b/app/views/layouts/nav/staff/_selection_subnav.html.haml index 255bf5eea..c807fd859 100644 --- a/app/views/layouts/nav/staff/_selection_subnav.html.haml +++ b/app/views/layouts/nav/staff/_selection_subnav.html.haml @@ -29,12 +29,12 @@ %span.badge= @all_waitlisted_track_count %ul.navbar-nav.ms-auto - %li.nav-item{class: subnav_item_class("event-program-proposals-link")} + %li.nav-item{class: subnav_item_class(:event_program_proposals)} = link_to event_staff_program_proposals_path, class: 'nav-link' do %span Proposals - %li.nav-item{class: subnav_item_class("event-program-proposals-selection-link")} + %li.nav-item{class: subnav_item_class(:event_program_proposals_selection)} = link_to selection_event_staff_program_proposals_path, class: 'nav-link' do %span Selection - %li.nav-item{class: subnav_item_class("event-program-bulk-finalize-link")} + %li.nav-item{class: subnav_item_class(:event_program_bulk_finalize)} = link_to bulk_finalize_event_staff_program_proposals_path, class: 'nav-link' do %span Bulk Finalize diff --git a/app/views/layouts/nav/staff/_website_subnav.html.haml b/app/views/layouts/nav/staff/_website_subnav.html.haml index f57032fd8..09484f6ec 100644 --- a/app/views/layouts/nav/staff/_website_subnav.html.haml +++ b/app/views/layouts/nav/staff/_website_subnav.html.haml @@ -1,12 +1,12 @@ .navbar.navbar-expand-lg.fixed-top.website-subnav .container-fluid %ul.navbar-nav.ms-auto - %li.nav-item{class: subnav_item_class('event-website-configuration-link')} + %li.nav-item{class: subnav_item_class(:event_website_configuration)} = link_to edit_event_staff_website_path(current_event), class: 'nav-link' do %span Configuration - %li.nav-item{class: subnav_item_class('event-pages-link')} + %li.nav-item{class: subnav_item_class(:event_pages)} = link_to event_staff_pages_path(current_event), class: 'nav-link' do %span Pages - %li.nav-item{class: subnav_item_class('event-sponsor-link')} + %li.nav-item{class: subnav_item_class(:event_sponsor)} = link_to event_staff_sponsors_path, class: 'nav-link' do %span Sponsors