From 5e99960d84fbb50f07bc113aeacc00916657f88b Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:29:22 -0400 Subject: [PATCH 01/99] PLAN-453 fields for sched by room and time --- app/controllers/reports_controller.rb | 322 +++++++++++++------------- 1 file changed, 159 insertions(+), 163 deletions(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index e0dcecf85..64e1e74b3 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,4 +1,5 @@ class ReportsController < ApplicationController + around_action :set_timezone # # Name @@ -129,72 +130,72 @@ def sessions_with_participants # sort by room then time then session title # def schedule_by_room_then_time - # TZ - timezone = ConfigService.value('convention_timezone') - # We want the times to be in the TZ of the con for the report - Time.use_zone(timezone) do - authorize SessionAssignment, policy_class: ReportPolicy - - session_table = Arel::Table.new(Session.table_name) - subquery = Session.area_list.as('areas_list') - joins = [ - session_table.create_join( - subquery, - session_table.create_on( - subquery[:session_id].eq(session_table[:id]) - ), - Arel::Nodes::OuterJoin - ) - ] + authorize SessionAssignment, policy_class: ReportPolicy - # array aggregate ... - sessions = Session.select( - ::Session.arel_table[Arel.star], - 'areas_list.area_list' - ) - .joins(joins) - .references(:room) - .eager_load(:areas, :room, {session_assignments: [:person]}) - .where("sessions.room_id is not null and sessions.start_time is not null") - .order('rooms.sort_order', 'sessions.start_time', 'sessions.title') + session_table = Arel::Table.new(Session.table_name) + subquery = Session.area_list.as('areas_list') + joins = [ + session_table.create_join( + subquery, + session_table.create_on( + subquery[:session_id].eq(session_table[:id]) + ), + Arel::Nodes::OuterJoin + ) + ] - workbook = FastExcel.open(constant_memory: true) - worksheet = workbook.add_worksheet("Schedule by Room then Time") + # array aggregate ... + sessions = Session.select( + ::Session.arel_table[Arel.star], + 'areas_list.area_list' + ) + .joins(joins) + .references(:room) + .eager_load(:areas, :room, {session_assignments: [:person]}) + .where("sessions.room_id is not null and sessions.start_time is not null") + .order('rooms.sort_order', 'sessions.start_time', 'sessions.title') + + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("Schedule by Room then Time") + worksheet.append_row( + [ + 'Session', + 'Area', + 'Start Time', + 'Duration', + 'Room', + 'Moderator', + 'Assigned' + ] + ) + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [nil, nil, date_time_style, nil, nil, nil, nil] + moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') + participant = SessionAssignmentRoleType.find_by(name: 'Participant') + invisible = SessionAssignmentRoleType.find_by(name: 'Invisible') + sessions.each do |session| worksheet.append_row( [ - 'Room', - 'Start Time', - 'Session', - 'Area', - 'Assigned' - ] + session.title, + session.area_list.sort.join(';'), + FastExcel.date_num(session.start_time, session.start_time.in_time_zone.utc_offset), + session.duration, + session.room.name, + session.session_assignments. + select{|a| [moderator.id].include?(a.session_assignment_role_type_id)}. + collect{|s| s.person.published_name}.join('; '), + session.session_assignments. + select{|a| [participant.id, invisible.id].include?(a.session_assignment_role_type_id)}. + collect{|s| s.person.published_name}.join('; ') + ], + styles ) - date_time_style = workbook.number_format("d mmm yyyy h:mm") - styles = [nil, date_time_style, nil, nil, nil] - moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') - participant = SessionAssignmentRoleType.find_by(name: 'Participant') - invisible = SessionAssignmentRoleType.find_by(name: 'Invisible') - sessions.each do |session| - worksheet.append_row( - [ - session.room.name, - FastExcel.date_num(session.start_time, session.start_time.in_time_zone.utc_offset), - session.title, - session.area_list.sort.join(';'), - session.session_assignments. - select{|a| [participant.id, moderator.id, invisible.id].include?(a.session_assignment_role_type_id)}. - collect{|s| s.person.published_name}.join('; ') - ], - styles - ) - end - - send_data workbook.read_string, - filename: "ScheduleByRoomThenTime#{Time.now.strftime('%m-%d-%Y')}.xlsx", - disposition: 'attachment' - end + + send_data workbook.read_string, + filename: "ScheduleByRoomThenTime#{Time.now.strftime('%m-%d-%Y')}.xlsx", + disposition: 'attachment' end @@ -213,74 +214,69 @@ def schedule_by_room_then_time # sort by person (alpha asc) then by start time (asc) then by session title # def schedule_by_person - # TZ - timezone = ConfigService.value('convention_timezone') - # We want the times to be in the TZ of the con for the report - Time.use_zone(timezone) do - authorize SessionAssignment, policy_class: ReportPolicy - - conflicts_table = ::PersonSchedule.arel_table - subquery = Session.area_list.as('areas_list') - - joins = [ - conflicts_table.create_join( - subquery, - conflicts_table.create_on( - subquery[:session_id].eq(conflicts_table[:session_id]) - ), - Arel::Nodes::OuterJoin - ) - ] + authorize SessionAssignment, policy_class: ReportPolicy - people_sessions = PersonSchedule.select( - ::PersonSchedule.arel_table[Arel.star], - 'areas_list.area_list' - ) - .includes(:room).references(:room) - .joins(joins) - .where("session_assignment_name in (?)", ['Moderator', 'Participant', "Invisible"]) - .where("start_time is not null and room_id is not null") - .order('person_schedules.name', 'start_time', 'title') + conflicts_table = ::PersonSchedule.arel_table + subquery = Session.area_list.as('areas_list') - workbook = FastExcel.open(constant_memory: true) - worksheet = workbook.add_worksheet("Schedule by Participant") + joins = [ + conflicts_table.create_join( + subquery, + conflicts_table.create_on( + subquery[:session_id].eq(conflicts_table[:session_id]) + ), + Arel::Nodes::OuterJoin + ) + ] - worksheet.append_row( - [ - 'Name', - 'Published Name', - 'Participant Status', - 'Session', - 'Area', - 'Start Time', - 'Room', - 'Moderator', - 'Invisible', - ] + people_sessions = PersonSchedule.select( + ::PersonSchedule.arel_table[Arel.star], + 'areas_list.area_list' ) + .includes(:room).references(:room) + .joins(joins) + .where("session_assignment_name in (?)", ['Moderator', 'Participant', "Invisible"]) + .where("start_time is not null and room_id is not null") + .order('person_schedules.name', 'start_time', 'title') - date_time_style = workbook.number_format("d mmm yyyy h:mm") - styles = [nil, nil, nil, nil, nil, date_time_style, nil, nil, nil] - people_sessions.each do |sa| - worksheet.append_row( - [ sa.name, - sa.published_name, - sa.con_state, - sa.title, - sa.area_list.join('; '), - FastExcel.date_num(sa.start_time, sa.start_time.in_time_zone.utc_offset), - sa.room.name, - if sa.session_assignment_name == 'Moderator' then 'Y' else 'N' end, - if sa.session_assignment_name == 'Invisible' then 'Y' else 'N' end - ], - styles - ) - end + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("Schedule by Participant") - send_data workbook.read_string, - filename: "ScheduleByParticipant#{Time.now.strftime('%m-%d-%Y')}.xlsx", - disposition: 'attachment' + worksheet.append_row( + [ + 'Name', + 'Published Name', + 'Participant Status', + 'Session', + 'Area', + 'Start Time', + 'Room', + 'Moderator', + 'Invisible', + ] + ) + + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [nil, nil, nil, nil, nil, date_time_style, nil, nil, nil] + people_sessions.each do |sa| + worksheet.append_row( + [ sa.name, + sa.published_name, + sa.con_state, + sa.title, + sa.area_list.join('; '), + FastExcel.date_num(sa.start_time, sa.start_time.in_time_zone.utc_offset), + sa.room.name, + if sa.session_assignment_name == 'Moderator' then 'Y' else 'N' end, + if sa.session_assignment_name == 'Invisible' then 'Y' else 'N' end + ], + styles + ) end + + send_data workbook.read_string, + filename: "ScheduleByParticipant#{Time.now.strftime('%m-%d-%Y')}.xlsx", + disposition: 'attachment' end # Assigned session by participant - this should only return if the person is assigned as a moderator or a participant @@ -333,57 +329,52 @@ def assigned_sessions_by_participant # # def participant_availabilities - # TZ - timezone = ConfigService.value('convention_timezone') - # We want the times to be in the TZ of the con for the report - Time.use_zone(timezone) do - people = Person.includes( - :availabilities, - :session_limits, - :person_exclusions, - :exclusions - ).references( - :availabilities, - :session_limits, - :person_exclusions - ).where( - "availabilities.person_id is not null OR session_limits.person_id is not null OR person_exclusions.person_id is not null" - ) + people = Person.includes( + :availabilities, + :session_limits, + :person_exclusions, + :exclusions + ).references( + :availabilities, + :session_limits, + :person_exclusions + ).where( + "availabilities.person_id is not null OR session_limits.person_id is not null OR person_exclusions.person_id is not null" + ) - workbook = FastExcel.open(constant_memory: true) - worksheet = workbook.add_worksheet("Participant Availability") + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("Participant Availability") + + worksheet.append_row( + [ + 'Name', + 'Published Name', + 'Attendance Type', + 'Availabilities', + 'Limits', + 'Exclusions', + 'Availability Notes' + ] + ) + people.each do |person| worksheet.append_row( [ - 'Name', - 'Published Name', - 'Attendance Type', - 'Availabilities', - 'Limits', - 'Exclusions', - 'Availability Notes' + person.name, + person.published_name, + person.attendance_type, + person.availabilities.order('start_time').collect{|av| "#{av.start_time} to #{av.end_time}" }.join(";\n"), + person.session_limits.order('day').collect{|l| "#{l.day ? l.day : 'Global'}: #{l.max_sessions}" }.join(";\n"), + person.exclusions.collect{|e| "#{e.title}"}.join(";\n"), + person.availability_notes ] ) - people.each do |person| - worksheet.append_row( - [ - person.name, - person.published_name, - person.attendance_type, - person.availabilities.order('start_time').collect{|av| "#{av.start_time} to #{av.end_time}" }.join(";\n"), - person.session_limits.order('day').collect{|l| "#{l.day ? l.day : 'Global'}: #{l.max_sessions}" }.join(";\n"), - person.exclusions.collect{|e| "#{e.title}"}.join(";\n"), - person.availability_notes - ] - ) - - end - - send_data workbook.read_string, - filename: "ParticipantAvailabilities_#{Time.now.strftime('%m-%d-%Y')}.xlsx", - disposition: 'attachment' end + + send_data workbook.read_string, + filename: "ParticipantAvailabilities_#{Time.now.strftime('%m-%d-%Y')}.xlsx", + disposition: 'attachment' end # By participant @@ -563,4 +554,9 @@ def participant_do_not_assign_with filename: "ParticipantDoNotAssignWith#{Time.now.strftime('%m-%d-%Y')}.xlsx", disposition: 'attachment' end + + def set_timezone(&block) + timezone = ConfigService.value('convention_timezone') + Time.use_zone(timezone, &block) + end end From 00459df066a57667114c7619f1f16c40a2a97d91 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:43:18 -0400 Subject: [PATCH 02/99] PLAN-455 tweak availability report --- .../reports/conflict_reports_controller.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index 24165d742..f9d02b33b 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -412,6 +412,7 @@ def people_outside_availability 'areas_list.area_list' ) .includes(:session, :person) + .eager_load(person: :availabilities) .joins(joins) .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .order('people.published_name') @@ -424,24 +425,28 @@ def people_outside_availability [ 'Name', 'Pub Name', + 'Status', 'Session', 'Area', - 'Start Time' - + 'Start Time', + 'Duration', + 'Availability' ] ) date_time_style = workbook.number_format("d mmm yyyy h:mm") - styles = [nil, nil, nil, nil, date_time_style, nil] + styles = [nil, nil, nil, nil, nil, date_time_style, nil, nil] conflicts.each do |conflict| worksheet.append_row( [ conflict.person.name, conflict.person.published_name, + conflict.person.con_state, conflict.session.title, conflict.area_list.join('; '), - FastExcel.date_num(conflict.session.start_time, conflict.session.start_time.in_time_zone.utc_offset) - + FastExcel.date_num(conflict.session.start_time, conflict.session.start_time.in_time_zone.utc_offset), + conflict.session.duration, + conflict.person.availabilities.order('start_time').collect{|av| "#{av.start_time} to #{av.end_time}" }.join(";\n"), ], styles ) From 718a0139f7d327ab54b169e36009cac6401c8bb1 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:46:41 -0400 Subject: [PATCH 03/99] PLAN-456 add status to double booked --- app/controllers/reports/conflict_reports_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index f9d02b33b..344c16723 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -356,6 +356,7 @@ def people_double_booked [ 'Name', 'Published Name', + 'Status', 'Time', 'Session', 'Area', @@ -367,13 +368,14 @@ def people_double_booked ] ) date_time_style = workbook.number_format("d mmm yyyy h:mm") - styles = [nil, nil, date_time_style, nil, nil, nil, nil, nil] + styles = [nil, nil, nil, date_time_style, nil, nil, nil, nil, nil] conflicts.each do |conflict| worksheet.append_row( [ conflict.person.name, conflict.person.published_name, + conflict.person.con_state, FastExcel.date_num(conflict.session.start_time, conflict.session.start_time.in_time_zone.utc_offset), conflict.session.title, conflict.area_list.join('; '), From aa2d7ac7b4bb8136b7454df8c22c52df025147d1 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:49:36 -0400 Subject: [PATCH 04/99] PLAN-458 Add person status --- app/controllers/reports/session_reports_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/reports/session_reports_controller.rb b/app/controllers/reports/session_reports_controller.rb index 59b83a731..03907733b 100644 --- a/app/controllers/reports/session_reports_controller.rb +++ b/app/controllers/reports/session_reports_controller.rb @@ -268,6 +268,7 @@ def participants_over_con_session_limits [ 'Name', 'Published Name', + 'Statue', 'Session Count', 'Con Limit' ] @@ -278,6 +279,7 @@ def participants_over_con_session_limits [ person.name, person.published_name, + person.con_state, person.session_count, 6 ] From db265778babf5a4266efb2429d431a5da67ee546 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:54:00 -0400 Subject: [PATCH 05/99] PLAN-461 indicate moderator --- app/controllers/reports/session_reports_controller.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/reports/session_reports_controller.rb b/app/controllers/reports/session_reports_controller.rb index 03907733b..8500b9499 100644 --- a/app/controllers/reports/session_reports_controller.rb +++ b/app/controllers/reports/session_reports_controller.rb @@ -304,18 +304,20 @@ def panels_with_too_few_people 'Title', 'Areas', 'Participant Count', - 'List of Participants' + 'List of Participants', + 'Moderators' ] ) - # has_many :submissions + moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') sessions.each do |session| worksheet.append_row( [ session.title, session.area_list.sort.join(';'), session.nbr_assignments, - session.session_assignments.collect{|a| a.person.published_name}.join(';') + session.session_assignments.select{|a| a.session_assignment_role_type_id != moderator.id}.collect{|a| a.person.published_name}.join(';'), + session.session_assignments.select{|a| a.session_assignment_role_type_id == moderator.id}.collect{|a| a.person.published_name}.join(';'), ] ) end From eafc2a9c6a96e0eb2e3487d94974a7a768be0e91 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 17:58:20 -0400 Subject: [PATCH 06/99] Put conflicts in conflict group --- app/javascript/reports/reports_screen.vue | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/javascript/reports/reports_screen.vue b/app/javascript/reports/reports_screen.vue index 71c24882c..4606baa20 100644 --- a/app/javascript/reports/reports_screen.vue +++ b/app/javascript/reports/reports_screen.vue @@ -12,9 +12,6 @@
  • Assigned Sessions by Participant
  • -
  • - Schedule by Participant -
  • People and Survey Submissions
  • @@ -28,9 +25,6 @@
  • Participants over Con Limit
  • -
  • - Person scheduled against a conflict item -
  • Non-Accepted Participants on Scheduled Sessions
  • @@ -56,16 +50,19 @@
  • Sessions with Participants not Scheduled +
  • + Panels with too few Participants +
  • +
  • + Panels with too many Participants +
  • Conflicts

    From 0b7a260084925f39048d1df7643184b50836c894 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 1 Jul 2022 18:00:24 -0400 Subject: [PATCH 07/99] PLAN-462 indicate moderator --- app/controllers/reports/session_reports_controller.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/reports/session_reports_controller.rb b/app/controllers/reports/session_reports_controller.rb index 8500b9499..73bfcb4ce 100644 --- a/app/controllers/reports/session_reports_controller.rb +++ b/app/controllers/reports/session_reports_controller.rb @@ -317,7 +317,7 @@ def panels_with_too_few_people session.area_list.sort.join(';'), session.nbr_assignments, session.session_assignments.select{|a| a.session_assignment_role_type_id != moderator.id}.collect{|a| a.person.published_name}.join(';'), - session.session_assignments.select{|a| a.session_assignment_role_type_id == moderator.id}.collect{|a| a.person.published_name}.join(';'), + session.session_assignments.select{|a| a.session_assignment_role_type_id == moderator.id}.collect{|a| a.person.published_name}.join(';') ] ) end @@ -340,18 +340,21 @@ def panels_with_too_many_people 'Session', 'Areas', 'Participant Count', - 'List of Participants' + 'List of Participants', + 'Moderators' ] ) # has_many :submissions + moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') sessions.each do |session| worksheet.append_row( [ session.title, session.area_list.sort.join(';'), session.nbr_assignments, - session.session_assignments.collect{|a| a.person.published_name}.join(';') + session.session_assignments.select{|a| a.session_assignment_role_type_id != moderator.id}.collect{|a| a.person.published_name}.join(';'), + session.session_assignments.select{|a| a.session_assignment_role_type_id == moderator.id}.collect{|a| a.person.published_name}.join(';') ] ) end From 2cc5b204fed16606114ed2802e0288ca64772f16 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 11:59:10 -0400 Subject: [PATCH 08/99] PLAN-471 fields for sessions with participants --- app/controllers/reports_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 64e1e74b3..500989a73 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -91,10 +91,12 @@ def sessions_with_participants worksheet.append_row( [ 'Session', + 'Session Type/Format', 'Areas', 'Moderators', 'Participants', - 'Reserves' + 'Reserves', + 'Scehduled' ] ) @@ -105,10 +107,12 @@ def sessions_with_participants worksheet.append_row( [ session.title, + session.format.name, session.area_list.sort.join(';'), session.session_assignments.select{|a| a.session_assignment_role_type_id == moderator.id}.collect{|a| a.person.published_name}.join(';'), session.session_assignments.select{|a| a.session_assignment_role_type_id == participant.id}.collect{|a| a.person.published_name}.join(';'), session.session_assignments.select{|a| a.session_assignment_role_type_id == reserve.id}.collect{|a| a.person.published_name}.join(';'), + session.start_time && session.room_id ? 'Y' : 'N' ] ) end From 550f314229c2f920206eadf886e990812b1b9e4e Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 12:03:17 -0400 Subject: [PATCH 09/99] PLAN-470 session selections new fields --- app/controllers/reports_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 500989a73..c49ecf8c0 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -448,6 +448,7 @@ def session_selections 'Title', 'Who is Interested', 'Who is Interested (Pub Name)', + 'Participant Status', 'Ranking', 'Notes', 'Areas' @@ -461,6 +462,7 @@ def session_selections session.title, assignment.person.name, assignment.person.published_name, + assignment.person.con_state, assignment.interest_ranking, assignment.interest_notes, session.areas.collect(&:name).join("; ") From b9a98ceb5ae22d66d4ecdd4987a8afed0f9354d7 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 12:14:00 -0400 Subject: [PATCH 10/99] PLAN-469 participant selections extra fields --- app/controllers/reports_controller.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index c49ecf8c0..5e2184f71 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -392,7 +392,7 @@ def participant_selections assignments = SessionAssignment .joins(:person) - .includes([{session: :areas}, :person]) + .includes([{session: :areas}, :person, :session_assignment_role_type]) .where(interested: true).order("people.name") workbook = FastExcel.open(constant_memory: true) @@ -402,10 +402,13 @@ def participant_selections [ 'Name', 'Published Name', + 'Participant Status', 'Session', 'Ranking', 'Ranking Notes', - 'Areas' + 'Areas', + 'Assigned', + 'Scheduled' ] ) assignments.each do |assignment| @@ -413,10 +416,13 @@ def participant_selections [ assignment.person.name, assignment.person.published_name, + assignment.person.con_state, assignment.session.title, assignment.interest_ranking, assignment.interest_notes, - assignment.session.areas.collect(&:name).join("; ") + assignment.session.areas.collect(&:name).join("; "), + assignment.session_assignment_role_type && assignment.session_assignment_role_type.role_type == 'participant' && ['Moderator', 'Participant'].include?(assignment.session_assignment_role_type.name) ? 'Y' : 'N', + assignment.session.start_time && assignment.session.room_id ? 'Y' : 'N' ] ) end From 37a645ac884aac7cc906148748f471005adf5c39 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 12:16:06 -0400 Subject: [PATCH 11/99] PLAN-468 availability extra fields --- app/controllers/reports_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 5e2184f71..b306c3dc1 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -353,6 +353,7 @@ def participant_availabilities [ 'Name', 'Published Name', + 'Participant Status', 'Attendance Type', 'Availabilities', 'Limits', @@ -366,6 +367,7 @@ def participant_availabilities [ person.name, person.published_name, + person.con_state, person.attendance_type, person.availabilities.order('start_time').collect{|av| "#{av.start_time} to #{av.end_time}" }.join(";\n"), person.session_limits.order('day').collect{|l| "#{l.day ? l.day : 'Global'}: #{l.max_sessions}" }.join(";\n"), From 3ff8c87e90e2506dc075187c7bf964af8043d423 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 12:19:27 -0400 Subject: [PATCH 12/99] PLAN-463 Assigned Sessions new fields --- app/controllers/reports_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index b306c3dc1..fa6b2061b 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -306,8 +306,10 @@ def assigned_sessions_by_participant [ 'Name', 'Published Name', + 'Participant Status', 'Session', - 'Role' + 'Role', + 'Scheduled' ] ) @@ -317,8 +319,10 @@ def assigned_sessions_by_participant [ person.name, person.published_name, + person.con_state, assignment.session.title, - assignment.session_assignment_role_type.name + assignment.session_assignment_role_type.name, + assignment.session.start_time && assignment.session.room_id ? 'Y' : 'N' ] ) end From 18d6bdc2b2afc15a313c5ab15fd5fa7e051377c8 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 12:28:45 -0400 Subject: [PATCH 13/99] PLAN-325 add attendance type col to people table --- app/javascript/people/people.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/javascript/people/people.js b/app/javascript/people/people.js index 30a4977a0..364e3792c 100644 --- a/app/javascript/people/people.js +++ b/app/javascript/people/people.js @@ -46,6 +46,10 @@ export const people_columns = [ ], sortable: false }, + { + key: 'attendance_type', + label: 'Attendance Type' + }, { key: 'organization', label: 'Organization', From 17f4090e30561fcbbcd5e5c2730c7473ba7aa7a5 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 16:40:37 -0400 Subject: [PATCH 14/99] PLAN-358 and PLAN-357 all conflicts and all ignored conflicts --- .../reports/conflict_reports_controller.rb | 78 +++++++++++++++++++ app/javascript/reports/reports_screen.vue | 5 +- .../reports/conflict_report_policy.rb | 8 ++ app/services/reports_service.rb | 30 +++++++ config/routes.rb | 2 + lib/tasks/rbac.rake | 8 +- 6 files changed, 128 insertions(+), 3 deletions(-) diff --git a/app/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index 24165d742..f428c9848 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -1,6 +1,84 @@ class Reports::ConflictReportsController < ApplicationController around_action :set_timezone + def all_ignored_conflicts + authorize SessionAssignment, policy_class: Reports::ConflictReportPolicy + + conflicts = ReportsService::all_conflicts(ignored: true) + + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("All Conflicts") + + worksheet.append_row( + [ + 'Session', + 'Areas', + 'Start Time', + 'Room', + 'Conflict Type' + ] + ) + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [ + nil, nil, date_time_style, nil, nil + ] + conflicts.each do |conflict| + worksheet.append_row( + [ + conflict.session_title, + conflict.area_list.join('; '), + FastExcel.date_num(conflict.session_start_time, conflict.session_start_time.in_time_zone.utc_offset), + conflict.room&.name, + conflict.conflict_type + ], + styles + ) + end + + send_data workbook.read_string, + filename: "all_ignored_conflicts#{Time.now.strftime('%m-%d-%Y')}.xlsx", + disposition: 'attachment' + end + + def all_conflicts + authorize SessionAssignment, policy_class: Reports::ConflictReportPolicy + + conflicts = ReportsService::all_conflicts + + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("All Conflicts") + + worksheet.append_row( + [ + 'Session', + 'Areas', + 'Start Time', + 'Room', + 'Conflict Type' + ] + ) + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [ + nil, nil, date_time_style, nil, nil + ] + conflicts.each do |conflict| + worksheet.append_row( + [ + conflict.session_title, + conflict.area_list.join('; '), + FastExcel.date_num(conflict.session_start_time, conflict.session_start_time.in_time_zone.utc_offset), + conflict.room&.name, + conflict.conflict_type + ], + styles + ) + end + + send_data workbook.read_string, + filename: "all_conflicts#{Time.now.strftime('%m-%d-%Y')}.xlsx", + disposition: 'attachment' + end + def multiple_sessions_in_room authorize SessionAssignment, policy_class: Reports::ConflictReportPolicy diff --git a/app/javascript/reports/reports_screen.vue b/app/javascript/reports/reports_screen.vue index 71c24882c..d06f14fac 100644 --- a/app/javascript/reports/reports_screen.vue +++ b/app/javascript/reports/reports_screen.vue @@ -80,7 +80,10 @@ Back to Back to Back
  • - Multiple Sessions in a Room + All Conflicts +
  • +
  • + All Ignored Conflicts
  • diff --git a/app/policies/reports/conflict_report_policy.rb b/app/policies/reports/conflict_report_policy.rb index 8f16a5c62..64d03172a 100644 --- a/app/policies/reports/conflict_report_policy.rb +++ b/app/policies/reports/conflict_report_policy.rb @@ -22,4 +22,12 @@ def person_exclusion_conflicts? def multiple_sessions_in_room? allowed?(action: :multiple_sessions_in_room) end + + def all_conflicts? + allowed?(action: :all_conflicts) + end + + def all_ignored_conflicts? + allowed?(action: :all_ignored_conflicts) + end end diff --git a/app/services/reports_service.rb b/app/services/reports_service.rb index 6c01f905a..731c28256 100644 --- a/app/services/reports_service.rb +++ b/app/services/reports_service.rb @@ -1,5 +1,35 @@ module ReportsService + def self.all_conflicts(ignored: false) + conflicts_table = ::Conflicts::SessionConflict.arel_table + subquery = Session.area_list.as('areas_list') + + joins = [ + conflicts_table.create_join( + subquery, + conflicts_table.create_on( + subquery[:session_id].eq(conflicts_table[:session_id]) + ), + Arel::Nodes::OuterJoin + ) + ] + + where_clause = if ignored + "session_conflicts.conflict_id in (select conflict_id from ignored_conflicts)" + else + "session_conflicts.conflict_id not in (select conflict_id from ignored_conflicts)" + end + + Conflicts::SessionConflict.select( + ::Conflicts::SessionConflict.arel_table[Arel.star], + 'areas_list.area_list' + ) + .joins(joins) + .includes(:room) + .where(where_clause) + .order(:session_title) + end + def self.assigned_sessions_not_scheduled active_roles = SessionAssignmentRoleType.where("role_type = 'participant' and name != 'Reserve'") diff --git a/config/routes.rb b/config/routes.rb index 125acfe35..ef53ba2e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -71,6 +71,8 @@ get 'report/conflict_reports/back_to_back_to_back', to: 'reports/conflict_reports#back_to_back_to_back' get 'report/conflict_reports/person_exclusion_conflicts', to: 'reports/conflict_reports#person_exclusion_conflicts' get 'report/conflict_reports/multiple_sessions_in_room', to: 'reports/conflict_reports#multiple_sessions_in_room' + get 'report/conflict_reports/all_conflicts', to: 'reports/conflict_reports#all_conflicts' + get 'report/conflict_reports/all_ignored_conflicts', to: 'reports/conflict_reports#all_ignored_conflicts' resources :availabilities, path: 'availability', except: [:index] resources :person_exclusions, path: 'person_exclusion', except: [:index] diff --git a/lib/tasks/rbac.rake b/lib/tasks/rbac.rake index b74c5d162..a3ee1166f 100644 --- a/lib/tasks/rbac.rake +++ b/lib/tasks/rbac.rake @@ -493,7 +493,9 @@ namespace :rbac do "back_to_back": true, "back_to_back_to_back": true, "person_exclusion_conflicts": true, - "multiple_sessions_in_room": true + "multiple_sessions_in_room": true, + "all_conflicts": true, + "all_ignored_conflicts": true }, "session_conflict": { "conflicts_with": true, @@ -749,7 +751,9 @@ namespace :rbac do "back_to_back": true, "back_to_back_to_back": true, "person_exclusion_conflicts": true, - "multiple_sessions_in_room": true + "multiple_sessions_in_room": true, + "all_conflicts": true, + "all_ignored_conflicts": true }, "session_conflict": { "conflicts_with": true, From 345e484022d684a6ea5d1f4b22f8c14d9de9572a Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 3 Jul 2022 17:00:15 -0400 Subject: [PATCH 15/99] adjust fields in ignored conflicts --- app/controllers/reports/conflict_reports_controller.rb | 6 +++++- app/services/reports_service.rb | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index f428c9848..b2a8b53d9 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -14,7 +14,9 @@ def all_ignored_conflicts 'Session', 'Areas', 'Start Time', + 'Duration', 'Room', + 'Person', 'Conflict Type' ] ) @@ -28,8 +30,10 @@ def all_ignored_conflicts conflict.session_title, conflict.area_list.join('; '), FastExcel.date_num(conflict.session_start_time, conflict.session_start_time.in_time_zone.utc_offset), + conflict.session&.duration, conflict.room&.name, - conflict.conflict_type + conflict.person_published_name, + conflict.conflict_type, ], styles ) diff --git a/app/services/reports_service.rb b/app/services/reports_service.rb index 731c28256..785d3d92e 100644 --- a/app/services/reports_service.rb +++ b/app/services/reports_service.rb @@ -25,7 +25,7 @@ def self.all_conflicts(ignored: false) 'areas_list.area_list' ) .joins(joins) - .includes(:room) + .includes(:room, :session) .where(where_clause) .order(:session_title) end From 7a555fbbe66accd5f47890d75a53cab2de0e29fa Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 09:29:09 -0400 Subject: [PATCH 16/99] sort assignments from server side call --- .../session_assignments_controller.rb | 17 ++++++++++++++++- .../sessions/assign_participants.vue | 1 + app/models/session_assignment_role_type.rb | 13 +++---------- app/serializers/person_serializer.rb | 18 +++++++++--------- .../20220704121816_add_sort_to_role_type.rb | 5 +++++ db/structure.sql | 6 ++++-- lib/tasks/role_types.rake | 13 +++++++++++++ script/planorama_start.sh | 1 + 8 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20220704121816_add_sort_to_role_type.rb diff --git a/app/controllers/session_assignments_controller.rb b/app/controllers/session_assignments_controller.rb index ab45d3cfa..965fb0fe7 100644 --- a/app/controllers/session_assignments_controller.rb +++ b/app/controllers/session_assignments_controller.rb @@ -28,6 +28,20 @@ def update_actions [:update, :unexpress_interest] end + def order_string(order_by: nil) + return super(order_by: order_by) if order_by + + order_str = %(session_assignment_role_type.sort_order asc NULLS LAST, + CASE WHEN session_assignments.state = 'accepted' THEN 1 + WHEN session_assignments.state = 'proposed' THEN 2 + WHEN session_assignments.state = 'rejected' THEN 3 + else 4 + end + ) + + Arel.sql(order_str.squish) + end + def serializer_includes if params[:session_id] # remove included data for now to speed up loads @@ -47,7 +61,8 @@ def serializer_includes def includes [ :person, - :session + :session, + :session_assignment_role_type ] end diff --git a/app/javascript/sessions/assign_participants.vue b/app/javascript/sessions/assign_participants.vue index e238be37d..c00c40404 100644 --- a/app/javascript/sessions/assign_participants.vue +++ b/app/javascript/sessions/assign_participants.vue @@ -72,6 +72,7 @@ export default { return this.selected_model(sessionModel); }, peopleFilter() { + // NOTE: sessionAssignmentModel let filter = { "op": "all", "queries":[ diff --git a/app/models/session_assignment_role_type.rb b/app/models/session_assignment_role_type.rb index 01cddb082..75a79244f 100644 --- a/app/models/session_assignment_role_type.rb +++ b/app/models/session_assignment_role_type.rb @@ -1,15 +1,8 @@ -## schema -# CREATE TABLE public.session_assignment_role_type ( -# id integer NOT NULL, -# lock_version integer DEFAULT 0, -# created_at timestamp without time zone, -# updated_at timestamp without time zone, -# name character varying(100) NOT NULL, -# role_type public.assignment_role_enum, -# default_visibility public.visibility_enum DEFAULT 'public'::public.visibility_enum -# ); class SessionAssignmentRoleType < ApplicationRecord self.table_name = "session_assignment_role_type" + include RankedModel + ranks :sort_order + has_many :session_assignments has_many :published_session_assignments diff --git a/app/serializers/person_serializer.rb b/app/serializers/person_serializer.rb index 470334e6c..e7bfe8dfc 100644 --- a/app/serializers/person_serializer.rb +++ b/app/serializers/person_serializer.rb @@ -55,7 +55,7 @@ class PersonSerializer #< ActiveModel::Serializer person.base_tags.collect(&:name) end - has_many :email_addresses, serializer: EmailAddressSerializer, + has_many :email_addresses, lazy_load_data: true, serializer: EmailAddressSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -65,7 +65,7 @@ class PersonSerializer #< ActiveModel::Serializer } } - has_many :convention_roles, serializer: ConventionRoleSerializer, + has_many :convention_roles, lazy_load_data: true, serializer: ConventionRoleSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -75,7 +75,7 @@ class PersonSerializer #< ActiveModel::Serializer } } - has_many :submissions, serializer: Survey::SubmissionSerializer, + has_many :submissions, lazy_load_data: true, serializer: Survey::SubmissionSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -86,7 +86,7 @@ class PersonSerializer #< ActiveModel::Serializer } # - has_many :mailed_surveys, serializer: SurveySerializer, + has_many :mailed_surveys, lazy_load_data: true, serializer: SurveySerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -96,7 +96,7 @@ class PersonSerializer #< ActiveModel::Serializer } } - has_many :assigned_surveys, serializer: SurveySerializer, + has_many :assigned_surveys, lazy_load_data: true, serializer: SurveySerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -108,7 +108,7 @@ class PersonSerializer #< ActiveModel::Serializer # # Availabilities - has_many :availabilities, serializer: AvailabilitySerializer, + has_many :availabilities, lazy_load_data: true, serializer: AvailabilitySerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -118,7 +118,7 @@ class PersonSerializer #< ActiveModel::Serializer } } - has_many :person_exclusions, serializer:PersonExclusionSerializer, + has_many :person_exclusions, lazy_load_data: true, serializer:PersonExclusionSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -128,7 +128,7 @@ class PersonSerializer #< ActiveModel::Serializer } } - has_many :session_limits, serializer:SessionLimitSerializer, + has_many :session_limits, lazy_load_data: true, serializer:SessionLimitSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" @@ -170,7 +170,7 @@ class PersonSerializer #< ActiveModel::Serializer # } # } - has_many :mail_histories, serializer: MailHistorySerializer, + has_many :mail_histories, lazy_load_data: true, serializer: MailHistorySerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" diff --git a/db/migrate/20220704121816_add_sort_to_role_type.rb b/db/migrate/20220704121816_add_sort_to_role_type.rb new file mode 100644 index 000000000..d4473247d --- /dev/null +++ b/db/migrate/20220704121816_add_sort_to_role_type.rb @@ -0,0 +1,5 @@ +class AddSortToRoleType < ActiveRecord::Migration[6.1] + def change + add_column :session_assignment_role_type, :sort_order, :integer + end +end diff --git a/db/structure.sql b/db/structure.sql index 7b5a8cdc1..a071f3736 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -596,7 +596,8 @@ CREATE TABLE public.session_assignment_role_type ( updated_at timestamp without time zone, name character varying(100) NOT NULL, role_type public.assignment_role_enum, - default_visibility public.visibility_enum DEFAULT 'public'::public.visibility_enum + default_visibility public.visibility_enum DEFAULT 'public'::public.visibility_enum, + sort_order integer ); @@ -3144,6 +3145,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220624121252'), ('20220628121934'), ('20220629132145'), -('20220630032544'); +('20220630032544'), +('20220704121816'); diff --git a/lib/tasks/role_types.rake b/lib/tasks/role_types.rake index eafe709fe..ca12f94c6 100644 --- a/lib/tasks/role_types.rake +++ b/lib/tasks/role_types.rake @@ -43,5 +43,18 @@ namespace :role_types do ) end + fix_sort_order + + end + + def fix_sort_order + rt = SessionAssignmentRoleType.find_by(name: 'Moderator') + rt.update!(sort_order: 1) + rt = SessionAssignmentRoleType.find_by(name: 'Participant') + rt.update!(sort_order: 2) + rt = SessionAssignmentRoleType.find_by(name: 'Invisible') + rt.update!(sort_order: 3) + rt = SessionAssignmentRoleType.find_by(name: 'Reserve') + rt.update!(sort_order: 4) end end diff --git a/script/planorama_start.sh b/script/planorama_start.sh index d1862b9d3..fceb1f7a4 100755 --- a/script/planorama_start.sh +++ b/script/planorama_start.sh @@ -28,6 +28,7 @@ if [[ -z $RAILS_ENV ]] || [[ $RAILS_ENV = "development" ]]; then bin/rake views:recreate bin/rake db:migrate bin/rake parameters:seed_names + bin/rake role_types:seed_role_types bin/rake chicon:seed_exclusions bin/rake chicon:seed_rooms bin/rake chicon:fix_formats From 870d2f15448c7129fac757982a0870529ee143cf Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 09:39:54 -0400 Subject: [PATCH 17/99] Add re-order button per wireframe --- app/javascript/sessions/assign_participants.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/javascript/sessions/assign_participants.vue b/app/javascript/sessions/assign_participants.vue index c00c40404..b872eff10 100644 --- a/app/javascript/sessions/assign_participants.vue +++ b/app/javascript/sessions/assign_participants.vue @@ -6,10 +6,13 @@
    -
    - Assignment State +
    + + Assignment State + +
    -
    +
    Potential Participants
    @@ -86,6 +89,9 @@ export default { } }, methods: { + reorder() { + this.fetchPaged(false) + }, saveAssignment(assignment) { this.save(assignment).then( () => { From 61bd49c3aff840ea7f5f0594688d199ac45aa802 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 09:52:47 -0400 Subject: [PATCH 18/99] PLAN-283 clear selected on search etc --- app/javascript/components/table_vue.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/javascript/components/table_vue.vue b/app/javascript/components/table_vue.vue index 30eaea3bb..2d03a4a16 100644 --- a/app/javascript/components/table_vue.vue +++ b/app/javascript/components/table_vue.vue @@ -286,13 +286,16 @@ export default { } }, onSortChanged(ctx) { + this.editable_ids = [] this.sortBy = ctx.sortBy; this.sortDesc = ctx.sortDesc; }, onSearchChanged(arg) { + this.editable_ids = [] this.filter = arg }, setFilter(newFilter) { + this.editable_ids = [] this.filter = newFilter }, showAlternateSearch() { From fc24e90f86e53321f5a2f976053cf7b50f12a9fb Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 10:12:15 -0400 Subject: [PATCH 19/99] mention both sessions in double booking --- app/javascript/conflicts/session_conflicts.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/javascript/conflicts/session_conflicts.vue b/app/javascript/conflicts/session_conflicts.vue index 47517506b..4095190b5 100644 --- a/app/javascript/conflicts/session_conflicts.vue +++ b/app/javascript/conflicts/session_conflicts.vue @@ -137,10 +137,12 @@ export default { case 'person_schedule_conflict': if (conflict_with) { return `${conflict.person_published_name} is double booked with - "${conflict.session_title}"` + "${conflict.conflict_session_title}" + and "${conflict.session_title}"` } else { return `${conflict.person_published_name} is double booked with - "${conflict.conflict_session_title}"` + "${conflict.session_title}" + and "${conflict.conflict_session_title}"` } case 'person_back_to_back': if (conflict_with) { From ac678e33cea16d6258e0a923621fccc64bdd56c7 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 10:26:35 -0400 Subject: [PATCH 20/99] PLAN-413 do not show doubles --- app/controllers/conflicts/session_conflicts_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/conflicts/session_conflicts_controller.rb b/app/controllers/conflicts/session_conflicts_controller.rb index d7b8bbd27..6bbbe8b7f 100644 --- a/app/controllers/conflicts/session_conflicts_controller.rb +++ b/app/controllers/conflicts/session_conflicts_controller.rb @@ -24,6 +24,7 @@ def conflicts_with .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .where("conflict_session_assignment_name is null or conflict_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .where("session_conflicts.conflict_id not in (select conflict_id from ignored_conflicts)") + .where("session_conflicts.conflict_type != 'person_schedule_conflict' and session_conflicts.conflict_type != 'person_back_to_back'") .distinct meta = {} From e7bfaba5c7e2c845cbad8b28f1afa08a6394d380 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 10:42:59 -0400 Subject: [PATCH 21/99] PLAN-475 validate that primary email address is unique acroess people --- app/models/person.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/person.rb b/app/models/person.rb index 4208e7a85..f2cf84ccb 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -16,6 +16,7 @@ class Person < ApplicationRecord has_paper_trail versions: { class_name: 'Audit::PersonVersion' }, ignore: [:updated_at, :created_at] before_destroy :check_if_assigned + before_save :check_primary_email has_many :availabilities @@ -147,6 +148,12 @@ def no_group? convention_roles.size == 0 end + def check_primary_email + if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true").count > 0 + raise "That email has been taken by someone else as a primary email address" + end + end + # # For devise login as a person # From 3c8dfae34665c8103019190c8dfeeca3a2cf1190 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 12:17:13 -0400 Subject: [PATCH 22/99] PLAN-362 filter all scheduable sessions, just ones with time (no room) or just ones with room (no time) --- .../schedule/schedulable_sessions.vue | 21 +----- app/javascript/schedule/schedule_screen.vue | 14 ++-- .../schedule/schedule_session_search.vue | 64 +++++++++++++++++-- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/app/javascript/schedule/schedulable_sessions.vue b/app/javascript/schedule/schedulable_sessions.vue index c7eedd54f..e5e0c6f9c 100644 --- a/app/javascript/schedule/schedulable_sessions.vue +++ b/app/javascript/schedule/schedulable_sessions.vue @@ -1,7 +1,5 @@ @@ -56,7 +66,15 @@ export default { title_desc: null, area_id: null, tags: null, - match: 'any' + match: 'any', + schedFilter: 'all' + } + }, + watch: { + schedFilter(newVal, oldVal) { + if (newVal != oldVal) { + this.onSearch() + } } }, methods: { @@ -90,6 +108,41 @@ export default { ) } + if (this.schedFilter != 'all') { + if (this.schedFilter == 'time') { + queries = { + "op": 'all', + "queries": [ + ["start_time","is not null",null], + ["room_id", "is null"], + queries + ] + } + } else { + queries = { + "op": 'all', + "queries": [ + ["start_time","is null"], + ["room_id", "is not null"], + queries + ] + } + } + } else { + queries = { + "op": 'all', + "queries": [ + { + "op": "any", + "queries":[ + ["start_time", "is null"], + ["room_id", "is null"] + ] + }, + queries + ] + } + } return queries }, onSearch: function (event) { @@ -99,22 +152,23 @@ export default { title_desc: this.title_desc, area_id: this.area_id, tags: this.tags, - match: this.match + match: this.match, + schedFilter: this.schedFilter } }) this.$emit('change', this.fields_to_query()) }, init() { - let saved = this.getSearchState()(SAVED_SEARCH_STATE) - // console.debug("**** INIT ", saved) if (saved) { this.title_desc = saved.title_desc this.area_id = saved.area_id this.tags = saved.tags this.match = saved.match - this.$emit('change', this.fields_to_query()) + this.schedFilter = saved.schedFilter } + + this.$emit('change', this.fields_to_query()) } }, mounted() { From cc2c0507bc8ffdffb39075ff49198dbbdb6fe73e Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 12:36:15 -0400 Subject: [PATCH 23/99] PLAN-374 add tooltop to availabilities --- .../profile/availability_time_picker.vue | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/app/javascript/profile/availability_time_picker.vue b/app/javascript/profile/availability_time_picker.vue index 072b46f6c..c1a99ae9e 100644 --- a/app/javascript/profile/availability_time_picker.vue +++ b/app/javascript/profile/availability_time_picker.vue @@ -29,12 +29,14 @@ {{ formatDate(view.selectedDate, { day: 'numeric', month: 'short' }) }} @@ -85,17 +87,7 @@ export default { } }, data: () => ({ - dayEvents: {}, - // TODO: we need to pass this in based on TZ - // conventionHours: { - // 1: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 2: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 3: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 4: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 5: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 6: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // 7: { from: 8.5 * 60, to: 24 * 60, class: 'convention-hours' }, - // } + dayEvents: {} }), computed: { dayColClass() { @@ -108,6 +100,9 @@ export default { } }, methods: { + hoverText(event) { + return this.formatLocaleJsDate(event.start) + ' - ' + this.formatLocaleJsDate(event.end) + }, scrollBarElement: function() { return this.$refs['dayColumn'].$el.getElementsByClassName('vuecal__bg')[0] }, From af0c4066b7ca48f55c1020e6460c3cc79da72c4e Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 4 Jul 2022 14:10:42 -0400 Subject: [PATCH 24/99] PLAN-387 add spinner to sched load place tooltips above --- app/javascript/schedule/schedule_calendar.vue | 33 ++++++++++++------- app/javascript/schedule/schedule_day.vue | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/app/javascript/schedule/schedule_calendar.vue b/app/javascript/schedule/schedule_calendar.vue index 413099500..f795d9871 100644 --- a/app/javascript/schedule/schedule_calendar.vue +++ b/app/javascript/schedule/schedule_calendar.vue @@ -5,17 +5,22 @@ -->
    - + + + +
    @@ -50,7 +55,8 @@ export default { } }, data: () => ({ - sessionModel + sessionModel, + loading: false }), methods: { onScheduleChanged: function() { @@ -60,13 +66,16 @@ export default { this.$emit("show-conflicts", session_id); }, init: function() { + this.loading = true this.fetch({}).then( () => { // $nextTick ensures that the DOM is rendered... which is usefull // when we want to do DOM type functions... this.$nextTick( () => { + this.loading = false for (const day of this.days) { + console.debug("******** DAY IS ", day) let component = this.$refs[`day-${day}`][0].scrollBarElement() let targets = this.days.filter(d => d != day) diff --git a/app/javascript/schedule/schedule_day.vue b/app/javascript/schedule/schedule_day.vue index 5894ee7b4..bf615930e 100644 --- a/app/javascript/schedule/schedule_day.vue +++ b/app/javascript/schedule/schedule_day.vue @@ -29,7 +29,7 @@ style="height: 100%;" v-bind:class="{ 'selected-event': (selected && (selected.id == event.id)), 'event-with-conflicts': (event.has_conflicts && !(selected && (selected.id == event.id))) }" > -
    +
    Date: Mon, 4 Jul 2022 18:22:38 -0400 Subject: [PATCH 25/99] PLAN-384 bump version to 1.5.0 --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 0be43bbc7..b905472b6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,8 +7,8 @@ This software is open source! If you'd like to contribute, please email planoram [Planorama Data Privacy & Protection Policy](/planorama/privacy) -Production version: 1.4.2 +Production version: 1.5.0 -Staging version: 1.4.2 +Staging version: 1.5.0 From 327461443db0772107766c824de3103755c6ad4e Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Mon, 4 Jul 2022 21:41:25 -0400 Subject: [PATCH 26/99] fix syntax error on logout --- app/models/person.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/person.rb b/app/models/person.rb index f2cf84ccb..ce36e5dba 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -149,7 +149,7 @@ def no_group? end def check_primary_email - if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true").count > 0 + if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true", id, email.strip).count > 0 raise "That email has been taken by someone else as a primary email address" end end From c01e09c5b573198d0168ef543f035937bbc49c6d Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 5 Jul 2022 10:39:39 -0400 Subject: [PATCH 27/99] PLAN-392 remove assignments for uninterested people if unassigned --- app/controllers/concerns/resource_methods.rb | 3 ++- .../session_assignments_controller.rb | 16 ++++++++++++++++ app/javascript/sessions/assign_participants.vue | 13 ++++++++++--- app/javascript/sessions/assignment_state.vue | 2 +- app/javascript/store/model.mixin.js | 3 +-- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app/controllers/concerns/resource_methods.rb b/app/controllers/concerns/resource_methods.rb index face6f670..11cbbf59e 100644 --- a/app/controllers/concerns/resource_methods.rb +++ b/app/controllers/concerns/resource_methods.rb @@ -91,7 +91,8 @@ def update after_update end end - after_update_tx + ret = after_update_tx + return if ret render_object(@object) end diff --git a/app/controllers/session_assignments_controller.rb b/app/controllers/session_assignments_controller.rb index 965fb0fe7..14c02656d 100644 --- a/app/controllers/session_assignments_controller.rb +++ b/app/controllers/session_assignments_controller.rb @@ -28,6 +28,22 @@ def update_actions [:update, :unexpress_interest] end + def after_update_tx + # if unassigning and they are not selected then we delete .... + if @object.state == 'proposed' && !@object.interested && !@object.session_assignment_role_type_id + # Get rid of the assignment + @object.destroy + + # tell the client to refetch so it updates data correctly + # we may need to revist cause this is not good either + redirect_to(action: :destroy, id: @object.id, status: 303) + + return true + else + return false + end + end + def order_string(order_by: nil) return super(order_by: order_by) if order_by diff --git a/app/javascript/sessions/assign_participants.vue b/app/javascript/sessions/assign_participants.vue index b872eff10..0fce2efec 100644 --- a/app/javascript/sessions/assign_participants.vue +++ b/app/javascript/sessions/assign_participants.vue @@ -7,10 +7,10 @@
    - + Assignment State - +
    Potential Participants @@ -95,7 +95,14 @@ export default { saveAssignment(assignment) { this.save(assignment).then( () => { - this.refreshSession() + // TODO? + // this.refreshSession() + this.fetchPaged(false) + } + ).catch( + () => { + // this.refreshSession() + this.fetchPaged(false) } ) }, diff --git a/app/javascript/sessions/assignment_state.vue b/app/javascript/sessions/assignment_state.vue index 349a61ad8..522e6ab1e 100644 --- a/app/javascript/sessions/assignment_state.vue +++ b/app/javascript/sessions/assignment_state.vue @@ -105,7 +105,7 @@ export default { break; case 'rejected': this.sessionAssignment.state = 'rejected' - this.sessionAssignment.visibility = 'private' + this.sessionAssignment.visibility = 'is_private' this.sessionAssignment.session_assignment_role_type_id = null break; } diff --git a/app/javascript/store/model.mixin.js b/app/javascript/store/model.mixin.js index f48030a85..fed144c19 100644 --- a/app/javascript/store/model.mixin.js +++ b/app/javascript/store/model.mixin.js @@ -11,7 +11,7 @@ export const modelMixinNoProp = { selected() { return this.$store.getters[SELECTED]({model: this.model}) }, - collection() { + collection() { return Object.values(this.$store.getters['jv/get']({_jv: { type: this.model }})) } }, @@ -49,7 +49,6 @@ export const modelMixinNoProp = { }, // need a save instance save(instance) { - console.log(instance); return this.toastPromise(this.$store.dispatch(SAVE, {model: this.model, selected: false, item: instance}), MODEL_SAVE_SUCCESS(this.model), MODEL_SAVE_ERROR(this.model)); }, delete_by_id(id) { From 821f6fa7a98cd2ebfcece0b89f97f6e678ca5269 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 5 Jul 2022 18:55:59 -0400 Subject: [PATCH 28/99] PLAN-517 endpoint for draft sessions WIP --- app/controllers/people_controller.rb | 26 +++++++++++++++++++ app/policies/person_policy.rb | 6 +++++ app/serializers/person_serializer.rb | 38 ++++++++++++++-------------- config/routes.rb | 3 ++- lib/tasks/rbac.rake | 3 +++ 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 4b2331db8..13266d8f0 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -21,6 +21,32 @@ def me ) end + def draft_sessions + authorize current_person, policy_class: policy_class + + person = Person.find params{:person_id} + + if person + reserved = SessionAssignmentRoleType.find_by(name: 'Reserve') + sessions = person.sessions + .where("session_assignments.session_assignment_role_type_id is not null AND session_assignments.state != 'rejected'") + .where("session_assignments.session_assignment_role_type_id != ?", reserved) + .where("sessions.start_time is not null AND sessions.room_id is not null") + .order("sessions.start_time asc, sessions.title asc") + + render json: SessionSerializer.new( + sessions, + { + params: { + domain: "#{request.base_url}", + current_person: current_person + } + } + ).serializable_hash(), + content_type: 'application/json' + end + end + # Get all the session names for the people ids passed in def session_names authorize current_person, policy_class: policy_class diff --git a/app/policies/person_policy.rb b/app/policies/person_policy.rb index 66d064821..90306d543 100644 --- a/app/policies/person_policy.rb +++ b/app/policies/person_policy.rb @@ -21,6 +21,12 @@ def import? allowed?(action: :import) end + def draft_sessions? + return true if @record.class != Symbol && @record.id == @person.id + + allowed?(action: :draft_sessions) + end + def assigned_surveys? return true if @record.class != Symbol && @record.id == @person.id diff --git a/app/serializers/person_serializer.rb b/app/serializers/person_serializer.rb index e7bfe8dfc..78d2f2839 100644 --- a/app/serializers/person_serializer.rb +++ b/app/serializers/person_serializer.rb @@ -138,26 +138,26 @@ class PersonSerializer #< ActiveModel::Serializer } } - # links: { - # self: -> (object, params) { - # "#{params[:domain]}/person/#{object.id}" - # }, - # related: -> (object, params) { - # "#{params[:domain]}/person/#{object.id}/session_limit" - # } - # } - # sessions - # has_many :sessions, serializer: SessionSerializer, - # if: Proc.new { |record, params| AccessControlService.allowed_access?(instance: record, person: params[:current_person]) }, - # links: { - # self: -> (object, params) { - # "#{params[:domain]}/person/#{object.id}" - # }, - # related: -> (object, params) { - # "#{params[:domain]}/person/#{object.id}/sessions" - # } - # } + has_many :draft_sessions, lazy_load_data: true, serializer: SessionSerializer, + links: { + self: -> (object, params) { + "#{params[:domain]}/person/#{object.id}" + }, + related: -> (object, params) { + "#{params[:domain]}/person/#{object.id}/draft_sessions" + } + } + # sessions + has_many :sessions, lazy_load_data: true, serializer: SessionSerializer, + links: { + self: -> (object, params) { + "#{params[:domain]}/person/#{object.id}" + }, + related: -> (object, params) { + "#{params[:domain]}/person/#{object.id}/sessions" + } + } # published_sessions # has_many :published_sessions, serializer: PublishedSessionSerializer, diff --git a/config/routes.rb b/config/routes.rb index ef53ba2e5..6102213c9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,6 +31,7 @@ get 'convention_roles', to: 'convention_roles#index' get 'email_addresses', to: 'email_addresses#index' get 'sessions', to: 'sessions#index' + get 'draft_sessions', to: 'people#draft_sessions' get 'published_sessions', to: 'published_sessions#index' get 'mail_histories', to: 'mail_histories#index' get 'submissions', to: 'people#submissions' @@ -72,7 +73,7 @@ get 'report/conflict_reports/person_exclusion_conflicts', to: 'reports/conflict_reports#person_exclusion_conflicts' get 'report/conflict_reports/multiple_sessions_in_room', to: 'reports/conflict_reports#multiple_sessions_in_room' get 'report/conflict_reports/all_conflicts', to: 'reports/conflict_reports#all_conflicts' - get 'report/conflict_reports/all_ignored_conflicts', to: 'reports/conflict_reports#all_ignored_conflicts' + get 'report/conflict_reports/all_ignored_conflicts', to: 'reports/conflict_reports#all_ignored_conflicts' resources :availabilities, path: 'availability', except: [:index] resources :person_exclusions, path: 'person_exclusion', except: [:index] diff --git a/lib/tasks/rbac.rake b/lib/tasks/rbac.rake index a3ee1166f..2b0caf147 100644 --- a/lib/tasks/rbac.rake +++ b/lib/tasks/rbac.rake @@ -89,6 +89,7 @@ namespace :rbac do "update": true, "update_all": false, "session_names": false, + "draft_sessions": false, "create": false, "destroy": false }, @@ -311,6 +312,7 @@ namespace :rbac do "update": true, "update_all": true, "session_names": true, + "draft_sessions": true, "create": true, "destroy": true }, @@ -569,6 +571,7 @@ namespace :rbac do "update": true, "update_all": true, "session_names": true, + "draft_sessions": true, "create": true, "destroy": true }, From beeeff4eeb309c1ea8c356903cfaeea7c0a87cb6 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 5 Jul 2022 19:34:15 -0400 Subject: [PATCH 29/99] fixes primary email check --- app/models/person.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/person.rb b/app/models/person.rb index ce36e5dba..91c70aa83 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -149,7 +149,9 @@ def no_group? end def check_primary_email - if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true", id, email.strip).count > 0 + return unless primary_email + + if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true", id, primary_email.email.strip).count > 0 raise "That email has been taken by someone else as a primary email address" end end From db266409afcfd58e0c6ee552f06288d428a33499 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 5 Jul 2022 19:35:51 -0400 Subject: [PATCH 30/99] fix primary email check --- app/models/person.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/person.rb b/app/models/person.rb index 91c70aa83..757fdc208 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -149,9 +149,9 @@ def no_group? end def check_primary_email - return unless primary_email + return unless email - if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true", id, primary_email.email.strip).count > 0 + if EmailAddress.where("person_id != ? and email ilike ? and isdefault = true", id, email.strip).count > 0 raise "That email has been taken by someone else as a primary email address" end end From 7336b201e182b2e7c4c477589d95927276a6e6eb Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Tue, 5 Jul 2022 20:44:18 -0400 Subject: [PATCH 31/99] PLAN-446 schedule tab existance also PLAN-434 add admin notes tab more to come on PLAN-446 --- app/javascript/people/people_admin_tab.vue | 13 +++++++++---- app/javascript/people/people_sidebar.vue | 2 +- app/javascript/people/person_tabs.vue | 18 ++++++++++++++++-- app/javascript/profile/person_schedule.vue | 15 +++++++++++++++ app/javascript/reports/reports_screen.vue | 12 ++++++------ app/javascript/store/model.mixin.js | 2 +- 6 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 app/javascript/profile/person_schedule.vue diff --git a/app/javascript/people/people_admin_tab.vue b/app/javascript/people/people_admin_tab.vue index fb9f1ef06..a1ef304ec 100644 --- a/app/javascript/people/people_admin_tab.vue +++ b/app/javascript/people/people_admin_tab.vue @@ -1,5 +1,5 @@ diff --git a/app/javascript/people/people_sidebar.vue b/app/javascript/people/people_sidebar.vue index b942a0bd0..984a3ecbb 100644 --- a/app/javascript/people/people_sidebar.vue +++ b/app/javascript/people/people_sidebar.vue @@ -15,7 +15,7 @@ - + + {{title}} + + + + + + + + + + + + + + + + diff --git a/app/javascript/sessions/session_fields.mixin.js b/app/javascript/sessions/session_fields.mixin.js index 250de54d8..769c8b439 100644 --- a/app/javascript/sessions/session_fields.mixin.js +++ b/app/javascript/sessions/session_fields.mixin.js @@ -23,16 +23,27 @@ export const scheduledMixin = { } } -export const startTimeMixin = { +export const startTimeMixinNoSelected = { mixins: [ conventionTimezoneMixin ], - computed: { - formattedStartTime() { - if(this.selected?.start_time) { - return DateTime.fromISO(this.selected.start_time, {zone: 'utc'}).setZone(this.conventionTimezone).toFormat('DDDD, t ZZZZ'); + methods: { + formatStartTime(session) { + if(session.start_time) { + return DateTime.fromISO(session.start_time, {zone: 'utc'}).setZone(this.conventionTimezone).toFormat('DDDD, t ZZZZ'); } return ''; }, } } + +export const startTimeMixin = { + mixins: [ + startTimeMixinNoSelected + ], + computed: { + formattedStartTime() { + this.formatStartTime(this.selected); + }, + } +} From 8541829a4b9e178d02f2db01024d10ccffc7f05f Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Wed, 6 Jul 2022 09:40:51 -0400 Subject: [PATCH 34/99] more tweaks to schedule view PLAN-446 --- app/javascript/profile/person_schedule.vue | 16 ++++++--- app/javascript/sessions/session_role.mixin.js | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 app/javascript/sessions/session_role.mixin.js diff --git a/app/javascript/profile/person_schedule.vue b/app/javascript/profile/person_schedule.vue index b56332eac..b6f956491 100644 --- a/app/javascript/profile/person_schedule.vue +++ b/app/javascript/profile/person_schedule.vue @@ -16,7 +16,8 @@
    Title
    {{session.title}}
    Participants (with contact information where allowed)
    -
    TODO
    +
    {{sa.person.publication_name}}{{ isModerator(sa) ? " (m)" : ""}} {{sa.person.pronouns}} - {{ sa.person.contact_email ? sa.person.contact_email : 'permission not given'}}
    +
    None Assigned
    Description
    Space/Time
    @@ -26,9 +27,10 @@
    Session Environment
    {{SESSION_ENVIRONMENT[session.environment]}}
    Session Format
    -
    TODO
    +
    {{session.format.name || session.format_id}}
    Session Area(s)
    -
    TODO
    +
    {{area}}
    +
    None Selected
    Schedule Notes
    @@ -45,6 +47,7 @@ import { personModel as model } from '@/store/person.store'; import { modelMixinNoProp } from '@/mixins'; import { startTimeMixinNoSelected } from '@/sessions/session_fields.mixin'; import { SESSION_ENVIRONMENT } from '@/constants/strings'; +import { sessionRoleMixin } from '@/sessions/session_role.mixin'; export default { name: "PersonSchedule", @@ -53,7 +56,8 @@ export default { }, mixins: [ modelMixinNoProp, - startTimeMixinNoSelected + startTimeMixinNoSelected, + sessionRoleMixin ], data: () => ({ sessions: {}, @@ -102,7 +106,9 @@ export default { .indented-dl { dd { margin-left: 0.5rem; - font-style: italic; + &:not(.not-italic) { + font-style: italic; + } } } diff --git a/app/javascript/sessions/session_role.mixin.js b/app/javascript/sessions/session_role.mixin.js new file mode 100644 index 000000000..965fac862 --- /dev/null +++ b/app/javascript/sessions/session_role.mixin.js @@ -0,0 +1,35 @@ +import { settingsMixin } from "@/mixins"; + +export const sessionRoleMixin = { + mixins: [ settingsMixin ], + computed: { + moderatorRole() { + return this.sessionRoleByName('Moderator'); + }, + participantRole() { + return this.sessionRoleByName('Participant'); + }, + invisibleRole() { + return this.sessionRoleByName('Invisible'); + }, + reserveRole() { + return this.sessionRoleByName('Reserve'); + } + }, + methods: { + isModerator(sa) { + return sa.session_assignment_role_type_id && sa.session_assignment_role_type_id === this.moderatorRole?.id + }, + isParticipant(sa) { + return sa.session_assignment_role_type_id && sa.session_assignment_role_type_id === this.participantRole?.id + }, + isInvisible(sa) { + return sa.session_assignment_role_type_id && sa.session_assignment_role_type_id === this.invisibleRole?.id + }, + isReserve(sa) { + return sa.session_assignment_role_type_id && sa.session_assignment_role_type_id === this.reserveRole?.id + }, + } +} + +export default sessionRoleMixin; From 46d1638e511887ea2b784d905504675a1c5c9570 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 09:48:55 -0400 Subject: [PATCH 35/99] fix endpoint for draft sessions --- app/controllers/people_controller.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 13266d8f0..0d13ee82f 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -24,11 +24,12 @@ def me def draft_sessions authorize current_person, policy_class: policy_class - person = Person.find params{:person_id} + person = Person.find params[:person_id] if person reserved = SessionAssignmentRoleType.find_by(name: 'Reserve') sessions = person.sessions + .eager_load({session_assignments: :person}, :format, :session_areas) .where("session_assignments.session_assignment_role_type_id is not null AND session_assignments.state != 'rejected'") .where("session_assignments.session_assignment_role_type_id != ?", reserved) .where("sessions.start_time is not null AND sessions.room_id is not null") @@ -37,6 +38,15 @@ def draft_sessions render json: SessionSerializer.new( sessions, { + # need assgnments and rooms etc + include: [ + :format, + :room, + :session_areas, + :'session_areas.area', + :session_assignments, + :'session_assignments.person' + ], params: { domain: "#{request.base_url}", current_person: current_person From 568425d92e5d12a56cc6b7e22345785d4b26e10f Mon Sep 17 00:00:00 2001 From: ralphlevan Date: Wed, 6 Jul 2022 10:36:43 -0400 Subject: [PATCH 36/99] PLAN-397 Commented out the surveyLink column --- app/javascript/surveys/survey.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/surveys/survey.js b/app/javascript/surveys/survey.js index 10ae328e0..7473798e0 100644 --- a/app/javascript/surveys/survey.js +++ b/app/javascript/surveys/survey.js @@ -40,7 +40,7 @@ export const survey_columns = [ sortable: false }, 'preview', - 'surveyLink', + //'surveyLink', // welcome // thank_you // submit_string From e027a7a9702bf134299c6170d95114af42c64ff1 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 10:47:43 -0400 Subject: [PATCH 37/99] imporved participant relationshop in sessions --- app/controllers/people_controller.rb | 8 +++----- app/models/session.rb | 10 ++++++++++ app/serializers/session_serializer.rb | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 0d13ee82f..8bbf2441f 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -29,9 +29,7 @@ def draft_sessions if person reserved = SessionAssignmentRoleType.find_by(name: 'Reserve') sessions = person.sessions - .eager_load({session_assignments: :person}, :format, :session_areas) - .where("session_assignments.session_assignment_role_type_id is not null AND session_assignments.state != 'rejected'") - .where("session_assignments.session_assignment_role_type_id != ?", reserved) + .eager_load({participant_assignments: :person}, :format, :session_areas) .where("sessions.start_time is not null AND sessions.room_id is not null") .order("sessions.start_time asc, sessions.title asc") @@ -44,8 +42,8 @@ def draft_sessions :room, :session_areas, :'session_areas.area', - :session_assignments, - :'session_assignments.person' + :participant_assignments, + :'participant_assignments.person' ], params: { domain: "#{request.base_url}", diff --git a/app/models/session.rb b/app/models/session.rb index d02bd50f4..2ba4a6b3b 100644 --- a/app/models/session.rb +++ b/app/models/session.rb @@ -61,6 +61,16 @@ def interests_for(person_id) end has_many :people, through: :session_assignments + has_many :participant_assignments, + -> { + joins("JOIN session_assignment_role_type as sart ON sart.id = session_assignments.session_assignment_role_type_id") + .where("session_assignments.session_assignment_role_type_id is not null AND session_assignments.state != 'rejected'") + .where("session_assignments.session_assignment_role_type_id not in (select id from session_assignment_role_type where session_assignment_role_type.name = 'Reserve')") + .order("sart.sort_order") + }, + class_name: 'SessionAssignment' + has_many :participants, through: :participant_assignments, source: :person, class_name: 'Person' + # TODO: Will also need a published versioon of the relationship has_many :session_areas, inverse_of: :session has_many :areas, through: :session_areas diff --git a/app/serializers/session_serializer.rb b/app/serializers/session_serializer.rb index 7fe0f34d0..6940511ac 100644 --- a/app/serializers/session_serializer.rb +++ b/app/serializers/session_serializer.rb @@ -65,6 +65,8 @@ class SessionSerializer } } + has_many :participant_assignments, lazy_load_data: true, serializer: SessionAssignmentSerializer + has_one :format, lazy_load_data: true, if: Proc.new { |record| record.format }, links: { From 891ab70471268bbde37d6b8199e35e916e14f87d Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 14:02:47 -0400 Subject: [PATCH 38/99] WIP --- .../conflicts/session_conflicts.vue | 60 +++++++++++-------- app/javascript/schedule/schedule_calendar.vue | 5 +- app/javascript/schedule/schedule_day.vue | 13 ++-- app/javascript/schedule/schedule_screen.vue | 8 ++- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/app/javascript/conflicts/session_conflicts.vue b/app/javascript/conflicts/session_conflicts.vue index 4095190b5..34faea219 100644 --- a/app/javascript/conflicts/session_conflicts.vue +++ b/app/javascript/conflicts/session_conflicts.vue @@ -1,30 +1,32 @@ @@ -53,7 +55,8 @@ export default { }, data: () => ({ conflicts: [], - conflicts_with: [] + conflicts_with: [], + loading: false }), components: { IgnoreButton @@ -93,24 +96,31 @@ export default { } ) }, + refreshConflicts() { + this.getConflicts(this.sessionId) + }, getConflicts(sessionId) { + this.loading = true this.conflicts = [] this.conflicts_with = [] this.clear() - this.get_conflicts({session_id: sessionId}).then( + let p1 = this.get_conflicts({session_id: sessionId}).then( (conflicts) => { this.conflicts = Object.values(conflicts).filter( obj => (typeof obj.json === 'undefined') ) } ) - this.get_conflicts_with({session_id: sessionId}).then( + let p2 = this.get_conflicts_with({session_id: sessionId}).then( (conflicts) => { this.conflicts_with = Object.values(conflicts).filter( obj => (typeof obj.json === 'undefined') ) } ) + Promise.all([p1, p2]).then((values) => { + this.loading = false + }); }, // TODO template these conflict_type_string(conflict, conflict_with=false) { diff --git a/app/javascript/schedule/schedule_calendar.vue b/app/javascript/schedule/schedule_calendar.vue index f795d9871..5213a4ad5 100644 --- a/app/javascript/schedule/schedule_calendar.vue +++ b/app/javascript/schedule/schedule_calendar.vue @@ -59,8 +59,8 @@ export default { loading: false }), methods: { - onScheduleChanged: function() { - this.$emit("schedule-changed"); + onScheduleChanged: function(id) { + this.$emit("schedule-changed", id); }, onShowConflicts: function(session_id) { this.$emit("show-conflicts", session_id); @@ -75,7 +75,6 @@ export default { () => { this.loading = false for (const day of this.days) { - console.debug("******** DAY IS ", day) let component = this.$refs[`day-${day}`][0].scrollBarElement() let targets = this.days.filter(d => d != day) diff --git a/app/javascript/schedule/schedule_day.vue b/app/javascript/schedule/schedule_day.vue index bf615930e..6ab733f83 100644 --- a/app/javascript/schedule/schedule_day.vue +++ b/app/javascript/schedule/schedule_day.vue @@ -188,11 +188,7 @@ export default { } }, onEventDrop ({ event, originalEvent, external }) { - this.updateSession(event.id, event.start, event.split).then( - () => { - this.$emit("show-conflicts", event.id); - } - ) + this.updateSession(event.id, event.start, event.split) }, onDelete(event, ev) { event.stopPropagation() @@ -204,11 +200,16 @@ export default { }, updateSession(id, start_time, room_id) { let session = this.get_model(sessionModel, id) + let removed = start_time == null session.start_time = start_time ? this.uiDateToTZDate(start_time) : null session.room_id = room_id return this.save_model(sessionModel, session).then( () => { - this.$emit("schedule-changed"); + if (removed) { + this.$emit("schedule-changed", null); + } else { + this.$emit("schedule-changed", id); + } } ) } diff --git a/app/javascript/schedule/schedule_screen.vue b/app/javascript/schedule/schedule_screen.vue index 2be8cbd59..b549a14b9 100644 --- a/app/javascript/schedule/schedule_screen.vue +++ b/app/javascript/schedule/schedule_screen.vue @@ -153,10 +153,14 @@ export default { ...mapActions({ fetch: FETCH }), - onScheduleChanged: function() { + onScheduleChanged: function(id) { this.$refs["schedulable-sessions"].fetchPaged(false) // update the conflicts - this.$refs["conflict-reporting"].fetchPaged() + if (this.sessionIdForConflict == id) { + this.$refs["conflict-reporting"].refreshConflicts() + } else { + this.sessionIdForConflict = id + } }, onShowConflicts: function(session_id) { this.sessionIdForConflict = session_id From 9bd481ea01b06ead9d8f518bee39d75c66d03193 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 15:52:59 -0400 Subject: [PATCH 39/99] PLAN-513 ensure conflict reports ignored ignored --- .../reports/conflict_reports_controller.rb | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index 346fc5d36..da8aa7921 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -91,6 +91,7 @@ def multiple_sessions_in_room .includes(:room) .references(:room) .where("room_conflicts.back_to_back = false") + .where("room_conflicts.id not in (select conflict_id from ignored_conflicts)") .order('rooms.name, start_time') workbook = FastExcel.open(constant_memory: true) @@ -151,6 +152,7 @@ def person_exclusion_conflicts :person, :session, :exclusion, :excluded_session ) .where("session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .where("person_exclusion_conflicts.id not in (select conflict_id from ignored_conflicts)") .order('people.published_name asc') workbook = FastExcel.open(constant_memory: true) @@ -337,16 +339,17 @@ def back_to_back ] conflicts = Conflicts::PersonBackToBack.select( - Conflicts::PersonBackToBack.arel_table[Arel.star], - 'areas_list.area_list as area_list', - 'conflict_areas_list.area_list as conflict_area_list' - ) - .includes(:room, :conflict_room) - .references(:room, :conflict_room) - .joins(joins) - .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") - .where("conflict_session_assignment_name is null or conflict_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") - .order('published_name asc, conflict_start_time asc') + Conflicts::PersonBackToBack.arel_table[Arel.star], + 'areas_list.area_list as area_list', + 'conflict_areas_list.area_list as conflict_area_list' + ) + .includes(:room, :conflict_room) + .references(:room, :conflict_room) + .joins(joins) + .where("person_back_to_back.id not in (select conflict_id from ignored_conflicts)") + .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .where("conflict_session_assignment_name is null or conflict_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .order('published_name asc, conflict_start_time asc') workbook = FastExcel.open(constant_memory: true) worksheet = workbook.add_worksheet("People Scheduled Back to Back") @@ -428,6 +431,7 @@ def people_double_booked ) .includes(:person, :session, :conflict_session, :room, :conflict_room) .joins(joins) + .where("person_schedule_conflicts.id not in (select conflict_id from ignored_conflicts)") .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .where("conflict_session_assignment_name is null or conflict_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .order('people.published_name asc, start_time asc') @@ -499,6 +503,7 @@ def people_outside_availability .includes(:session, :person) .eager_load(person: :availabilities) .joins(joins) + .where("availability_conflicts.id not in (select conflict_id from ignored_conflicts)") .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") .order('people.published_name') From c69c82bd1004eb68bdaead13b63a778775771d00 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 16:38:25 -0400 Subject: [PATCH 40/99] PLAN-512 remove ignores for session that is moved --- app/controllers/sessions_controller.rb | 13 +++++++++++++ app/models/session.rb | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5b797e343..6af7cde24 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -139,6 +139,19 @@ def tags content_type: 'application/json' end + def before_update + # if time or room have changed removed ignored conflicts + p = _permitted_params(model: object_name, instance: @object) + if (@object.start_time || @object.room_id) + if p[:start_time] != @object.start_time || p[:room_id] != @object.room_id + # so we remove any ignore conflicts for this session + cids = @object.ignored_session_conflicts.pluck(:conflict_id) + cids += @object.ignored_conflict_sessions.pluck(:conflict_id) + IgnoredConflict.where(conflict_id: cids).delete_all + end + end + end + def serializer_includes [ :format, diff --git a/app/models/session.rb b/app/models/session.rb index d02bd50f4..9b7123c54 100644 --- a/app/models/session.rb +++ b/app/models/session.rb @@ -35,6 +35,18 @@ class Session < ApplicationRecord }, foreign_key: :conflict_session_id, class_name: 'Conflicts::SessionConflict' + has_many :ignored_session_conflicts, + -> { + where("session_conflicts.conflict_id in (select conflict_id from ignored_conflicts)") + }, + class_name: 'Conflicts::SessionConflict' + + has_many :ignored_conflict_sessions, + -> { + where("session_conflicts.conflict_id in (select conflict_id from ignored_conflicts)") + }, + foreign_key: :conflict_session_id, class_name: 'Conflicts::SessionConflict' + has_and_belongs_to_many :room_services has_many :session_assignments, dependent: :destroy do From f51affcd7a215e4e32e00d656eaf32ddfeec2be8 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 16:55:43 -0400 Subject: [PATCH 41/99] PLAN-428 check for submissions with responses --- app/models/survey.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/survey.rb b/app/models/survey.rb index ff3c3dcb3..5311e27cf 100644 --- a/app/models/survey.rb +++ b/app/models/survey.rb @@ -10,12 +10,12 @@ class Survey < ApplicationRecord has_many :questions, through: :pages, class_name: 'Survey::Question' - has_many :submissions, class_name: 'Survey::Submission' + has_many :submissions, class_name: 'Survey::Submission', dependent: :destroy has_many :mailings has_many :mailed_submitters, through: :mailings, source: :person - before_destroy :check_for_use, :check_if_public + before_destroy :check_if_public, :check_for_use before_update :check_if_public before_save :check_if_public @@ -40,7 +40,8 @@ class Survey < ApplicationRecord private def check_for_use - raise 'can not delete a survey that has responses in the system' if submissions.any? + # If it has submissions with responses + raise 'can not delete a survey that has responses in the system' if submissions.joins(:responses).any? end def check_if_public From 54ce43bf09d092e819e8ab682386c8bf7c625f36 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 17:21:54 -0400 Subject: [PATCH 42/99] PLAN-466 state the environment in devise emails --- .../devise/mailer/confirmation_instructions.html.erb | 6 +++++- app/views/devise/mailer/email_changed.html.erb | 8 ++++++-- app/views/devise/mailer/password_change.html.erb | 6 +++++- .../devise/mailer/reset_password_instructions.html.erb | 6 +++++- app/views/devise/mailer/unlock_instructions.html.erb | 6 +++++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb index dc55f64f6..4b07586ea 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.erb +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -1,5 +1,9 @@

    Welcome <%= @email %>!

    -

    You can confirm your account email through the link below:

    +

    You can confirm your account email for Chicon Planorama through the link below:

    <%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

    + +<% if !Rails.env.production? %> +

    Brought to you by <%= Rails.env%>

    +<% end %> diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb index 32f4ba803..fcbe4cb68 100644 --- a/app/views/devise/mailer/email_changed.html.erb +++ b/app/views/devise/mailer/email_changed.html.erb @@ -1,7 +1,11 @@

    Hello <%= @email %>!

    <% if @resource.try(:unconfirmed_email?) %> -

    We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

    +

    We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %> for Chicon Planorama.

    <% else %> -

    We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

    +

    We're contacting you to notify you that your email has been changed to <%= @resource.email %> for Chicon Planorama.

    +<% end %> + +<% if !Rails.env.production? %> +

    Brought to you by <%= Rails.env%>

    <% end %> diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb index 4b672fc17..0809e45d9 100644 --- a/app/views/devise/mailer/password_change.html.erb +++ b/app/views/devise/mailer/password_change.html.erb @@ -1,3 +1,7 @@

    Hello <%= @resource.name %>!

    -

    We're contacting you to notify you that your password has been changed.

    +

    We're contacting you to notify you that your password has been changed for Chicon Planorama.

    + +<% if !Rails.env.production? %> +

    Brought to you by <%= Rails.env%>

    +<% end %> diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb index 6939ae6f7..12cc85200 100644 --- a/app/views/devise/mailer/reset_password_instructions.html.erb +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -1,6 +1,6 @@

    Hello <%= @resource.name %>!

    -

    You, or someone on your behalf, has requested to change your password. You can do this by clicking the link below.

    +

    You, or someone on your behalf, has requested to change your password for Chicon Planorama. You can do this by clicking the link below.

    <%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

    @@ -9,3 +9,7 @@

    Sincerely,

    The Planorama Team

    + +<% if !Rails.env.production? %> +

    Brought to you by <%= Rails.env%>

    +<% end %> diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb index 41e148bf2..bf170af64 100644 --- a/app/views/devise/mailer/unlock_instructions.html.erb +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -1,7 +1,11 @@

    Hello <%= @resource.email %>!

    -

    Your account has been locked due to an excessive number of unsuccessful sign in attempts.

    +

    Your account has been locked due to an excessive number of unsuccessful sign in attempts on Chicon Planorama.

    Click the link below to unlock your account:

    <%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

    + +<% if !Rails.env.production? %> +

    Brought to you by <%= Rails.env%>

    +<% end %> From 2c689d37c7b2fefc0cf22baaed61673797714582 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 17:54:27 -0400 Subject: [PATCH 43/99] PLAN-207 do not indicate a problem when a wrong email is passed --- app/javascript/login/forgot_password.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/javascript/login/forgot_password.vue b/app/javascript/login/forgot_password.vue index 307aeb28e..ff2f173f8 100644 --- a/app/javascript/login/forgot_password.vue +++ b/app/javascript/login/forgot_password.vue @@ -86,8 +86,10 @@ export default { } }) .catch((error) => { - this.alert.text = SOMETHING_WENT_WRONG(this.configByName('email_reply_to_address')); - this.alert.visible = true; + // this.alert.text = SOMETHING_WENT_WRONG(this.configByName('email_reply_to_address')); + // this.alert.visible = true; + // Even if we have a problem we need to pretend that we do not + this.$router.push("/?alert=reset_sent"); }); } }, From e1434530b9815e4373fa92dabca6eb816f0b066a Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 18:09:52 -0400 Subject: [PATCH 44/99] PLAN-402 allow edit of survey title and description --- app/javascript/surveys/manage-survey.vue | 2 +- app/models/survey.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/javascript/surveys/manage-survey.vue b/app/javascript/surveys/manage-survey.vue index 9985dfc2d..c53331389 100644 --- a/app/javascript/surveys/manage-survey.vue +++ b/app/javascript/surveys/manage-survey.vue @@ -9,7 +9,7 @@ label="Survey Name" label-for="survey-name" > - + {{SURVEY_PUBLIC_NO_EDIT}} diff --git a/app/models/survey.rb b/app/models/survey.rb index ff3c3dcb3..932405041 100644 --- a/app/models/survey.rb +++ b/app/models/survey.rb @@ -47,6 +47,8 @@ def check_if_public return if self.new_record? return if self.public && self.public_changed? # to allow for changing to "published" + return if self.public && self.name_changed? + return if self.public && self.description_changed? raise 'can not delete or update a survey that is public' if self.public end From 0e834353c4ce68e765e2fc8597bb97430df22e04 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 6 Jul 2022 18:39:25 -0400 Subject: [PATCH 45/99] fix promise assignment --- app/javascript/conflicts/session_conflicts.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/javascript/conflicts/session_conflicts.vue b/app/javascript/conflicts/session_conflicts.vue index 34faea219..77a270992 100644 --- a/app/javascript/conflicts/session_conflicts.vue +++ b/app/javascript/conflicts/session_conflicts.vue @@ -104,14 +104,16 @@ export default { this.conflicts = [] this.conflicts_with = [] this.clear() - let p1 = this.get_conflicts({session_id: sessionId}).then( + let p1 = this.get_conflicts({session_id: sessionId}); + p1.then( (conflicts) => { this.conflicts = Object.values(conflicts).filter( obj => (typeof obj.json === 'undefined') ) } ) - let p2 = this.get_conflicts_with({session_id: sessionId}).then( + let p2 = this.get_conflicts_with({session_id: sessionId}); + p2.then( (conflicts) => { this.conflicts_with = Object.values(conflicts).filter( obj => (typeof obj.json === 'undefined') From f7b2827d2ab6520927b18af10e4fe081c7286606 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Wed, 6 Jul 2022 20:14:31 -0400 Subject: [PATCH 46/99] PLAN-446 tweaks to participant views --- app/javascript/people/person_tabs.vue | 2 +- app/javascript/profile/person_schedule.vue | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/javascript/people/person_tabs.vue b/app/javascript/people/person_tabs.vue index 36779118c..8bddfc476 100644 --- a/app/javascript/people/person_tabs.vue +++ b/app/javascript/people/person_tabs.vue @@ -41,7 +41,7 @@ :person_id="person.id" > - + diff --git a/app/javascript/profile/person_schedule.vue b/app/javascript/profile/person_schedule.vue index b6f956491..83c98b684 100644 --- a/app/javascript/profile/person_schedule.vue +++ b/app/javascript/profile/person_schedule.vue @@ -3,7 +3,7 @@
    -

    Draft Schedule

    +

    Live Schedule

    {{ anyOpen ? 'Collapse all' : 'Show all'}}
    @@ -16,8 +16,8 @@
    Title
    {{session.title}}
    Participants (with contact information where allowed)
    -
    {{sa.person.publication_name}}{{ isModerator(sa) ? " (m)" : ""}} {{sa.person.pronouns}} - {{ sa.person.contact_email ? sa.person.contact_email : 'permission not given'}}
    -
    None Assigned
    +
    {{sa.person.published_name}}{{ isModerator(sa) ? " (m)" : ""}} {{sa.person.pronouns}} - {{ sa.person.contact_email ? sa.person.contact_email.email : 'permission not given'}}
    +
    None Assigned
    Description
    Space/Time
    @@ -80,8 +80,9 @@ export default { allButton() { const newDir = !this.anyOpen; Object.keys(this.open).forEach((id) => { - this.open[id] = newDir; - console.log(`changed ${id} to ${this.open[id]}`) + if (this.open[id] !== newDir) { + this.$root.$emit('bv::toggle::collapse', id) + } }) } }, From 60bc29a0f488574640ee5203d3e7fd06fb634369 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Wed, 6 Jul 2022 20:20:01 -0400 Subject: [PATCH 47/99] PLAN-402 move description to top section --- app/javascript/surveys/edit-survey.vue | 9 --------- app/javascript/surveys/manage-survey.vue | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/javascript/surveys/edit-survey.vue b/app/javascript/surveys/edit-survey.vue index 14120a46c..b8e2f614c 100644 --- a/app/javascript/surveys/edit-survey.vue +++ b/app/javascript/surveys/edit-survey.vue @@ -1,14 +1,5 @@ @@ -51,16 +56,19 @@ import TableVue from '../components/table_vue'; import ModalForm from '../components/modal_form'; import TooltipOverflow from '../shared/tooltip-overflow'; import { session_columns as columns } from './session'; -import { sessionModel as model } from '@/store/session.store' +import { NEW_SESSION, sessionModel as model } from '@/store/session.store' import dateTimeMixin from '../components/date_time.mixin' import { areaMixin } from './session_fields.mixin'; +import PlanoModal from '@/components/plano_modal.vue'; +import { mapActions } from 'vuex'; export default { name: 'SessionTable', components: { TableVue, TooltipOverflow, - ModalForm + ModalForm, + PlanoModal, }, mixins: [ dateTimeMixin, @@ -68,10 +76,21 @@ export default { ], data: () => ({ columns, - model + model, + newSessionTitle: null }), methods: { + ...mapActions({ + newSession: NEW_SESSION + }), + openNewModal() { + this.newSessionTitle = null; + this.$root.$emit('bv::show::modal', 'add-session'); + }, onNew() { + this.newSession({title: this.newSessionTitle}).then((data) => { + this.$router.push(`/sessions/edit/${data.id}`) + }) }, onSave() { } From 50e7cf11a2920f305656a7d525ce61e05e631632 Mon Sep 17 00:00:00 2001 From: ralphlevan Date: Wed, 6 Jul 2022 21:30:13 -0400 Subject: [PATCH 49/99] PLAN-430 added the two missing Scheduling reports as commented out entries --- app/javascript/reports/reports_screen.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/javascript/reports/reports_screen.vue b/app/javascript/reports/reports_screen.vue index e19792e9e..7ed8dcd2a 100644 --- a/app/javascript/reports/reports_screen.vue +++ b/app/javascript/reports/reports_screen.vue @@ -56,7 +56,6 @@
  • Panels with too many Participants
  • -

    Conflicts

    @@ -92,6 +91,12 @@
  • Schedule by Participant
  • + +
    From 83a178c7ea9984da4264aae2e623cb0215b41478 Mon Sep 17 00:00:00 2001 From: ralphlevan Date: Wed, 6 Jul 2022 22:22:38 -0400 Subject: [PATCH 50/99] PLAN-239 The clone button is disabled if selected_items.length===0 --- app/javascript/components/table_vue.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/components/table_vue.vue b/app/javascript/components/table_vue.vue index 2d03a4a16..a2c3998dc 100644 --- a/app/javascript/components/table_vue.vue +++ b/app/javascript/components/table_vue.vue @@ -27,7 +27,7 @@
    - +
    From 9cea962fec187295f0df609ad3bc3dddb250d0f1 Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 7 Jul 2022 09:04:50 -0400 Subject: [PATCH 51/99] paper trail audit tables should use uuids --- db/migrate/20220707124302_fix_audit_ids.rb | 15 +++++++++++++++ db/structure.sql | 15 ++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20220707124302_fix_audit_ids.rb diff --git a/db/migrate/20220707124302_fix_audit_ids.rb b/db/migrate/20220707124302_fix_audit_ids.rb new file mode 100644 index 000000000..2e984deff --- /dev/null +++ b/db/migrate/20220707124302_fix_audit_ids.rb @@ -0,0 +1,15 @@ +require 'webdack/uuid_migration/helpers' + +class FixAuditIds < ActiveRecord::Migration[6.1] + # fix columns in audit table to use the correct id type for the models + def up + columns_to_uuid :audit_people_versions, :item_id + columns_to_uuid :audit_published_session_versions, :item_id + columns_to_uuid :audit_session_versions, :item_id + columns_to_uuid :audit_survey_versions, :item_id + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/structure.sql b/db/structure.sql index a071f3736..024ba0248 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -343,7 +343,7 @@ CREATE TABLE public.areas ( CREATE TABLE public.audit_people_versions ( id bigint NOT NULL, item_type character varying NOT NULL, - item_id bigint NOT NULL, + item_id uuid NOT NULL, event character varying NOT NULL, whodunnit character varying, object json, @@ -378,7 +378,7 @@ ALTER SEQUENCE public.audit_people_versions_id_seq OWNED BY public.audit_people_ CREATE TABLE public.audit_published_session_versions ( id bigint NOT NULL, item_type character varying NOT NULL, - item_id bigint NOT NULL, + item_id uuid NOT NULL, event character varying NOT NULL, whodunnit character varying, object json, @@ -413,7 +413,7 @@ ALTER SEQUENCE public.audit_published_session_versions_id_seq OWNED BY public.au CREATE TABLE public.audit_session_versions ( id bigint NOT NULL, item_type character varying NOT NULL, - item_id bigint NOT NULL, + item_id uuid NOT NULL, event character varying NOT NULL, whodunnit character varying, object json, @@ -448,7 +448,7 @@ ALTER SEQUENCE public.audit_session_versions_id_seq OWNED BY public.audit_sessio CREATE TABLE public.audit_survey_versions ( id bigint NOT NULL, item_type character varying NOT NULL, - item_id bigint NOT NULL, + item_id uuid NOT NULL, event character varying NOT NULL, whodunnit character varying, object json, @@ -1205,7 +1205,7 @@ CREATE VIEW public.person_exclusion_conflicts AS LEFT JOIN public.person_exclusions pe ON ((pe.person_id = person_schedules.person_id))) JOIN public.exclusions_sessions es ON ((es.exclusion_id = pe.exclusion_id))) LEFT JOIN public.sessions s ON ((s.id = es.session_id))) - WHERE ((person_schedules.session_id <> s.id) AND (person_schedules.start_time >= s.start_time) AND ((person_schedules.start_time < (s.start_time + ((s.duration || ' minute'::text))::interval)) OR ((person_schedules.end_time > s.start_time) AND (person_schedules.end_time <= (s.start_time + ((s.duration || ' minute'::text))::interval))))); + WHERE ((person_schedules.session_id <> s.id) AND (((person_schedules.start_time >= s.start_time) AND (person_schedules.start_time < (s.start_time + ((s.duration || ' minute'::text))::interval))) OR ((person_schedules.end_time > s.start_time) AND (person_schedules.end_time <= (s.start_time + ((s.duration || ' minute'::text))::interval))))); -- @@ -1252,7 +1252,7 @@ CREATE VIEW public.person_schedule_conflicts AS ps2.session_assignment_name AS conflict_session_assignment_name, ps2.room_id AS conflict_room_id FROM (public.person_schedules ps1 - JOIN public.person_schedules ps2 ON (((ps2.person_id = ps1.person_id) AND (ps2.session_id <> ps1.session_id) AND (ps2.start_time >= ps1.start_time) AND ((ps2.start_time <= ps1.end_time) OR ((ps2.end_time >= ps1.start_time) AND (ps2.end_time <= ps1.end_time)))))); + JOIN public.person_schedules ps2 ON (((ps2.person_id = ps1.person_id) AND (ps2.session_id <> ps1.session_id) AND (ps2.start_time >= ps1.start_time) AND ((ps2.start_time < ps1.end_time) OR ((ps2.end_time > ps1.start_time) AND (ps2.end_time <= ps1.end_time)))))); -- @@ -3146,6 +3146,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220628121934'), ('20220629132145'), ('20220630032544'), -('20220704121816'); +('20220704121816'), +('20220707124302'); From d530566aedc71b3f78346eceedea90ea9bf58989 Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 7 Jul 2022 16:00:18 -0400 Subject: [PATCH 52/99] fix to exclude reserve and rejected --- app/controllers/people_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 8bbf2441f..19eaf91dd 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -27,9 +27,10 @@ def draft_sessions person = Person.find params[:person_id] if person - reserved = SessionAssignmentRoleType.find_by(name: 'Reserve') sessions = person.sessions .eager_load({participant_assignments: :person}, :format, :session_areas) + .where("session_assignments.session_assignment_role_type_id is not null AND session_assignments.state != 'rejected'") + .where("session_assignments.session_assignment_role_type_id not in (select id from session_assignment_role_type where session_assignment_role_type.name = 'Reserve')") .where("sessions.start_time is not null AND sessions.room_id is not null") .order("sessions.start_time asc, sessions.title asc") From 633fd3dab6693210580add7a2e33ec7e93e05dee Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 7 Jul 2022 16:41:46 -0400 Subject: [PATCH 53/99] PLAN-446 filter out emails if can_share is false --- app/serializers/person_serializer.rb | 5 +++-- app/serializers/plano/serializer.rb | 19 +++++++++++++++++++ app/services/access_control_service.rb | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/app/serializers/person_serializer.rb b/app/serializers/person_serializer.rb index 78d2f2839..a066cc6c8 100644 --- a/app/serializers/person_serializer.rb +++ b/app/serializers/person_serializer.rb @@ -2,7 +2,7 @@ class PersonSerializer #< ActiveModel::Serializer include JSONAPI::Serializer include ::Plano::Serializer - attributes :primary_email, :contact_email + shareable_attributes :primary_email, :contact_email protected_attributes :id, :lock_version, :name, :name_sort_by, :name_sort_by_confirmed, @@ -55,7 +55,8 @@ class PersonSerializer #< ActiveModel::Serializer person.base_tags.collect(&:name) end - has_many :email_addresses, lazy_load_data: true, serializer: EmailAddressSerializer, + has_many :email_addresses, if: Proc.new { |record, params| AccessControlService.shared_attribute_access?(instance: record, person: params[:current_person]) }, + lazy_load_data: true, serializer: EmailAddressSerializer, links: { self: -> (object, params) { "#{params[:domain]}/person/#{object.id}" diff --git a/app/serializers/plano/serializer.rb b/app/serializers/plano/serializer.rb index c55dfe015..8f0dffa1f 100644 --- a/app/serializers/plano/serializer.rb +++ b/app/serializers/plano/serializer.rb @@ -34,11 +34,30 @@ def protected_attribute(*attributes_list, &block) # end end + def shareable_attribute(*attributes_list, &block) + proc = Proc.new { |record, params| + # logic to test if the person has access + AccessControlService.shared_attribute_access?( + instance: record, + person: params[:current_person] + ) + } + # if proc is at the end remove it and add the new one + new_list = attributes_list + [{if: proc}] + attributes(*new_list, &block) + end + def protected_attributes(*attributes_list, &block) attributes_list.each do |attr| protected_attribute(attr, &block) end end + + def shareable_attributes(*attributes_list, &block) + attributes_list.each do |attr| + shareable_attribute(attr, &block) + end + end end end end diff --git a/app/services/access_control_service.rb b/app/services/access_control_service.rb index 58b70f50c..118d5d58f 100644 --- a/app/services/access_control_service.rb +++ b/app/services/access_control_service.rb @@ -165,4 +165,19 @@ def self.allowed_attribute_access?(instance:, attributes:, person:) res end + + def self.shared_attribute_access?(instance:, person:) + return true if person.convention_roles.collect(&:role).include?('admin') + + if instance.is_a?(Person) + return true if instance.id == person.id + + return true if instance.can_share + end + + return false if person.convention_roles.count == 0 + return false if (person.convention_roles.count == 1) && person.convention_roles.collect(&:role).include?('participant') + + true + end end From defa43b21be2dbcf0c26dfb32abd2fd5c9246ed0 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Thu, 7 Jul 2022 19:42:24 -0400 Subject: [PATCH 54/99] fix missing li --- app/javascript/reports/reports_screen.vue | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/javascript/reports/reports_screen.vue b/app/javascript/reports/reports_screen.vue index 7ed8dcd2a..02c83d92d 100644 --- a/app/javascript/reports/reports_screen.vue +++ b/app/javascript/reports/reports_screen.vue @@ -18,7 +18,6 @@
  • Participants and Do Not Assign With
  • -
  • Participants over Daily Limits
  • @@ -50,12 +49,13 @@
  • Sessions with Participants not Scheduled -
  • - Panels with too few Participants -
  • -
  • - Panels with too many Participants -
  • + +
  • + Panels with too few Participants +
  • +
  • + Panels with too many Participants +
  • Conflicts

    @@ -91,12 +91,12 @@
  • Schedule by Participant
  • - - + + -->
    From ea141201cdae003b5a87d66af9bd852c273713a2 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Thu, 7 Jul 2022 20:31:19 -0400 Subject: [PATCH 55/99] order participants and add spinner --- app/javascript/profile/person_schedule.vue | 96 +++++++++++++++------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/app/javascript/profile/person_schedule.vue b/app/javascript/profile/person_schedule.vue index 83c98b684..53b58fcbd 100644 --- a/app/javascript/profile/person_schedule.vue +++ b/app/javascript/profile/person_schedule.vue @@ -9,32 +9,34 @@
    -
    - - -
    -
    Title
    -
    {{session.title}}
    -
    Participants (with contact information where allowed)
    -
    {{sa.person.published_name}}{{ isModerator(sa) ? " (m)" : ""}} {{sa.person.pronouns}} - {{ sa.person.contact_email ? sa.person.contact_email.email : 'permission not given'}}
    -
    None Assigned
    -
    Description
    -
    -
    Space/Time
    -
    {{session.room.name || "Room Name Here"}} {{formatStartTime(session)}}
    -
    Duration
    -
    {{session.duration}} minutes
    -
    Session Environment
    -
    {{SESSION_ENVIRONMENT[session.environment]}}
    -
    Session Format
    -
    {{session.format.name || session.format_id}}
    -
    Session Area(s)
    -
    {{area}}
    -
    None Selected
    -
    Schedule Notes
    -
    -
    -
    +
    + + + +
    +
    Title
    +
    {{session.title}}
    +
    Participants (with contact information where allowed)
    +
    {{sa.person.published_name}}{{ isModerator(sa) ? " (m)" : isInvisible(sa) ? " (i)" : ""}} {{sa.person.pronouns}} - {{ sa.person.contact_email ? sa.person.contact_email.email : 'permission not given'}}
    +
    None Assigned
    +
    Description
    +
    +
    Space/Time
    +
    {{session.room.name || "Room Name Here"}} {{formatStartTime(session)}}
    +
    Duration
    +
    {{session.duration}} minutes
    +
    Session Environment
    +
    {{SESSION_ENVIRONMENT[session.environment]}}
    +
    Session Format
    +
    {{session.format.name || session.format_id}}
    +
    Session Area(s)
    +
    {{area}}
    +
    None Selected
    +
    Schedule Notes
    +
    +
    +
    +
    @@ -63,14 +65,18 @@ export default { sessions: {}, open: {}, model, - SESSION_ENVIRONMENT + SESSION_ENVIRONMENT, + loading: false }), computed: { - amIOpen(id) { - return this.open[id]; - }, anyOpen() { return Object.values(this.open).some(v => v) + }, + heightHelper() { + if (this.loading) { + return {height: '200px', padding: "5rem"} + } + return {}; } }, methods: { @@ -84,15 +90,45 @@ export default { this.$root.$emit('bv::toggle::collapse', id) } }) + }, + orderedParticipants(session) { + const sas = Object.values(session.participant_assignments); + sas.sort((a, b) => { + if (a.session_assignment_role_type_id !== b.session_assignment_role_type_id) { + if (this.isModerator(a)) { + return -1; + } else if (this.isModerator(b)) { + return 1; + } else if (this.isParticipant(a)) { + return -1; + } else if (this.isParticipant(b)) { + return 1; + } + return 1; + } else { + const nameA = a.person.published_name_sort_by || a.person.published_name + const nameB = b.person.published_name_sort_by || a.person.published_name + console.log(`${nameA} vs ${nameB}`) + if (nameA < nameB) { + return -1; + } else if (nameB < nameA) { + return 1; + } + return 0; + } + }) + return sas; } }, mounted() { if(this.selected) { + this.loading = true; this.get(`/person/${this.selected.id}/draft_sessions`).then(data => { console.log(data); const {_jv, ...filtered_data} = data; this.sessions = filtered_data; this.open = Object.keys(this.sessions).reduce((p, c) => ({...p, [c]: false }), {}); + this.loading = false; }) } } From 5c7182fea44c95c6f95d141869876e7c89671c72 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Thu, 7 Jul 2022 20:35:32 -0400 Subject: [PATCH 56/99] Update app/javascript/profile/person_schedule.vue --- app/javascript/profile/person_schedule.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/app/javascript/profile/person_schedule.vue b/app/javascript/profile/person_schedule.vue index 53b58fcbd..dd2ffef95 100644 --- a/app/javascript/profile/person_schedule.vue +++ b/app/javascript/profile/person_schedule.vue @@ -108,7 +108,6 @@ export default { } else { const nameA = a.person.published_name_sort_by || a.person.published_name const nameB = b.person.published_name_sort_by || a.person.published_name - console.log(`${nameA} vs ${nameB}`) if (nameA < nameB) { return -1; } else if (nameB < nameA) { From 3a1a97a0f3aae33d46be8a306ec928305c435dc2 Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Thu, 7 Jul 2022 20:50:37 -0400 Subject: [PATCH 57/99] PLAN-523 make admin tab visible to staff --- app/javascript/people/person_tabs.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/people/person_tabs.vue b/app/javascript/people/person_tabs.vue index 8bddfc476..86b548e02 100644 --- a/app/javascript/people/person_tabs.vue +++ b/app/javascript/people/person_tabs.vue @@ -44,7 +44,7 @@ - + From 46a66b1d1c3d3252919aa6ae565f9c14ae95045d Mon Sep 17 00:00:00 2001 From: Gail Terman Date: Thu, 7 Jul 2022 21:10:43 -0400 Subject: [PATCH 58/99] PLAN-528 fix scoping on survey question labels --- app/javascript/surveys/edit-survey-question.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/surveys/edit-survey-question.vue b/app/javascript/surveys/edit-survey-question.vue index f0af0f8ea..d46668311 100644 --- a/app/javascript/surveys/edit-survey-question.vue +++ b/app/javascript/surveys/edit-survey-question.vue @@ -233,7 +233,7 @@ export default { } -