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/conflicts/session_conflicts_controller.rb b/app/controllers/conflicts/session_conflicts_controller.rb index d7b8bbd27..51d989103 100644 --- a/app/controllers/conflicts/session_conflicts_controller.rb +++ b/app/controllers/conflicts/session_conflicts_controller.rb @@ -24,7 +24,9 @@ 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 != 'room_conflict' OR (session_conflicts.conflict_type = 'room_conflict' AND session_conflicts.session_start_time != session_conflicts.conflict_session_start_time)") .distinct + # .where("session_conflicts.conflict_type != 'person_schedule_conflict' and session_conflicts.conflict_type != 'person_back_to_back'") meta = {} meta[:total] = collection.count diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 4b2331db8..19eaf91dd 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -21,6 +21,41 @@ def me ) end + def draft_sessions + authorize current_person, policy_class: policy_class + + person = Person.find params[:person_id] + + if person + 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") + + render json: SessionSerializer.new( + sessions, + { + # need assgnments and rooms etc + include: [ + :format, + :room, + :session_areas, + :'session_areas.area', + :participant_assignments, + :'participant_assignments.person' + ], + 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/controllers/reports/conflict_reports_controller.rb b/app/controllers/reports/conflict_reports_controller.rb index ef7a5246a..a2783becc 100644 --- a/app/controllers/reports/conflict_reports_controller.rb +++ b/app/controllers/reports/conflict_reports_controller.rb @@ -1,6 +1,92 @@ 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', + 'Session Duration', + 'Room', + 'Person', + '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.session&.duration, + conflict.room&.name, + conflict.person_published_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', + 'Session Duration', + 'Room', + 'Person', + 'Conflict Type' + ] + ) + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [ + nil, nil, date_time_style, nil, nil, 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.session_duration, + conflict.room&.name, + conflict.person_published_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 @@ -9,6 +95,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) @@ -69,6 +156,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) @@ -153,13 +241,14 @@ def back_to_back_to_back 'middle_areas_list.area_list as middle_area_list', 'conflict_areas_list.area_list as conflict_area_list' ) - .includes(:room, :middle_room, :conflict_room) - .references(:room, :middle_room, :conflict_room) - .joins(joins) - .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") - .where("middle_session_assignment_name is null or middle_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, start_time asc') + .includes(:room, :middle_room, :conflict_room) + .references(:room, :middle_room, :conflict_room) + .joins(joins) + .where("session_assignment_name is null or session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .where("middle_session_assignment_name is null or middle_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .where("conflict_session_assignment_name is null or conflict_session_assignment_name in ('Moderator', 'Participant', 'Invisible')") + .where("(b2b_id not in (select conflict_id from ignored_conflicts)) OR (conflict_b2b_id not in (select conflict_id from ignored_conflicts))") + .order('published_name asc, start_time asc') # workbook = FastExcel.open(constant_memory: true) @@ -255,16 +344,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") @@ -346,6 +436,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') @@ -357,6 +448,7 @@ def people_double_booked [ 'Name', 'Published Name', + 'Participant Status', 'Time', 'Session', 'Area', @@ -368,13 +460,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('; '), @@ -413,7 +506,9 @@ def people_outside_availability 'areas_list.area_list' ) .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') @@ -424,25 +519,29 @@ def people_outside_availability worksheet.append_row( [ 'Name', - 'Pub Name', + 'Published Name', + 'Participant Status', 'Session', 'Area', - 'Start Time' - + 'Start Time', + 'Session 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 ) diff --git a/app/controllers/reports/session_reports_controller.rb b/app/controllers/reports/session_reports_controller.rb index 59b83a731..d0d2d9e6b 100644 --- a/app/controllers/reports/session_reports_controller.rb +++ b/app/controllers/reports/session_reports_controller.rb @@ -234,6 +234,7 @@ def participants_over_session_limits [ 'Name', 'Published Name', + 'Participant Status', 'Day', 'Session Count', "Person's Limit" @@ -245,6 +246,7 @@ def participants_over_session_limits [ person.name, person.published_name, + person.con_state, person.day ? person.day : 'All', person.session_count, person.max_sessions @@ -268,6 +270,7 @@ def participants_over_con_session_limits [ 'Name', 'Published Name', + 'Participant Status', 'Session Count', 'Con Limit' ] @@ -278,6 +281,7 @@ def participants_over_con_session_limits [ person.name, person.published_name, + person.con_state, person.session_count, 6 ] @@ -294,27 +298,39 @@ def panels_with_too_few_people workbook = FastExcel.open(constant_memory: true) worksheet = workbook.add_worksheet("Panels with too Few People") + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [ + nil, nil, date_time_style, nil, nil, nil, nil + ] sessions = ::ReportsService.panels_with_too_few_people # Session name, Area, session start, participant count, participant count lower bound, list of participants worksheet.append_row( [ - 'Title', + 'Session', 'Areas', + 'Start Time', 'Participant Count', - 'List of Participants' + 'Participant Count Lower Bound', + 'Participants', + 'Moderators' ] ) - # has_many :submissions + moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') + participant = SessionAssignmentRoleType.find_by(name: 'Participant') sessions.each do |session| worksheet.append_row( [ session.title, session.area_list.sort.join(';'), + session.start_time ? FastExcel.date_num(session.start_time, session.start_time.in_time_zone.utc_offset) : '', session.nbr_assignments, - session.session_assignments.collect{|a| a.person.published_name}.join(';') - ] + 3, + 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 == moderator.id}.collect{|a| a.person.published_name}.join(';') + ], + styles ) end @@ -328,6 +344,11 @@ def panels_with_too_many_people workbook = FastExcel.open(constant_memory: true) worksheet = workbook.add_worksheet("Panels with too Many People") + date_time_style = workbook.number_format("d mmm yyyy h:mm") + styles = [ + nil, nil, date_time_style, nil, nil, nil + ] + sessions = ::ReportsService.panels_with_too_many_people # Session name, Area, session start, participant count, participant count lower bound, list of participants @@ -335,20 +356,29 @@ def panels_with_too_many_people [ 'Session', 'Areas', + 'Start Time', 'Participant Count', - 'List of Participants' + 'Participant Count Upper Bound', + 'Participants', + 'Moderators' ] ) # has_many :submissions + moderator = SessionAssignmentRoleType.find_by(name: 'Moderator') + participant = SessionAssignmentRoleType.find_by(name: 'Participant') sessions.each do |session| worksheet.append_row( [ session.title, session.area_list.sort.join(';'), + FastExcel.date_num(session.start_time, session.start_time.in_time_zone.utc_offset), session.nbr_assignments, - session.session_assignments.collect{|a| a.person.published_name}.join(';') - ] + 6, + 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 == moderator.id}.collect{|a| a.person.published_name}.join(';') + ], + styles ) end diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index e0dcecf85..b0e20798b 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 @@ -14,7 +15,9 @@ def people_and_submissions people = Person.includes( {submissions: :survey}, :primary_email - ).references( + ) + .where("people.con_state not in (?)", ['declined', 'rejected']) + .references( :submissions ).order("people.name") @@ -90,10 +93,12 @@ def sessions_with_participants worksheet.append_row( [ 'Session', + 'Session Type/Format', 'Areas', 'Moderators', 'Participants', - 'Reserves' + 'Reserves', + 'Scehduled' ] ) @@ -104,10 +109,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 @@ -129,72 +136,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 + + 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 + ) + ] - # 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') + # 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") + workbook = FastExcel.open(constant_memory: true) + worksheet = workbook.add_worksheet("Schedule by Room then Time") + worksheet.append_row( + [ + 'Session', + 'Area', + 'Start Time', + 'Session 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].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 +220,70 @@ 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") + .where("person_schedules.con_state not in (?)", ['declined', 'rejected']) + .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") + + worksheet.append_row( + [ + 'Name', + 'Published Name', + 'Participant Status', + 'Session', + 'Area', + 'Start Time', + 'Room', + 'Moderator', + 'Invisible', + ] + ) - send_data workbook.read_string, - filename: "ScheduleByParticipant#{Time.now.strftime('%m-%d-%Y')}.xlsx", - disposition: 'attachment' + 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 @@ -297,7 +300,7 @@ def assigned_sessions_by_participant {session_assignments: :session} ).where( "session_assignments.session_assignment_role_type_id is not null" - ).order("people.name") + ).where("people.con_state not in (?)", ['declined', 'rejected']).order("people.name") workbook = FastExcel.open(constant_memory: true) worksheet = workbook.add_worksheet("Assigned Sessions") @@ -306,8 +309,10 @@ def assigned_sessions_by_participant [ 'Name', 'Published Name', + 'Participant Status', 'Session', - 'Role' + 'Role', + 'Scheduled' ] ) @@ -317,8 +322,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 @@ -333,57 +340,57 @@ 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" + ).where( + "people.con_state not in (?)", ['declined','rejected'] + ) + .where("people.con_state not in (?)", ['declined', 'rejected']) - 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', + 'Participant Status', + '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.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"), + 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 @@ -397,8 +404,10 @@ def participant_selections assignments = SessionAssignment .joins(:person) - .includes([{session: :areas}, :person]) - .where(interested: true).order("people.name") + .includes([{session: :areas}, :person, :session_assignment_role_type]) + .where(interested: true) + .where("people.con_state not in (?)", ['declined', 'rejected']) + .order("people.name") workbook = FastExcel.open(constant_memory: true) worksheet = workbook.add_worksheet("Participant Selections") @@ -407,10 +416,13 @@ def participant_selections [ 'Name', 'Published Name', + 'Participant Status', 'Session', 'Ranking', 'Ranking Notes', - 'Areas' + 'Areas', + 'Assigned', + 'Scheduled' ] ) assignments.each do |assignment| @@ -418,10 +430,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 @@ -443,6 +458,7 @@ def session_selections sessions = Session .eager_load(:areas, {session_assignments: [:person]}) .where('session_assignments.interested': true) + .where("people.con_state not in (?)", ['declined', 'rejected']) .order('sessions.title') workbook = FastExcel.open(constant_memory: true) @@ -453,6 +469,7 @@ def session_selections 'Title', 'Who is Interested', 'Who is Interested (Pub Name)', + 'Participant Status', 'Ranking', 'Notes', 'Areas' @@ -466,6 +483,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("; ") @@ -525,6 +543,7 @@ def participant_do_not_assign_with ) .where("people.do_not_assign_with is not null and people.do_not_assign_with <> ''") .where("session_assignment_role_type.name in (?)", ['Moderator', 'Participant', "Invisible"]) + .where("people.con_state not in (?)", ['declined', 'rejected']) .order("people.published_name asc") workbook = FastExcel.open(constant_memory: true) @@ -563,4 +582,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 diff --git a/app/controllers/session_assignments_controller.rb b/app/controllers/session_assignments_controller.rb index ab45d3cfa..b0491b42c 100644 --- a/app/controllers/session_assignments_controller.rb +++ b/app/controllers/session_assignments_controller.rb @@ -28,6 +28,41 @@ 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 + + # sort by pub name within role + # except for unassigned where they are ordered by rank and then name inside each rank. + 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, + case when (session_assignment_role_type is null AND session_assignments.interested) then session_assignments.interest_ranking + end asc, + people.published_name asc + ) + + Arel.sql(order_str.squish) + end + def serializer_includes if params[:session_id] # remove included data for now to speed up loads @@ -47,7 +82,8 @@ def serializer_includes def includes [ :person, - :session + :session, + :session_assignment_role_type ] end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5b797e343..ee162f40f 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -139,10 +139,24 @@ 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, :room, + :room_set, :session_areas, :'session_areas.area' # Do not include assignment in the JSON by default as that can slow client down, diff --git a/app/javascript/components/email_address_editor.vue b/app/javascript/components/email_address_editor.vue index c5f6103ec..cebea72c3 100644 --- a/app/javascript/components/email_address_editor.vue +++ b/app/javascript/components/email_address_editor.vue @@ -28,6 +28,7 @@ :checked="isdefault" class="mt-2 pt-1" :disabled='disabled' + :name="radioGroup" > @@ -56,6 +57,10 @@ export default { disabled: { type: Boolean, default: false + }, + radioGroup: { + type: String, + default: 'email-address-make-primary' } }, data: () => ({ diff --git a/app/javascript/components/email_addresses_editor.vue b/app/javascript/components/email_addresses_editor.vue index fbc0b70f3..b18f7ba89 100644 --- a/app/javascript/components/email_addresses_editor.vue +++ b/app/javascript/components/email_addresses_editor.vue @@ -15,6 +15,7 @@ :can-delete="false" @input="onInput" :disabled="disabled" + :radioGroup="radioGroup" >
@@ -25,6 +26,7 @@ @delete="onDelete(email)" @input="onInput(email)" :disabled="disabled" + :radioGroup="radioGroup" >
@@ -60,7 +62,11 @@ export default { type: Boolean, default: false }, - disabled: false + disabled: false, + id: { + type: String, + default: 'email-addresses-editor' + } }, data() { return { @@ -81,6 +87,9 @@ export default { set: function(val) { // console.debug("****** SET", val) } + }, + radioGroup() { + return `${this.id}-make-primary`; } }, methods: { @@ -99,7 +108,10 @@ export default { () => { this.setLists() } - ) + ).catch((err) => { + console.log("i caught an error", err) + this.setLists() + }) } else { this.addEmail(arg).then( () => { @@ -115,7 +127,7 @@ export default { ).then(data => { this.emails = Object.values(data.email_addresses) this.additional = this.emails.filter(em => !em.isdefault) - this.$emit('input', data) + // this.$emit('input', data) }) }, onNew() { diff --git a/app/javascript/components/table_vue.vue b/app/javascript/components/table_vue.vue index 30eaea3bb..a2c3998dc 100644 --- a/app/javascript/components/table_vue.vue +++ b/app/javascript/components/table_vue.vue @@ -27,7 +27,7 @@
- +
@@ -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() { diff --git a/app/javascript/conflicts/session_conflicts.vue b/app/javascript/conflicts/session_conflicts.vue index 47517506b..77a270992 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,33 @@ 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}); + p1.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}); + p2.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) { @@ -137,10 +149,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) { diff --git a/app/javascript/constants/strings.js b/app/javascript/constants/strings.js index e0d47ce23..d6585b02c 100644 --- a/app/javascript/constants/strings.js +++ b/app/javascript/constants/strings.js @@ -240,6 +240,7 @@ module.exports = { languages_fluent_in: "Languages spoken" }, PERSON_SAVE_SUCCESS: "Profile record saved successfully", + PERSON_NEVER_LOGGED_IN: "Never logged in", SURVEY_REDIRECT: "Unfortunately due to the browser refreshing we have lost any answers you filled in. Please fill the survey out again.", SURVEY_PUBLIC_NO_EDIT: "You cannot edit a published survey. Close the survey to enable editing.", 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"); }); } }, 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', 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..4a4c8acbb 100644 --- a/app/javascript/people/people_sidebar.vue +++ b/app/javascript/people/people_sidebar.vue @@ -14,8 +14,8 @@ - - + + + {{title}} + + + + + + + + + + + + + + + + diff --git a/app/javascript/reports/reports_screen.vue b/app/javascript/reports/reports_screen.vue index 71c24882c..2cf56a1fa 100644 --- a/app/javascript/reports/reports_screen.vue +++ b/app/javascript/reports/reports_screen.vue @@ -12,25 +12,18 @@
  • Assigned Sessions by Participant
  • -
  • - Schedule by Participant -
  • People and Survey Submissions
  • Participants and Do Not Assign With
  • -
  • Participants over Daily Limits
  • Participants over Con Limit
  • -
  • - Person scheduled against a conflict item -
  • Non-Accepted Participants on Scheduled Sessions
  • @@ -57,22 +50,25 @@
  • Sessions with Participants not Scheduled
  • - - -

    Conflicts

    - + +

    Conflicts

    + @@ -89,6 +91,15 @@
  • Schedule by Room then Time
  • +
  • + Schedule by Participant +
  • + +
    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 @@ @@ -50,22 +55,25 @@ export default { } }, data: () => ({ - sessionModel + sessionModel, + 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); }, 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) { 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..6ab733f83 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))) }" > -
    +
    { - 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 ec4a597ff..65d105537 100644 --- a/app/javascript/schedule/schedule_screen.vue +++ b/app/javascript/schedule/schedule_screen.vue @@ -135,13 +135,13 @@ export default { let filter = { "op": "all", "queries":[ - { - "op": "any", - "queries":[ - ["start_time", "is null"], - ["room_id", "is null"] - ] - }, + // { + // "op": "any", + // "queries":[ + // ["start_time", "is null"], + // ["room_id", "is null"] + // ] + // }, ["duration", ">", "0"], ["status", "!=", "dropped"] ] @@ -154,10 +154,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 diff --git a/app/javascript/schedule/schedule_session_search.vue b/app/javascript/schedule/schedule_session_search.vue index 84baf8659..651188f00 100644 --- a/app/javascript/schedule/schedule_session_search.vue +++ b/app/javascript/schedule/schedule_session_search.vue @@ -29,6 +29,16 @@ Search
    + +
    +
    + + All + Time + Room + +
    +
    @@ -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() { diff --git a/app/javascript/sessions/assign_participants.vue b/app/javascript/sessions/assign_participants.vue index e238be37d..0fce2efec 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
    @@ -72,6 +75,7 @@ export default { return this.selected_model(sessionModel); }, peopleFilter() { + // NOTE: sessionAssignmentModel let filter = { "op": "all", "queries":[ @@ -85,10 +89,20 @@ export default { } }, methods: { + reorder() { + this.fetchPaged(false) + }, 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/sessions/session.js b/app/javascript/sessions/session.js index 844da4041..7e62173dd 100644 --- a/app/javascript/sessions/session.js +++ b/app/javascript/sessions/session.js @@ -46,6 +46,7 @@ export const session_columns = [ { key: 'duration', label: 'Duration', + type: "text" // todo formatter here }, { @@ -66,7 +67,7 @@ export const session_columns = [ { key: 'open_for_interest', label: 'Open for Interest', - type: "radio", + type: "select", choices: [{label: "Yes", value: "true"}, {label: "No", value: "false"}], formatter: (value) => value ? "Yes" : "No", sortable: true, @@ -75,7 +76,7 @@ export const session_columns = [ { key: 'require_signup', label: 'Requires Signup', - type: "radio", + type: "select", choices: [{label: "Yes", value: "true"}, {label: "No", value: "false"}], formatter: (value) => value ? "Yes" : "No", sortable: true, @@ -90,7 +91,12 @@ export const session_columns = [ }, { key: 'visibility', - label: 'Visibility' + label: 'Visibility', + formatter: (value) => value === 'is_public' ? 'Visible' : 'Not Visible', + type: "select", + choices: [{label: 'Visible', value: 'public'}, {label: 'Not Visible', value: 'private'}], + sortable: true, + sortKey: 'visibility' } ]; // diff --git a/app/javascript/sessions/session_edit.vue b/app/javascript/sessions/session_edit.vue index d6c79e5ef..2f64abd2e 100644 --- a/app/javascript/sessions/session_edit.vue +++ b/app/javascript/sessions/session_edit.vue @@ -61,7 +61,7 @@
    -
    +
    +
    + + + +
    diff --git a/app/javascript/sessions/session_fields.mixin.js b/app/javascript/sessions/session_fields.mixin.js index 250de54d8..f188105ec 100644 --- a/app/javascript/sessions/session_fields.mixin.js +++ b/app/javascript/sessions/session_fields.mixin.js @@ -1,4 +1,4 @@ -import { conventionTimezoneMixin } from '@/mixins'; +import { conventionTimezoneMixin, settingsMixin } from '@/mixins'; import { DateTime } from 'luxon'; export const areaMixin = { @@ -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() { + return this.formatStartTime(this.selected); + }, + } +} 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; diff --git a/app/javascript/sessions/session_sidebar.vue b/app/javascript/sessions/session_sidebar.vue index e81358d71..0386482c8 100644 --- a/app/javascript/sessions/session_sidebar.vue +++ b/app/javascript/sessions/session_sidebar.vue @@ -47,6 +47,19 @@
    +
    +
    + + Not Visible + Visible + +
    +
    @@ -58,9 +71,13 @@
    {{formattedAreaList}}
    None Selected
    Format
    -
    {{selected.format.name}}
    +
    {{selected.format.name}}
    +
    None Selected
    Session Environment
    {{SESSION_ENVIRONMENT[selected.environment]}}
    +
    Room Setup
    +
    {{selected.room_set.name}}
    +
    None Selected
    Attendee Signup Required
    {{selected.require_signup ? 'Yes' : 'No'}}
    If "Yes", max openings
    diff --git a/app/javascript/sessions/session_summary.vue b/app/javascript/sessions/session_summary.vue index 9ef7508c0..f4ee453cf 100644 --- a/app/javascript/sessions/session_summary.vue +++ b/app/javascript/sessions/session_summary.vue @@ -66,6 +66,15 @@ :checked="scheduled" >Scheduled + + Not Visible + Visible + {{SESSION_STATUS.draft}} @@ -104,6 +113,18 @@ export default { session() { return this.selected_model(sessionModel); }, + visibility: { + get() { + return this.session.visibility === 'is_public' + }, + set(val) { + if (val) { + this.session.visibility = 'is_public' + } else { + this.session.visibility = 'is_private' + } + } + } }, methods: { saveSession() { diff --git a/app/javascript/sessions/session_table.vue b/app/javascript/sessions/session_table.vue index b20a92936..f13f4e07a 100644 --- a/app/javascript/sessions/session_table.vue +++ b/app/javascript/sessions/session_table.vue @@ -1,7 +1,7 @@ - + + + + +
    @@ -51,16 +53,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 +73,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() { } diff --git a/app/javascript/sessions/view_participant_type.vue b/app/javascript/sessions/view_participant_type.vue index 290d8275b..21aa83ba2 100644 --- a/app/javascript/sessions/view_participant_type.vue +++ b/app/javascript/sessions/view_participant_type.vue @@ -36,9 +36,11 @@ export default { }, myAssignments() { // Using the fetch collection instead of relationship now - return this.collection.filter( - sa => (sa.session_assignment_role_type_id === this.sessionRole?.id && sa.session_id == this.session.id) + const coll = this.collection.filter( + sa => (sa.session_assignment_role_type_id === this.sessionRole?.id && sa.session_id === this.session.id) ); + coll.sort((a, b) => a.published_name < b.published_name ? -1 : a.published_name > b.published_name ? 1 : 0) + return coll; } } } diff --git a/app/javascript/store/model.mixin.js b/app/javascript/store/model.mixin.js index f48030a85..3b366ac5c 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) { @@ -89,7 +88,7 @@ export const modelMixin = { */ export const makeSelectedFieldMixin = (field) => ({ mixins: [ - modelMixin + modelMixinNoProp ], data: () => ({ [field]: null 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 { } -