From 539b385a2059e30a4963f0ce04e6b61e6bb333ed Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:11:31 +0100 Subject: [PATCH 01/44] Remove the words Added by from agenda item --- .../item_component/show_component.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 9634f694505c..87e7ddaf1af5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -54,10 +54,6 @@ author: @meeting_agenda_item.author.name, age: helpers.distance_of_time_in_words(Time.zone.now, @meeting_agenda_item.created_at)) flex_layout do |flex| - flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t("label_added_by", author: nil) } - end - flex.with_column(classes: 'ellipsis') do render(Users::AvatarComponent.new(user: @meeting_agenda_item.author, size: 'mini', title:, classes: 'op-principal_flex')) end From 406126fc7a0d0940a4839ccf759712813c42c4be Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:21:41 +0100 Subject: [PATCH 02/44] remove dot after author name --- modules/meeting/app/components/meetings/header_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meetings/header_component.rb b/modules/meeting/app/components/meetings/header_component.rb index 6e4c14027053..967c2a8d006c 100644 --- a/modules/meeting/app/components/meetings/header_component.rb +++ b/modules/meeting/app/components/meetings/header_component.rb @@ -44,7 +44,7 @@ def initialize(meeting:, state: :show) def render_author_link render(Primer::Beta::Link.new(font_size: :small, href: user_path(@meeting.author), underline: false, target: "_blank")) do - "#{@meeting.author.name}." + "#{@meeting.author.name}" end end From 513615964db86e807454d90bb15b5c61a06b5856 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:11:31 +0100 Subject: [PATCH 03/44] Remove the words Added by from agenda item --- .../item_component/show_component.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 9634f694505c..87e7ddaf1af5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -54,10 +54,6 @@ author: @meeting_agenda_item.author.name, age: helpers.distance_of_time_in_words(Time.zone.now, @meeting_agenda_item.created_at)) flex_layout do |flex| - flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t("label_added_by", author: nil) } - end - flex.with_column(classes: 'ellipsis') do render(Users::AvatarComponent.new(user: @meeting_agenda_item.author, size: 'mini', title:, classes: 'op-principal_flex')) end From a93c78c919e06156b6dd1f1a4d8db34933d93a2b Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:21:41 +0100 Subject: [PATCH 04/44] remove dot after author name --- modules/meeting/app/components/meetings/header_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meetings/header_component.rb b/modules/meeting/app/components/meetings/header_component.rb index 6e4c14027053..967c2a8d006c 100644 --- a/modules/meeting/app/components/meetings/header_component.rb +++ b/modules/meeting/app/components/meetings/header_component.rb @@ -44,7 +44,7 @@ def initialize(meeting:, state: :show) def render_author_link render(Primer::Beta::Link.new(font_size: :small, href: user_path(@meeting.author), underline: false, target: "_blank")) do - "#{@meeting.author.name}." + "#{@meeting.author.name}" end end From 43263d930ff915e27a5328c6e281dc61d9ed6929 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 6 Nov 2023 15:52:18 +0100 Subject: [PATCH 05/44] hide item actions when meeting is closed --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.rb | 3 +++ .../meeting_agenda_items/item_component/show_component.sass | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 87e7ddaf1af5..ba50197dcb03 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout('op-meeting-agenda-item', tag: :div) do |grid| + grid_layout((meeting_open? ? 'op-meeting-agenda-item' : 'closed-meeting op-meeting-agenda-item'), tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index eae7805f24e9..d3d56d7d50f5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -49,6 +49,9 @@ def edit_enabled? @meeting.open? && User.current.allowed_in_project?(:manage_agendas, @meeting.project) end + def meeting_open? + @meeting.open? + end def edit_action_item(menu) menu.with_item(label: t("label_edit"), href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index f4faaccd5f3d..cac0facf4883 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -26,6 +26,10 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener + &.closed-meeting + grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) + grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" + @media screen and (max-width: $breakpoint-lg) grid-template-columns: 20px auto 1fr 50px grid-template-areas: "drag-handle content content actions" ". author author duration" ". notes notes notes" From d54aefeae1fdfc66fff18092820391e9e3e25e9e Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:11:31 +0100 Subject: [PATCH 06/44] Remove the words Added by from agenda item --- .../item_component/show_component.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 9634f694505c..87e7ddaf1af5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -54,10 +54,6 @@ author: @meeting_agenda_item.author.name, age: helpers.distance_of_time_in_words(Time.zone.now, @meeting_agenda_item.created_at)) flex_layout do |flex| - flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t("label_added_by", author: nil) } - end - flex.with_column(classes: 'ellipsis') do render(Users::AvatarComponent.new(user: @meeting_agenda_item.author, size: 'mini', title:, classes: 'op-principal_flex')) end From 7ed5cf57e872862587f29b0b82146ce542ba7f7b Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:21:41 +0100 Subject: [PATCH 07/44] remove dot after author name --- modules/meeting/app/components/meetings/header_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meetings/header_component.rb b/modules/meeting/app/components/meetings/header_component.rb index 6e4c14027053..967c2a8d006c 100644 --- a/modules/meeting/app/components/meetings/header_component.rb +++ b/modules/meeting/app/components/meetings/header_component.rb @@ -44,7 +44,7 @@ def initialize(meeting:, state: :show) def render_author_link render(Primer::Beta::Link.new(font_size: :small, href: user_path(@meeting.author), underline: false, target: "_blank")) do - "#{@meeting.author.name}." + "#{@meeting.author.name}" end end From 679bbbc09c4ba9f46970a534655ae07fa549e9ed Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 6 Nov 2023 15:52:18 +0100 Subject: [PATCH 08/44] hide item actions when meeting is closed --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.rb | 3 +++ .../meeting_agenda_items/item_component/show_component.sass | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 87e7ddaf1af5..ba50197dcb03 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout('op-meeting-agenda-item', tag: :div) do |grid| + grid_layout((meeting_open? ? 'op-meeting-agenda-item' : 'closed-meeting op-meeting-agenda-item'), tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index eae7805f24e9..d3d56d7d50f5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -49,6 +49,9 @@ def edit_enabled? @meeting.open? && User.current.allowed_in_project?(:manage_agendas, @meeting.project) end + def meeting_open? + @meeting.open? + end def edit_action_item(menu) menu.with_item(label: t("label_edit"), href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index f4faaccd5f3d..cac0facf4883 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -26,6 +26,10 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener + &.closed-meeting + grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) + grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" + @media screen and (max-width: $breakpoint-lg) grid-template-columns: 20px auto 1fr 50px grid-template-areas: "drag-handle content content actions" ". author author duration" ". notes notes notes" From 5856348d99044e4a2d03d647c53ebae569b7e339 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 7 Nov 2023 11:47:45 +0100 Subject: [PATCH 09/44] reduce width of duration field --- .../app/components/meeting_agenda_items/form_component.sass | 2 +- modules/meeting/app/forms/meeting_agenda_item/duration.rb | 2 +- modules/meeting/config/locales/en.yml | 2 +- .../structured_meetings/structured_meeting_crud_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.sass b/modules/meeting/app/components/meeting_agenda_items/form_component.sass index 0d26789aa6e8..8728ef80b5b6 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.sass @@ -2,7 +2,7 @@ .op-meeting-agenda-item-form display: grid - grid-template-columns: 1fr 180px + grid-template-columns: 1fr 140px grid-template-areas: "title duration" "notes notes" "add_note actions" grid-gap: 8px diff --git a/modules/meeting/app/forms/meeting_agenda_item/duration.rb b/modules/meeting/app/forms/meeting_agenda_item/duration.rb index ee7751e4a622..6b4128e853d9 100644 --- a/modules/meeting/app/forms/meeting_agenda_item/duration.rb +++ b/modules/meeting/app/forms/meeting_agenda_item/duration.rb @@ -30,7 +30,7 @@ class MeetingAgendaItem::Duration < ApplicationForm form do |agenda_item_form| agenda_item_form.text_field( name: :duration_in_minutes, - placeholder: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), + placeholder: I18n.t('activerecord.attributes.meeting_agenda_items.duration_in_minutes'), label: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), leading_visual: { icon: :stopwatch }, visually_hide_label: true, diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index 45fc6856cf31..90e465344506 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -53,7 +53,7 @@ en: meeting_agenda_items: title: "Title" author: "Responsible" - duration_in_minutes: "Duration in minutes" + duration_in_minutes: "Duration (min)" description: "Notes" errors: messages: diff --git a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb index 2db4833cae99..96f879a9f80a 100644 --- a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb +++ b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb @@ -88,7 +88,7 @@ # Can add and edit a single item show_page.add_agenda_item do fill_in 'Title', with: 'My agenda item' - fill_in 'Duration in minutes', with: '25' + fill_in 'Duration (min)', with: '25' end show_page.expect_agenda_item title: 'My agenda item' From c8d8fe20f13e4478259a4164cb01470dfce6e8c5 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 09:43:24 +0100 Subject: [PATCH 10/44] add add notes button to actions of agenda item --- .../meeting_agenda_items/form_component.rb | 19 ++++++++++++++++--- .../meeting_agenda_items/item_component.rb | 8 +++++--- .../item_component/edit_component.rb | 6 ++++-- .../item_component/show_component.html.erb | 1 + .../item_component/show_component.rb | 10 ++++++++++ .../meetings/agenda_component_streams.rb | 5 +++-- .../meeting_agenda_items_controller.rb | 2 +- modules/meeting/config/locales/en.yml | 1 + 8 files changed, 41 insertions(+), 11 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.rb b/modules/meeting/app/components/meeting_agenda_items/form_component.rb index 5129f7258564..5c8bc4e13034 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.rb @@ -32,7 +32,7 @@ class FormComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple) + def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple, display_notes_input: nil) super @meeting = meeting @@ -41,6 +41,7 @@ def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_pat @submit_path = submit_path @cancel_path = cancel_path @type = type + @display_notes_input = display_notes_input end def render? @@ -58,11 +59,23 @@ def wrapper_data_attributes end def display_notes_input_value - @meeting_agenda_item.notes.blank? ? :none : nil + if @display_notes_input + :block + elsif @meeting_agenda_item.notes.blank? + :none + else + :block + end end def display_notes_add_button_value - @meeting_agenda_item.notes.blank? ? nil : :none + if @display_notes_input + :none + elsif @meeting_agenda_item.notes.blank? + :block + else + :none + end end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component.rb index f62ecdb28ecc..344facf801ed 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component.rb @@ -32,11 +32,12 @@ class ItemComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:, state: :show) + def initialize(meeting_agenda_item:, state: :show, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item @state = state + @display_notes_input = display_notes_input end def wrapper_uniq_by @@ -58,8 +59,9 @@ def call def child_component_params { - meeting_agenda_item: @meeting_agenda_item - } + meeting_agenda_item: @meeting_agenda_item, + display_notes_input: (@display_notes_input if @state == :edit) + }.compact end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb index e0cd4ebb1633..21754fa5e773 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb @@ -31,10 +31,11 @@ class ItemComponent::EditComponent < ApplicationComponent include ApplicationHelper include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:) + def initialize(meeting_agenda_item:, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item + @display_notes_input = display_notes_input @type = if @meeting_agenda_item.work_package.present? :work_package else @@ -50,7 +51,8 @@ def call method: :put, submit_path: meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, format: :turbo_stream), cancel_path: cancel_edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), - type: @type + type: @type, + display_notes_input: @display_notes_input )) end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index ba50197dcb03..8576682ddef8 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -64,6 +64,7 @@ render(Primer::Alpha::ActionMenu.new) do |menu| menu.with_show_button(icon: "kebab-horizontal", 'aria-label': t("label_agenda_item_actions"), scheme: :invisible, test_selector: 'op-meeting-agenda-actions') edit_action_item(menu) if @meeting_agenda_item.editable? + add_note_action_item(menu) if @meeting_agenda_item.editable? move_actions(menu) delete_action_item(menu) end if edit_enabled? diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index d3d56d7d50f5..2439735528a1 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -62,6 +62,16 @@ def edit_action_item(menu) end end + def add_note_action_item(menu) + menu.with_item(label: t("label_agenda_item_add_notes"), + href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, display_notes_input: true), + content_arguments: { + data: { 'turbo-stream': true } + }) do |item| + item.with_leading_visual_icon(icon: :note) + end + end + def move_actions(menu) move_action_item(menu, :highest, t("label_agenda_item_move_to_top"), "move-to-top") unless @meeting_agenda_item.first? move_action_item(menu, :higher, t("label_agenda_item_move_up"), "chevron-up") unless @meeting_agenda_item.first? diff --git a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb index 003888ffd473..0814c56ca12e 100644 --- a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb +++ b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb @@ -124,7 +124,7 @@ def update_list_via_turbo_stream(meeting: @meeting, form_hidden: true, form_type update_new_button_via_turbo_stream(disabled: false) if form_hidden == true end - def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item) + def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item, display_notes_input: nil) if @meeting_agenda_item.duration_in_minutes_previously_changed? # if duration was changed, all following items are affectected with their time-slot # thus update the whole list to reflect the changes on the UI immediately @@ -133,7 +133,8 @@ def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_age update_via_turbo_stream( component: MeetingAgendaItems::ItemComponent.new( state:, - meeting_agenda_item: + meeting_agenda_item:, + display_notes_input: ) ) end diff --git a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb index d563726b7a53..f0600f82906a 100644 --- a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb +++ b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb @@ -88,7 +88,7 @@ def create def edit if @meeting_agenda_item.editable? - update_item_via_turbo_stream(state: :edit) + update_item_via_turbo_stream(state: :edit, display_notes_input: params[:display_notes_input]) else update_all_via_turbo_stream render_error_flash_message_via_turbo_stream(message: t("text_meeting_not_editable_anymore")) diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index ae6d4d06459c..8edaad09090b 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -173,6 +173,7 @@ en: label_agenda_item_move_to_bottom: "Move to bottom" label_agenda_item_move_up: "Move up" label_agenda_item_move_down: "Move down" + label_agenda_item_add_notes: "Add notes" label_meeting_details: "Meeting details" label_meeting_details_edit: "Edit meeting details" From 7d175ff1b2632c9a8c2529b9e2caeb8642f97857 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 10:51:19 +0100 Subject: [PATCH 11/44] fix focus on ckeditor when adding note --- .../dynamic/meeting-agenda-item-form.controller.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts index 4c90dfcad70d..dd20e439e3df 100644 --- a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts @@ -52,7 +52,9 @@ export default class extends Controller { setTimeout(() => { this.element.scrollIntoView({ block: 'center' }); - if (titleInput) { + if (window.getComputedStyle(this.notesInputTarget).display !== 'none') { + this.focusCkEditor(); + } else if (titleInput) { (titleInput as HTMLInputElement).focus(); } }, 100); @@ -76,6 +78,10 @@ export default class extends Controller { addNotes() { this.notesInputTarget.classList.remove('d-none'); this.notesAddButtonTarget.classList.add('d-none'); + this.focusCkEditor(); + } + + private focusCkEditor() { setTimeout(() => { const ckContent = this.element.querySelector('.ck-content'); if (ckContent) { From e076524d790034168ddb1349cf7f5918e5dab195 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 15:32:49 +0100 Subject: [PATCH 12/44] move show/hide button to the bottom --- ...eetings-sidebar-participants.controller.ts | 51 +++++++++++++++++++ .../sidebar/participants_component.html.erb | 30 +++++------ .../sidebar/participants_component.rb | 7 +++ 3 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts new file mode 100644 index 000000000000..19972443ccfb --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -0,0 +1,51 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +export default class MeetingsSidebarParticipantsController extends Controller { + static targets = ['showHideButton', 'hiddenParticipants']; + declare readonly showHideButtonTarget:HTMLInputElement; + declare readonly hiddenParticipantsTarget:HTMLElement; + + connect():void { + this.showHiddenParticipants(); + } + + showHiddenParticipants():void { + this.showHideButtonTarget.addEventListener('click', () => { + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } + }); + } +} diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 924754b62f46..8111cfb1adc6 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper do + component_wrapper(data: wrapper_data_attributes) do flex_layout do |participants_container| participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| @@ -49,27 +49,21 @@ end list.with_row(mt: 2) do - render Primer::Beta::Details.new do |hidden_details| - flex_layout do |flex| - flex.with_row do - hidden_details.with_summary(size: :small, scheme: :link) do - t('label_meeting_show_hide_participants', - count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS).to_s - end - end - - flex.with_row do - hidden_details.with_body do - flex_layout do |hidden_user_list| - @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| - hidden_user_list.with_row(mt: 1) do - render_participant(participant) - end - end + flex_layout do |flex| + flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do + flex_layout do |hidden_user_list| + @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| + hidden_user_list.with_row(mt: 1) do + render_participant(participant) end end end end + flex.with_row do + render (Primer::Beta::Button.new(scheme: :invisible, + data: { 'meetings-sidebar-participants-target': "showHideButton" })) { I18n.t('label_meeting_show_hide_participants', + count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } + end end end end diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.rb b/modules/meeting/app/components/meetings/sidebar/participants_component.rb index 8ac30d4b720b..4b16784f9d39 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.rb @@ -34,6 +34,13 @@ class Sidebar::ParticipantsComponent < ApplicationComponent MAX_SHOWN_PARTICIPANTS = 5 + def wrapper_data_attributes + { + controller: 'meetings-sidebar-participants', + 'application-target': 'dynamic' + } + end + def initialize(meeting:) super From 0987bd374daf9b7ab78b833b0b350c6e64b26a51 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:11:31 +0100 Subject: [PATCH 13/44] Remove the words Added by from agenda item --- .../item_component/show_component.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 9634f694505c..87e7ddaf1af5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -54,10 +54,6 @@ author: @meeting_agenda_item.author.name, age: helpers.distance_of_time_in_words(Time.zone.now, @meeting_agenda_item.created_at)) flex_layout do |flex| - flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t("label_added_by", author: nil) } - end - flex.with_column(classes: 'ellipsis') do render(Users::AvatarComponent.new(user: @meeting_agenda_item.author, size: 'mini', title:, classes: 'op-principal_flex')) end From 909ce25629655920494ec73bfd792d4f82593d05 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:21:41 +0100 Subject: [PATCH 14/44] remove dot after author name --- modules/meeting/app/components/meetings/header_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meetings/header_component.rb b/modules/meeting/app/components/meetings/header_component.rb index 6e4c14027053..967c2a8d006c 100644 --- a/modules/meeting/app/components/meetings/header_component.rb +++ b/modules/meeting/app/components/meetings/header_component.rb @@ -44,7 +44,7 @@ def initialize(meeting:, state: :show) def render_author_link render(Primer::Beta::Link.new(font_size: :small, href: user_path(@meeting.author), underline: false, target: "_blank")) do - "#{@meeting.author.name}." + "#{@meeting.author.name}" end end From 62abff89b61fc32c9d2d8a2c4809f07fb37c2d7a Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 6 Nov 2023 15:52:18 +0100 Subject: [PATCH 15/44] hide item actions when meeting is closed --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.rb | 3 +++ .../meeting_agenda_items/item_component/show_component.sass | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 87e7ddaf1af5..ba50197dcb03 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout('op-meeting-agenda-item', tag: :div) do |grid| + grid_layout((meeting_open? ? 'op-meeting-agenda-item' : 'closed-meeting op-meeting-agenda-item'), tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index eae7805f24e9..d3d56d7d50f5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -49,6 +49,9 @@ def edit_enabled? @meeting.open? && User.current.allowed_in_project?(:manage_agendas, @meeting.project) end + def meeting_open? + @meeting.open? + end def edit_action_item(menu) menu.with_item(label: t("label_edit"), href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index f4faaccd5f3d..cac0facf4883 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -26,6 +26,10 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener + &.closed-meeting + grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) + grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" + @media screen and (max-width: $breakpoint-lg) grid-template-columns: 20px auto 1fr 50px grid-template-areas: "drag-handle content content actions" ". author author duration" ". notes notes notes" From 26fa18c1b7e86669e2653418b9c4c6e57e432c31 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 7 Nov 2023 11:47:45 +0100 Subject: [PATCH 16/44] reduce width of duration field --- .../app/components/meeting_agenda_items/form_component.sass | 2 +- modules/meeting/app/forms/meeting_agenda_item/duration.rb | 2 +- modules/meeting/config/locales/en.yml | 2 +- .../structured_meetings/structured_meeting_crud_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.sass b/modules/meeting/app/components/meeting_agenda_items/form_component.sass index 0d26789aa6e8..8728ef80b5b6 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.sass @@ -2,7 +2,7 @@ .op-meeting-agenda-item-form display: grid - grid-template-columns: 1fr 180px + grid-template-columns: 1fr 140px grid-template-areas: "title duration" "notes notes" "add_note actions" grid-gap: 8px diff --git a/modules/meeting/app/forms/meeting_agenda_item/duration.rb b/modules/meeting/app/forms/meeting_agenda_item/duration.rb index ee7751e4a622..6b4128e853d9 100644 --- a/modules/meeting/app/forms/meeting_agenda_item/duration.rb +++ b/modules/meeting/app/forms/meeting_agenda_item/duration.rb @@ -30,7 +30,7 @@ class MeetingAgendaItem::Duration < ApplicationForm form do |agenda_item_form| agenda_item_form.text_field( name: :duration_in_minutes, - placeholder: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), + placeholder: I18n.t('activerecord.attributes.meeting_agenda_items.duration_in_minutes'), label: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), leading_visual: { icon: :stopwatch }, visually_hide_label: true, diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index 74f6af3d9fb7..ae6d4d06459c 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -53,7 +53,7 @@ en: meeting_agenda_items: title: "Title" author: "Responsible" - duration_in_minutes: "Duration in minutes" + duration_in_minutes: "Duration (min)" description: "Notes" errors: messages: diff --git a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb index 7b077915bdcd..ccae6a2a6dd4 100644 --- a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb +++ b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb @@ -85,7 +85,7 @@ # Can add and edit a single item show_page.add_agenda_item do fill_in 'Title', with: 'My agenda item' - fill_in 'Duration in minutes', with: '25' + fill_in 'Duration (min)', with: '25' end show_page.expect_agenda_item title: 'My agenda item' From a08bb0df66df1b127771da88eae544cf2d19706f Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 09:43:24 +0100 Subject: [PATCH 17/44] add add notes button to actions of agenda item --- .../meeting_agenda_items/form_component.rb | 19 ++++++++++++++++--- .../meeting_agenda_items/item_component.rb | 8 +++++--- .../item_component/edit_component.rb | 6 ++++-- .../item_component/show_component.html.erb | 1 + .../item_component/show_component.rb | 10 ++++++++++ .../meetings/agenda_component_streams.rb | 5 +++-- .../meeting_agenda_items_controller.rb | 2 +- modules/meeting/config/locales/en.yml | 1 + 8 files changed, 41 insertions(+), 11 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.rb b/modules/meeting/app/components/meeting_agenda_items/form_component.rb index 5129f7258564..5c8bc4e13034 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.rb @@ -32,7 +32,7 @@ class FormComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple) + def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple, display_notes_input: nil) super @meeting = meeting @@ -41,6 +41,7 @@ def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_pat @submit_path = submit_path @cancel_path = cancel_path @type = type + @display_notes_input = display_notes_input end def render? @@ -58,11 +59,23 @@ def wrapper_data_attributes end def display_notes_input_value - @meeting_agenda_item.notes.blank? ? :none : nil + if @display_notes_input + :block + elsif @meeting_agenda_item.notes.blank? + :none + else + :block + end end def display_notes_add_button_value - @meeting_agenda_item.notes.blank? ? nil : :none + if @display_notes_input + :none + elsif @meeting_agenda_item.notes.blank? + :block + else + :none + end end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component.rb index f62ecdb28ecc..344facf801ed 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component.rb @@ -32,11 +32,12 @@ class ItemComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:, state: :show) + def initialize(meeting_agenda_item:, state: :show, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item @state = state + @display_notes_input = display_notes_input end def wrapper_uniq_by @@ -58,8 +59,9 @@ def call def child_component_params { - meeting_agenda_item: @meeting_agenda_item - } + meeting_agenda_item: @meeting_agenda_item, + display_notes_input: (@display_notes_input if @state == :edit) + }.compact end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb index e0cd4ebb1633..21754fa5e773 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb @@ -31,10 +31,11 @@ class ItemComponent::EditComponent < ApplicationComponent include ApplicationHelper include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:) + def initialize(meeting_agenda_item:, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item + @display_notes_input = display_notes_input @type = if @meeting_agenda_item.work_package.present? :work_package else @@ -50,7 +51,8 @@ def call method: :put, submit_path: meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, format: :turbo_stream), cancel_path: cancel_edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), - type: @type + type: @type, + display_notes_input: @display_notes_input )) end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index ba50197dcb03..8576682ddef8 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -64,6 +64,7 @@ render(Primer::Alpha::ActionMenu.new) do |menu| menu.with_show_button(icon: "kebab-horizontal", 'aria-label': t("label_agenda_item_actions"), scheme: :invisible, test_selector: 'op-meeting-agenda-actions') edit_action_item(menu) if @meeting_agenda_item.editable? + add_note_action_item(menu) if @meeting_agenda_item.editable? move_actions(menu) delete_action_item(menu) end if edit_enabled? diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index d3d56d7d50f5..2439735528a1 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -62,6 +62,16 @@ def edit_action_item(menu) end end + def add_note_action_item(menu) + menu.with_item(label: t("label_agenda_item_add_notes"), + href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, display_notes_input: true), + content_arguments: { + data: { 'turbo-stream': true } + }) do |item| + item.with_leading_visual_icon(icon: :note) + end + end + def move_actions(menu) move_action_item(menu, :highest, t("label_agenda_item_move_to_top"), "move-to-top") unless @meeting_agenda_item.first? move_action_item(menu, :higher, t("label_agenda_item_move_up"), "chevron-up") unless @meeting_agenda_item.first? diff --git a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb index 003888ffd473..0814c56ca12e 100644 --- a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb +++ b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb @@ -124,7 +124,7 @@ def update_list_via_turbo_stream(meeting: @meeting, form_hidden: true, form_type update_new_button_via_turbo_stream(disabled: false) if form_hidden == true end - def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item) + def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item, display_notes_input: nil) if @meeting_agenda_item.duration_in_minutes_previously_changed? # if duration was changed, all following items are affectected with their time-slot # thus update the whole list to reflect the changes on the UI immediately @@ -133,7 +133,8 @@ def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_age update_via_turbo_stream( component: MeetingAgendaItems::ItemComponent.new( state:, - meeting_agenda_item: + meeting_agenda_item:, + display_notes_input: ) ) end diff --git a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb index d563726b7a53..f0600f82906a 100644 --- a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb +++ b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb @@ -88,7 +88,7 @@ def create def edit if @meeting_agenda_item.editable? - update_item_via_turbo_stream(state: :edit) + update_item_via_turbo_stream(state: :edit, display_notes_input: params[:display_notes_input]) else update_all_via_turbo_stream render_error_flash_message_via_turbo_stream(message: t("text_meeting_not_editable_anymore")) diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index ae6d4d06459c..8edaad09090b 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -173,6 +173,7 @@ en: label_agenda_item_move_to_bottom: "Move to bottom" label_agenda_item_move_up: "Move up" label_agenda_item_move_down: "Move down" + label_agenda_item_add_notes: "Add notes" label_meeting_details: "Meeting details" label_meeting_details_edit: "Edit meeting details" From 6b3692f7d5ba67d4ede7923e33426e1d95b85e86 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 10:51:19 +0100 Subject: [PATCH 18/44] fix focus on ckeditor when adding note --- .../dynamic/meeting-agenda-item-form.controller.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts index 4c90dfcad70d..dd20e439e3df 100644 --- a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts @@ -52,7 +52,9 @@ export default class extends Controller { setTimeout(() => { this.element.scrollIntoView({ block: 'center' }); - if (titleInput) { + if (window.getComputedStyle(this.notesInputTarget).display !== 'none') { + this.focusCkEditor(); + } else if (titleInput) { (titleInput as HTMLInputElement).focus(); } }, 100); @@ -76,6 +78,10 @@ export default class extends Controller { addNotes() { this.notesInputTarget.classList.remove('d-none'); this.notesAddButtonTarget.classList.add('d-none'); + this.focusCkEditor(); + } + + private focusCkEditor() { setTimeout(() => { const ckContent = this.element.querySelector('.ck-content'); if (ckContent) { From 6ad05f183ff9742c3b0e09ee354e92418e0bdc75 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 15:32:49 +0100 Subject: [PATCH 19/44] move show/hide button to the bottom --- ...eetings-sidebar-participants.controller.ts | 51 +++++++++++++++++++ .../sidebar/participants_component.html.erb | 30 +++++------ .../sidebar/participants_component.rb | 7 +++ 3 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts new file mode 100644 index 000000000000..19972443ccfb --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -0,0 +1,51 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +export default class MeetingsSidebarParticipantsController extends Controller { + static targets = ['showHideButton', 'hiddenParticipants']; + declare readonly showHideButtonTarget:HTMLInputElement; + declare readonly hiddenParticipantsTarget:HTMLElement; + + connect():void { + this.showHiddenParticipants(); + } + + showHiddenParticipants():void { + this.showHideButtonTarget.addEventListener('click', () => { + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } + }); + } +} diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 924754b62f46..8111cfb1adc6 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper do + component_wrapper(data: wrapper_data_attributes) do flex_layout do |participants_container| participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| @@ -49,27 +49,21 @@ end list.with_row(mt: 2) do - render Primer::Beta::Details.new do |hidden_details| - flex_layout do |flex| - flex.with_row do - hidden_details.with_summary(size: :small, scheme: :link) do - t('label_meeting_show_hide_participants', - count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS).to_s - end - end - - flex.with_row do - hidden_details.with_body do - flex_layout do |hidden_user_list| - @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| - hidden_user_list.with_row(mt: 1) do - render_participant(participant) - end - end + flex_layout do |flex| + flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do + flex_layout do |hidden_user_list| + @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| + hidden_user_list.with_row(mt: 1) do + render_participant(participant) end end end end + flex.with_row do + render (Primer::Beta::Button.new(scheme: :invisible, + data: { 'meetings-sidebar-participants-target': "showHideButton" })) { I18n.t('label_meeting_show_hide_participants', + count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } + end end end end diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.rb b/modules/meeting/app/components/meetings/sidebar/participants_component.rb index 8ac30d4b720b..4b16784f9d39 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.rb @@ -34,6 +34,13 @@ class Sidebar::ParticipantsComponent < ApplicationComponent MAX_SHOWN_PARTICIPANTS = 5 + def wrapper_data_attributes + { + controller: 'meetings-sidebar-participants', + 'application-target': 'dynamic' + } + end + def initialize(meeting:) super From dd6fef3fd6a6bbf7e310518ce99e25306da21067 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 12:00:32 +0100 Subject: [PATCH 20/44] The Meeting details section should be at the top (before agenda items) --- .../meeting/app/components/meetings/show_component.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/meeting/app/components/meetings/show_component.html.erb b/modules/meeting/app/components/meetings/show_component.html.erb index 58be44ff7e93..79bb285fab80 100644 --- a/modules/meeting/app/components/meetings/show_component.html.erb +++ b/modules/meeting/app/components/meetings/show_component.html.erb @@ -12,7 +12,7 @@ end show_page.with_row do - render(Primer::Alpha::Layout.new(stacking_breakpoint: :lg)) do |content| + render(Primer::Alpha::Layout.new(stacking_breakpoint: :sm)) do |content| content.with_main do flex_layout do |agenda| agenda.with_row do @@ -25,7 +25,7 @@ end end - content.with_sidebar(row_placement: :end, col_placement: :end, width: :wide) do + content.with_sidebar(row_placement: :start, col_placement: :end, width: :wide) do render(Meetings::SidebarComponent.new(meeting: @meeting)) end end From 96d2eba6eed5c2b7efcc21e3af30b1b6afaf3863 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 13:21:34 +0100 Subject: [PATCH 21/44] shorten the meeting status part --- modules/meeting/app/components/_index.sass | 1 + .../meetings/sidebar/state_component.html.erb | 12 ++++++------ .../components/meetings/sidebar/state_component.sass | 9 +++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 modules/meeting/app/components/meetings/sidebar/state_component.sass diff --git a/modules/meeting/app/components/_index.sass b/modules/meeting/app/components/_index.sass index 3cdcef54becc..2f17a54aef68 100644 --- a/modules/meeting/app/components/_index.sass +++ b/modules/meeting/app/components/_index.sass @@ -1,2 +1,3 @@ @import "./meeting_agenda_items/item_component/show_component.sass" @import "./meeting_agenda_items/form_component.sass" +@import "./meetings/sidebar/state_component.sass" diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb index 74034d272882..8da7b29921b3 100644 --- a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do case @meeting.state when "open" - flex_layout do |open_state| + flex_layout(classes: 'op-meeting-sidebar-state') do |open_state| open_state.with_row do render(Primer::Beta::State.new(title: "state", scheme: :open)) do flex_layout do |open_state_label| @@ -17,14 +17,14 @@ end end - open_state.with_row(mt: 3) do + open_state.with_row(mt: 3, classes:'hidden-for-mobile') do render(Primer::Beta::Text.new(color: :subtle)) do t("text_meeting_open_description") end end if edit_enabled? - open_state.with_row(mt: 3) do + open_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |open_state_actions| @@ -50,7 +50,7 @@ end end when "closed" - flex_layout do |closed_state| + flex_layout(classes: 'op-meeting-sidebar-state') do |closed_state| closed_state.with_row do render(Primer::Beta::State.new(title: "state", scheme: :default)) do flex_layout do |closed_state_label| @@ -66,13 +66,13 @@ end closed_state.with_row(mt: 3) do - render(Primer::Beta::Text.new(color: :subtle)) do + render(Primer::Beta::Text.new(color: :subtle, classes:'hidden-for-mobile')) do t("text_meeting_closed_description") end end if edit_enabled? - closed_state.with_row(mt: 3) do + closed_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |closed_state_actions| diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.sass b/modules/meeting/app/components/meetings/sidebar/state_component.sass new file mode 100644 index 000000000000..53744633bafb --- /dev/null +++ b/modules/meeting/app/components/meetings/sidebar/state_component.sass @@ -0,0 +1,9 @@ +@import 'helpers' + +@media screen and (max-width: $breakpoint-sm) + .op-meeting-sidebar-state + flex-direction: row !important + justify-content: space-between + align-items: center + &-edit + margin-top: 0 !important \ No newline at end of file From 00f1d1106b7b19aa1bfe52b068723144d099630e Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 16:12:45 +0100 Subject: [PATCH 22/44] remove participants in mobile mode and show them in details part --- .../meetings-sidebar-details.controller.ts | 51 +++++++++++++++++++ modules/meeting/app/components/_index.sass | 1 + .../sidebar/details_component.html.erb | 23 ++++++++- .../meetings/sidebar/details_component.rb | 30 +++++++++++ .../meetings/sidebar/details_component.sass | 12 +++++ .../sidebar/participants_component.html.erb | 2 +- 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts create mode 100644 modules/meeting/app/components/meetings/sidebar/details_component.sass diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts new file mode 100644 index 000000000000..33c3408f387c --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts @@ -0,0 +1,51 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +export default class MeetingsSidebarDetailsController extends Controller { + static targets = ['showHideButton', 'hiddenParticipants']; + declare readonly showHideButtonTarget:HTMLInputElement; + declare readonly hiddenParticipantsTarget:HTMLElement; + + connect():void { + this.showHiddenParticipants(); + } + + showHiddenParticipants():void { + this.showHideButtonTarget.addEventListener('click', () => { + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } + }); + } +} diff --git a/modules/meeting/app/components/_index.sass b/modules/meeting/app/components/_index.sass index 2f17a54aef68..c38800880119 100644 --- a/modules/meeting/app/components/_index.sass +++ b/modules/meeting/app/components/_index.sass @@ -1,3 +1,4 @@ @import "./meeting_agenda_items/item_component/show_component.sass" @import "./meeting_agenda_items/form_component.sass" @import "./meetings/sidebar/state_component.sass" +@import "./meetings/sidebar/details_component.sass" diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index 86da51680f2f..bf66f82c2507 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper do + component_wrapper(data: wrapper_data_attributes) do flex_layout do |details_container| details_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| @@ -85,6 +85,27 @@ end end end + details.with_row(mt: 2, classes: 'op-meeting-sidebar-details-participants') do + flex_layout do |flex| + render(Primer::Beta::Octicon.new(icon: 'people')) + flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-details-target': "hiddenParticipants" }) do + flex_layout do |details| + @meeting.invited_or_attended_participants.sort.each do |participant| + details.with_row(mt: 1) do + render_participant(participant) + end + end + end + end + flex.with_row do + render (Primer::Beta::Button.new(scheme: :invisible, classes: 'op-meeting-sidebar-details-participants-button', + data: { 'meetings-sidebar-details-target': "showHideButton" })) do |button| + button.with_leading_visual_icon(icon: :people) + I18n.t('label_meeting_show_hide_participants',count: @meeting.invited_or_attended_participants.count) + end + end + end + end end end end diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.rb b/modules/meeting/app/components/meetings/sidebar/details_component.rb index 53f046d1d1b6..436af43a8eca 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.rb @@ -40,6 +40,13 @@ def initialize(meeting:) private + def wrapper_data_attributes + { + controller: 'meetings-sidebar-details', + 'application-target': 'dynamic' + } + end + def render_truncated_location render(Primer::Beta::Truncate.new) do |component| component.with_item(max_width: 250) do @@ -48,6 +55,29 @@ def render_truncated_location end end + def render_participant(participant) + flex_layout(align_items: :center) do |flex| + flex.with_column(classes: 'ellipsis') do + render(Users::AvatarComponent.new(user: participant.user, + size: :medium, + classes: 'op-principal_flex')) + end + render_participant_state(participant, flex) + end + end + + def render_participant_state(participant, flex) + if participant.attended? + flex.with_column(ml: 1) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_attended").capitalize } + end + elsif participant.invited? + flex.with_column(ml: 1) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_invite").capitalize } + end + end + end + def render_meeting_attribute_row(icon, &) flex_layout(align_items: :center, justify_content: :space_between) do |flex| flex.with_column do diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.sass b/modules/meeting/app/components/meetings/sidebar/details_component.sass new file mode 100644 index 000000000000..c980f3d981f8 --- /dev/null +++ b/modules/meeting/app/components/meetings/sidebar/details_component.sass @@ -0,0 +1,12 @@ +@import 'helpers' +.op-meeting-sidebar-details-participants + display: none + &-button + padding: 0 !important + color: var(--content-link-color) + + + +@media screen and (max-width: $breakpoint-sm) + .op-meeting-sidebar-details-participants + display: block !important \ No newline at end of file diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 8111cfb1adc6..b301d79f41e8 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,6 +1,6 @@ <%= component_wrapper(data: wrapper_data_attributes) do - flex_layout do |participants_container| + flex_layout(classes: 'hidden-for-mobile') do |participants_container| participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| heading.with_column(flex: 1) do From ca149d76e64778a8cba3d1f2144e3c50dd48545f Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:11:31 +0100 Subject: [PATCH 23/44] Remove the words Added by from agenda item --- .../item_component/show_component.html.erb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 9634f694505c..87e7ddaf1af5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -54,10 +54,6 @@ author: @meeting_agenda_item.author.name, age: helpers.distance_of_time_in_words(Time.zone.now, @meeting_agenda_item.created_at)) flex_layout do |flex| - flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t("label_added_by", author: nil) } - end - flex.with_column(classes: 'ellipsis') do render(Users::AvatarComponent.new(user: @meeting_agenda_item.author, size: 'mini', title:, classes: 'op-principal_flex')) end From 02701d353b5ba86105e78c5ad156443793713e1f Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Fri, 3 Nov 2023 09:21:41 +0100 Subject: [PATCH 24/44] remove dot after author name --- modules/meeting/app/components/meetings/header_component.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meetings/header_component.rb b/modules/meeting/app/components/meetings/header_component.rb index 6e4c14027053..967c2a8d006c 100644 --- a/modules/meeting/app/components/meetings/header_component.rb +++ b/modules/meeting/app/components/meetings/header_component.rb @@ -44,7 +44,7 @@ def initialize(meeting:, state: :show) def render_author_link render(Primer::Beta::Link.new(font_size: :small, href: user_path(@meeting.author), underline: false, target: "_blank")) do - "#{@meeting.author.name}." + "#{@meeting.author.name}" end end From 2c9f21beaef676f95dcbdaa4fa61613d9bea52fb Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 6 Nov 2023 15:52:18 +0100 Subject: [PATCH 25/44] hide item actions when meeting is closed --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.rb | 3 +++ .../meeting_agenda_items/item_component/show_component.sass | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 87e7ddaf1af5..ba50197dcb03 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout('op-meeting-agenda-item', tag: :div) do |grid| + grid_layout((meeting_open? ? 'op-meeting-agenda-item' : 'closed-meeting op-meeting-agenda-item'), tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index eae7805f24e9..d3d56d7d50f5 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -49,6 +49,9 @@ def edit_enabled? @meeting.open? && User.current.allowed_in_project?(:manage_agendas, @meeting.project) end + def meeting_open? + @meeting.open? + end def edit_action_item(menu) menu.with_item(label: t("label_edit"), href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index f4faaccd5f3d..cac0facf4883 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -26,6 +26,10 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener + &.closed-meeting + grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) + grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" + @media screen and (max-width: $breakpoint-lg) grid-template-columns: 20px auto 1fr 50px grid-template-areas: "drag-handle content content actions" ". author author duration" ". notes notes notes" From da51d47fcbe361283799cb29ce3c47dff878089e Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 7 Nov 2023 11:47:45 +0100 Subject: [PATCH 26/44] reduce width of duration field --- .../app/components/meeting_agenda_items/form_component.sass | 2 +- modules/meeting/app/forms/meeting_agenda_item/duration.rb | 2 +- modules/meeting/config/locales/en.yml | 2 +- .../structured_meetings/structured_meeting_crud_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.sass b/modules/meeting/app/components/meeting_agenda_items/form_component.sass index 0d26789aa6e8..8728ef80b5b6 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.sass @@ -2,7 +2,7 @@ .op-meeting-agenda-item-form display: grid - grid-template-columns: 1fr 180px + grid-template-columns: 1fr 140px grid-template-areas: "title duration" "notes notes" "add_note actions" grid-gap: 8px diff --git a/modules/meeting/app/forms/meeting_agenda_item/duration.rb b/modules/meeting/app/forms/meeting_agenda_item/duration.rb index ee7751e4a622..6b4128e853d9 100644 --- a/modules/meeting/app/forms/meeting_agenda_item/duration.rb +++ b/modules/meeting/app/forms/meeting_agenda_item/duration.rb @@ -30,7 +30,7 @@ class MeetingAgendaItem::Duration < ApplicationForm form do |agenda_item_form| agenda_item_form.text_field( name: :duration_in_minutes, - placeholder: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), + placeholder: I18n.t('activerecord.attributes.meeting_agenda_items.duration_in_minutes'), label: MeetingAgendaItem.human_attribute_name(:duration_in_minutes), leading_visual: { icon: :stopwatch }, visually_hide_label: true, diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index 74f6af3d9fb7..ae6d4d06459c 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -53,7 +53,7 @@ en: meeting_agenda_items: title: "Title" author: "Responsible" - duration_in_minutes: "Duration in minutes" + duration_in_minutes: "Duration (min)" description: "Notes" errors: messages: diff --git a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb index 7b077915bdcd..ccae6a2a6dd4 100644 --- a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb +++ b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb @@ -85,7 +85,7 @@ # Can add and edit a single item show_page.add_agenda_item do fill_in 'Title', with: 'My agenda item' - fill_in 'Duration in minutes', with: '25' + fill_in 'Duration (min)', with: '25' end show_page.expect_agenda_item title: 'My agenda item' From a74f9311f7eadce319f1e026881ddc9e658e3ab2 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 09:43:24 +0100 Subject: [PATCH 27/44] add add notes button to actions of agenda item --- .../meeting_agenda_items/form_component.rb | 19 ++++++++++++++++--- .../meeting_agenda_items/item_component.rb | 8 +++++--- .../item_component/edit_component.rb | 6 ++++-- .../item_component/show_component.html.erb | 1 + .../item_component/show_component.rb | 10 ++++++++++ .../meetings/agenda_component_streams.rb | 5 +++-- .../meeting_agenda_items_controller.rb | 2 +- modules/meeting/config/locales/en.yml | 1 + 8 files changed, 41 insertions(+), 11 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/form_component.rb b/modules/meeting/app/components/meeting_agenda_items/form_component.rb index 5129f7258564..5c8bc4e13034 100644 --- a/modules/meeting/app/components/meeting_agenda_items/form_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/form_component.rb @@ -32,7 +32,7 @@ class FormComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple) + def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_path:, type: :simple, display_notes_input: nil) super @meeting = meeting @@ -41,6 +41,7 @@ def initialize(meeting:, meeting_agenda_item:, method:, submit_path:, cancel_pat @submit_path = submit_path @cancel_path = cancel_path @type = type + @display_notes_input = display_notes_input end def render? @@ -58,11 +59,23 @@ def wrapper_data_attributes end def display_notes_input_value - @meeting_agenda_item.notes.blank? ? :none : nil + if @display_notes_input + :block + elsif @meeting_agenda_item.notes.blank? + :none + else + :block + end end def display_notes_add_button_value - @meeting_agenda_item.notes.blank? ? nil : :none + if @display_notes_input + :none + elsif @meeting_agenda_item.notes.blank? + :block + else + :none + end end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component.rb index f62ecdb28ecc..344facf801ed 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component.rb @@ -32,11 +32,12 @@ class ItemComponent < ApplicationComponent include OpTurbo::Streamable include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:, state: :show) + def initialize(meeting_agenda_item:, state: :show, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item @state = state + @display_notes_input = display_notes_input end def wrapper_uniq_by @@ -58,8 +59,9 @@ def call def child_component_params { - meeting_agenda_item: @meeting_agenda_item - } + meeting_agenda_item: @meeting_agenda_item, + display_notes_input: (@display_notes_input if @state == :edit) + }.compact end end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb index e0cd4ebb1633..21754fa5e773 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/edit_component.rb @@ -31,10 +31,11 @@ class ItemComponent::EditComponent < ApplicationComponent include ApplicationHelper include OpPrimer::ComponentHelpers - def initialize(meeting_agenda_item:) + def initialize(meeting_agenda_item:, display_notes_input: nil) super @meeting_agenda_item = meeting_agenda_item + @display_notes_input = display_notes_input @type = if @meeting_agenda_item.work_package.present? :work_package else @@ -50,7 +51,8 @@ def call method: :put, submit_path: meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, format: :turbo_stream), cancel_path: cancel_edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item), - type: @type + type: @type, + display_notes_input: @display_notes_input )) end end diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index ba50197dcb03..8576682ddef8 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -64,6 +64,7 @@ render(Primer::Alpha::ActionMenu.new) do |menu| menu.with_show_button(icon: "kebab-horizontal", 'aria-label': t("label_agenda_item_actions"), scheme: :invisible, test_selector: 'op-meeting-agenda-actions') edit_action_item(menu) if @meeting_agenda_item.editable? + add_note_action_item(menu) if @meeting_agenda_item.editable? move_actions(menu) delete_action_item(menu) end if edit_enabled? diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index d3d56d7d50f5..2439735528a1 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -62,6 +62,16 @@ def edit_action_item(menu) end end + def add_note_action_item(menu) + menu.with_item(label: t("label_agenda_item_add_notes"), + href: edit_meeting_agenda_item_path(@meeting_agenda_item.meeting, @meeting_agenda_item, display_notes_input: true), + content_arguments: { + data: { 'turbo-stream': true } + }) do |item| + item.with_leading_visual_icon(icon: :note) + end + end + def move_actions(menu) move_action_item(menu, :highest, t("label_agenda_item_move_to_top"), "move-to-top") unless @meeting_agenda_item.first? move_action_item(menu, :higher, t("label_agenda_item_move_up"), "chevron-up") unless @meeting_agenda_item.first? diff --git a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb index 003888ffd473..0814c56ca12e 100644 --- a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb +++ b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb @@ -124,7 +124,7 @@ def update_list_via_turbo_stream(meeting: @meeting, form_hidden: true, form_type update_new_button_via_turbo_stream(disabled: false) if form_hidden == true end - def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item) + def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_agenda_item, display_notes_input: nil) if @meeting_agenda_item.duration_in_minutes_previously_changed? # if duration was changed, all following items are affectected with their time-slot # thus update the whole list to reflect the changes on the UI immediately @@ -133,7 +133,8 @@ def update_item_via_turbo_stream(state: :show, meeting_agenda_item: @meeting_age update_via_turbo_stream( component: MeetingAgendaItems::ItemComponent.new( state:, - meeting_agenda_item: + meeting_agenda_item:, + display_notes_input: ) ) end diff --git a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb index d563726b7a53..f0600f82906a 100644 --- a/modules/meeting/app/controllers/meeting_agenda_items_controller.rb +++ b/modules/meeting/app/controllers/meeting_agenda_items_controller.rb @@ -88,7 +88,7 @@ def create def edit if @meeting_agenda_item.editable? - update_item_via_turbo_stream(state: :edit) + update_item_via_turbo_stream(state: :edit, display_notes_input: params[:display_notes_input]) else update_all_via_turbo_stream render_error_flash_message_via_turbo_stream(message: t("text_meeting_not_editable_anymore")) diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index ae6d4d06459c..8edaad09090b 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -173,6 +173,7 @@ en: label_agenda_item_move_to_bottom: "Move to bottom" label_agenda_item_move_up: "Move up" label_agenda_item_move_down: "Move down" + label_agenda_item_add_notes: "Add notes" label_meeting_details: "Meeting details" label_meeting_details_edit: "Edit meeting details" From 926e4925cfd09163f987e82dd95130724ef43a2f Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 10:51:19 +0100 Subject: [PATCH 28/44] fix focus on ckeditor when adding note --- .../dynamic/meeting-agenda-item-form.controller.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts index 4c90dfcad70d..dd20e439e3df 100644 --- a/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meeting-agenda-item-form.controller.ts @@ -52,7 +52,9 @@ export default class extends Controller { setTimeout(() => { this.element.scrollIntoView({ block: 'center' }); - if (titleInput) { + if (window.getComputedStyle(this.notesInputTarget).display !== 'none') { + this.focusCkEditor(); + } else if (titleInput) { (titleInput as HTMLInputElement).focus(); } }, 100); @@ -76,6 +78,10 @@ export default class extends Controller { addNotes() { this.notesInputTarget.classList.remove('d-none'); this.notesAddButtonTarget.classList.add('d-none'); + this.focusCkEditor(); + } + + private focusCkEditor() { setTimeout(() => { const ckContent = this.element.querySelector('.ck-content'); if (ckContent) { From b5237801fcfe540a17a8aa0efb5dc8bc6d88997c Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 8 Nov 2023 15:32:49 +0100 Subject: [PATCH 29/44] move show/hide button to the bottom --- ...eetings-sidebar-participants.controller.ts | 51 +++++++++++++++++++ .../sidebar/participants_component.html.erb | 30 +++++------ .../sidebar/participants_component.rb | 7 +++ 3 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts new file mode 100644 index 000000000000..19972443ccfb --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -0,0 +1,51 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +export default class MeetingsSidebarParticipantsController extends Controller { + static targets = ['showHideButton', 'hiddenParticipants']; + declare readonly showHideButtonTarget:HTMLInputElement; + declare readonly hiddenParticipantsTarget:HTMLElement; + + connect():void { + this.showHiddenParticipants(); + } + + showHiddenParticipants():void { + this.showHideButtonTarget.addEventListener('click', () => { + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } + }); + } +} diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 924754b62f46..8111cfb1adc6 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper do + component_wrapper(data: wrapper_data_attributes) do flex_layout do |participants_container| participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| @@ -49,27 +49,21 @@ end list.with_row(mt: 2) do - render Primer::Beta::Details.new do |hidden_details| - flex_layout do |flex| - flex.with_row do - hidden_details.with_summary(size: :small, scheme: :link) do - t('label_meeting_show_hide_participants', - count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS).to_s - end - end - - flex.with_row do - hidden_details.with_body do - flex_layout do |hidden_user_list| - @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| - hidden_user_list.with_row(mt: 1) do - render_participant(participant) - end - end + flex_layout do |flex| + flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do + flex_layout do |hidden_user_list| + @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| + hidden_user_list.with_row(mt: 1) do + render_participant(participant) end end end end + flex.with_row do + render (Primer::Beta::Button.new(scheme: :invisible, + data: { 'meetings-sidebar-participants-target': "showHideButton" })) { I18n.t('label_meeting_show_hide_participants', + count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } + end end end end diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.rb b/modules/meeting/app/components/meetings/sidebar/participants_component.rb index 8ac30d4b720b..4b16784f9d39 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.rb @@ -34,6 +34,13 @@ class Sidebar::ParticipantsComponent < ApplicationComponent MAX_SHOWN_PARTICIPANTS = 5 + def wrapper_data_attributes + { + controller: 'meetings-sidebar-participants', + 'application-target': 'dynamic' + } + end + def initialize(meeting:) super From 1da4496fbc6f2db0d3bbb0a45356fbdf50410d53 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 12:00:32 +0100 Subject: [PATCH 30/44] The Meeting details section should be at the top (before agenda items) --- .../meeting/app/components/meetings/show_component.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/meeting/app/components/meetings/show_component.html.erb b/modules/meeting/app/components/meetings/show_component.html.erb index 58be44ff7e93..79bb285fab80 100644 --- a/modules/meeting/app/components/meetings/show_component.html.erb +++ b/modules/meeting/app/components/meetings/show_component.html.erb @@ -12,7 +12,7 @@ end show_page.with_row do - render(Primer::Alpha::Layout.new(stacking_breakpoint: :lg)) do |content| + render(Primer::Alpha::Layout.new(stacking_breakpoint: :sm)) do |content| content.with_main do flex_layout do |agenda| agenda.with_row do @@ -25,7 +25,7 @@ end end - content.with_sidebar(row_placement: :end, col_placement: :end, width: :wide) do + content.with_sidebar(row_placement: :start, col_placement: :end, width: :wide) do render(Meetings::SidebarComponent.new(meeting: @meeting)) end end From 625b434e42143abc419732e03f0b4721cef42e83 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 13:21:34 +0100 Subject: [PATCH 31/44] shorten the meeting status part --- modules/meeting/app/components/_index.sass | 1 + .../meetings/sidebar/state_component.html.erb | 12 ++++++------ .../components/meetings/sidebar/state_component.sass | 9 +++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 modules/meeting/app/components/meetings/sidebar/state_component.sass diff --git a/modules/meeting/app/components/_index.sass b/modules/meeting/app/components/_index.sass index 3cdcef54becc..2f17a54aef68 100644 --- a/modules/meeting/app/components/_index.sass +++ b/modules/meeting/app/components/_index.sass @@ -1,2 +1,3 @@ @import "./meeting_agenda_items/item_component/show_component.sass" @import "./meeting_agenda_items/form_component.sass" +@import "./meetings/sidebar/state_component.sass" diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb index 74034d272882..8da7b29921b3 100644 --- a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb @@ -2,7 +2,7 @@ component_wrapper do case @meeting.state when "open" - flex_layout do |open_state| + flex_layout(classes: 'op-meeting-sidebar-state') do |open_state| open_state.with_row do render(Primer::Beta::State.new(title: "state", scheme: :open)) do flex_layout do |open_state_label| @@ -17,14 +17,14 @@ end end - open_state.with_row(mt: 3) do + open_state.with_row(mt: 3, classes:'hidden-for-mobile') do render(Primer::Beta::Text.new(color: :subtle)) do t("text_meeting_open_description") end end if edit_enabled? - open_state.with_row(mt: 3) do + open_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |open_state_actions| @@ -50,7 +50,7 @@ end end when "closed" - flex_layout do |closed_state| + flex_layout(classes: 'op-meeting-sidebar-state') do |closed_state| closed_state.with_row do render(Primer::Beta::State.new(title: "state", scheme: :default)) do flex_layout do |closed_state_label| @@ -66,13 +66,13 @@ end closed_state.with_row(mt: 3) do - render(Primer::Beta::Text.new(color: :subtle)) do + render(Primer::Beta::Text.new(color: :subtle, classes:'hidden-for-mobile')) do t("text_meeting_closed_description") end end if edit_enabled? - closed_state.with_row(mt: 3) do + closed_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |closed_state_actions| diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.sass b/modules/meeting/app/components/meetings/sidebar/state_component.sass new file mode 100644 index 000000000000..53744633bafb --- /dev/null +++ b/modules/meeting/app/components/meetings/sidebar/state_component.sass @@ -0,0 +1,9 @@ +@import 'helpers' + +@media screen and (max-width: $breakpoint-sm) + .op-meeting-sidebar-state + flex-direction: row !important + justify-content: space-between + align-items: center + &-edit + margin-top: 0 !important \ No newline at end of file From 04893289beb925b4526e545f87fb7e059ac47fb4 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 9 Nov 2023 16:12:45 +0100 Subject: [PATCH 32/44] remove participants in mobile mode and show them in details part --- .../meetings-sidebar-details.controller.ts | 51 +++++++++++++++++++ modules/meeting/app/components/_index.sass | 1 + .../sidebar/details_component.html.erb | 23 ++++++++- .../meetings/sidebar/details_component.rb | 30 +++++++++++ .../meetings/sidebar/details_component.sass | 12 +++++ .../sidebar/participants_component.html.erb | 2 +- 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts create mode 100644 modules/meeting/app/components/meetings/sidebar/details_component.sass diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts new file mode 100644 index 000000000000..33c3408f387c --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts @@ -0,0 +1,51 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; + +export default class MeetingsSidebarDetailsController extends Controller { + static targets = ['showHideButton', 'hiddenParticipants']; + declare readonly showHideButtonTarget:HTMLInputElement; + declare readonly hiddenParticipantsTarget:HTMLElement; + + connect():void { + this.showHiddenParticipants(); + } + + showHiddenParticipants():void { + this.showHideButtonTarget.addEventListener('click', () => { + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } + }); + } +} diff --git a/modules/meeting/app/components/_index.sass b/modules/meeting/app/components/_index.sass index 2f17a54aef68..c38800880119 100644 --- a/modules/meeting/app/components/_index.sass +++ b/modules/meeting/app/components/_index.sass @@ -1,3 +1,4 @@ @import "./meeting_agenda_items/item_component/show_component.sass" @import "./meeting_agenda_items/form_component.sass" @import "./meetings/sidebar/state_component.sass" +@import "./meetings/sidebar/details_component.sass" diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index 86da51680f2f..bf66f82c2507 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper do + component_wrapper(data: wrapper_data_attributes) do flex_layout do |details_container| details_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| @@ -85,6 +85,27 @@ end end end + details.with_row(mt: 2, classes: 'op-meeting-sidebar-details-participants') do + flex_layout do |flex| + render(Primer::Beta::Octicon.new(icon: 'people')) + flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-details-target': "hiddenParticipants" }) do + flex_layout do |details| + @meeting.invited_or_attended_participants.sort.each do |participant| + details.with_row(mt: 1) do + render_participant(participant) + end + end + end + end + flex.with_row do + render (Primer::Beta::Button.new(scheme: :invisible, classes: 'op-meeting-sidebar-details-participants-button', + data: { 'meetings-sidebar-details-target': "showHideButton" })) do |button| + button.with_leading_visual_icon(icon: :people) + I18n.t('label_meeting_show_hide_participants',count: @meeting.invited_or_attended_participants.count) + end + end + end + end end end end diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.rb b/modules/meeting/app/components/meetings/sidebar/details_component.rb index 53f046d1d1b6..436af43a8eca 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.rb @@ -40,6 +40,13 @@ def initialize(meeting:) private + def wrapper_data_attributes + { + controller: 'meetings-sidebar-details', + 'application-target': 'dynamic' + } + end + def render_truncated_location render(Primer::Beta::Truncate.new) do |component| component.with_item(max_width: 250) do @@ -48,6 +55,29 @@ def render_truncated_location end end + def render_participant(participant) + flex_layout(align_items: :center) do |flex| + flex.with_column(classes: 'ellipsis') do + render(Users::AvatarComponent.new(user: participant.user, + size: :medium, + classes: 'op-principal_flex')) + end + render_participant_state(participant, flex) + end + end + + def render_participant_state(participant, flex) + if participant.attended? + flex.with_column(ml: 1) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_attended").capitalize } + end + elsif participant.invited? + flex.with_column(ml: 1) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_invite").capitalize } + end + end + end + def render_meeting_attribute_row(icon, &) flex_layout(align_items: :center, justify_content: :space_between) do |flex| flex.with_column do diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.sass b/modules/meeting/app/components/meetings/sidebar/details_component.sass new file mode 100644 index 000000000000..c980f3d981f8 --- /dev/null +++ b/modules/meeting/app/components/meetings/sidebar/details_component.sass @@ -0,0 +1,12 @@ +@import 'helpers' +.op-meeting-sidebar-details-participants + display: none + &-button + padding: 0 !important + color: var(--content-link-color) + + + +@media screen and (max-width: $breakpoint-sm) + .op-meeting-sidebar-details-participants + display: block !important \ No newline at end of file diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 8111cfb1adc6..b301d79f41e8 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,6 +1,6 @@ <%= component_wrapper(data: wrapper_data_attributes) do - flex_layout do |participants_container| + flex_layout(classes: 'hidden-for-mobile') do |participants_container| participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| heading.with_column(flex: 1) do From a68d3f98fcee02a356b9f1aa27740ede4d6dee83 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 11:17:17 +0100 Subject: [PATCH 33/44] use participants component in details component --- ...eetings-sidebar-participants.controller.ts | 15 ++++++- .../sidebar/details_component.html.erb | 22 +---------- .../sidebar/participants_component.html.erb | 39 +++++++++++++++++-- .../meetings/sidebar_component.html.erb | 2 +- modules/meeting/config/locales/en.yml | 2 + 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts index 19972443ccfb..1e0d75b8c4c8 100644 --- a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -31,12 +31,15 @@ import { Controller } from '@hotwired/stimulus'; export default class MeetingsSidebarParticipantsController extends Controller { - static targets = ['showHideButton', 'hiddenParticipants']; + static targets = ['showHideButton', 'hiddenParticipants', 'showHideMobileButton', 'hiddenMobileParticipants']; declare readonly showHideButtonTarget:HTMLInputElement; declare readonly hiddenParticipantsTarget:HTMLElement; + declare readonly showHideMobileButtonTarget:HTMLInputElement; + declare readonly hiddenMobileParticipantsTarget:HTMLElement; connect():void { this.showHiddenParticipants(); + this.showHiddenMobileParticipants(); } showHiddenParticipants():void { @@ -48,4 +51,14 @@ export default class MeetingsSidebarParticipantsController extends Controller { } }); } + + showHiddenMobileParticipants():void { + this.showHideMobileButtonTarget.addEventListener('click', () => { + if (this.hiddenMobileParticipantsTarget.classList.contains('d-none')) { + this.hiddenMobileParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenMobileParticipantsTarget.classList.add('d-none'); + } + }); + } } diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index bf66f82c2507..5b46f6e98efa 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -85,26 +85,8 @@ end end end - details.with_row(mt: 2, classes: 'op-meeting-sidebar-details-participants') do - flex_layout do |flex| - render(Primer::Beta::Octicon.new(icon: 'people')) - flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-details-target': "hiddenParticipants" }) do - flex_layout do |details| - @meeting.invited_or_attended_participants.sort.each do |participant| - details.with_row(mt: 1) do - render_participant(participant) - end - end - end - end - flex.with_row do - render (Primer::Beta::Button.new(scheme: :invisible, classes: 'op-meeting-sidebar-details-participants-button', - data: { 'meetings-sidebar-details-target': "showHideButton" })) do |button| - button.with_leading_visual_icon(icon: :people) - I18n.t('label_meeting_show_hide_participants',count: @meeting.invited_or_attended_participants.count) - end - end - end + details.with_row(mt: 2, display: [:block, :block, :none, :none, :none]) do + render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) end end end diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index b301d79f41e8..5ca810c36a4d 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,7 +1,7 @@ <%= component_wrapper(data: wrapper_data_attributes) do - flex_layout(classes: 'hidden-for-mobile') do |participants_container| - participants_container.with_row do + flex_layout do |participants_container| + participants_container.with_row(hide: :sm) do flex_layout(align_items: :center, justify_content: :space_between) do |heading| heading.with_column(flex: 1) do flex_layout(align_items: :center) do |title| @@ -29,7 +29,7 @@ end end - participants_container.with_row(mt: 2) do + participants_container.with_row(mt: 2, hide: :sm) do if count == 0 render(Primer::Beta::Text.new(color: :subtle)) { t("label_meeting_no_participants") } elsif count <= MAX_SHOWN_PARTICIPANTS @@ -70,8 +70,39 @@ end end + participants_container.with_row(display: [:block, :block, :none, :none, :none]) do + flex_layout do |flex| + if count == 0 + render(Primer::Beta::Text.new(color: :subtle)) { t("label_meeting_no_participants") } + else + flex.with_row(display: :none, data: { 'meetings-sidebar-participants-target': "hiddenMobileParticipants" }) do + flex_layout do |details| + @meeting.invited_or_attended_participants.sort.each do |participant| + details.with_row(mt: 1) do + render_participant(participant) + end + end + end + end + flex.with_row do + flex.with_column do + render(Primer::Beta::Octicon.new('people', color: :subtle, mr: 1)) + end + flex.with_column do + render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t('label_meeting_count_participants', count: @meeting.invited_or_attended_participants.count) } + end + flex.with_column(data: { 'meetings-sidebar-participants-target': "showHideMobileButton" }) do + render(Primer::Beta::Link.new(href: "#", target: "_blank")) do + I18n.t('label_meeting_show_hide_all_participants') + end + end + end + end + end + end + if @meeting.editable? - participants_container.with_row(mt: 3) do + participants_container.with_row(mt: 3, hide: :sm) do render(Primer::Beta::Button.new( scheme: :link, color: :default, diff --git a/modules/meeting/app/components/meetings/sidebar_component.html.erb b/modules/meeting/app/components/meetings/sidebar_component.html.erb index 182e5b13787a..565f3705a58d 100644 --- a/modules/meeting/app/components/meetings/sidebar_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar_component.html.erb @@ -3,7 +3,7 @@ render(Primer::OpenProject::BorderGrid.new) do |border_grid| border_grid.with_row { render(Meetings::Sidebar::DetailsComponent.new(meeting: @meeting)) } border_grid.with_row { render(Meetings::Sidebar::StateComponent.new(meeting: @meeting)) } - border_grid.with_row { render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) } + border_grid.with_row(hide: :sm) { render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) } end end %> diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index 8edaad09090b..f0d7e537bb97 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -188,6 +188,8 @@ en: label_meeting_manage_participants: "Manage participants" label_meeting_no_participants: "No participants" label_meeting_show_hide_participants: "Show/hide %{count} more" + label_meeting_show_hide_all_participants: "Show/hide all" + label_meeting_count_participants: "%{count} participants" label_meeting_add_participants: "Add participants" text_meeting_not_editable_anymore: "This meeting is not editable anymore." From a7a34544f7c68655ec126c5d325925cb87129418 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 11:24:56 +0100 Subject: [PATCH 34/44] fix merge error --- .../meetings/sidebar/participants_component.html.erb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index b3a9bdbb9b90..5ca810c36a4d 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,12 +1,7 @@ <%= component_wrapper(data: wrapper_data_attributes) do -<<<<<<< HEAD flex_layout do |participants_container| participants_container.with_row(hide: :sm) do -======= - flex_layout(classes: 'hidden-for-mobile') do |participants_container| - participants_container.with_row do ->>>>>>> 04893289beb925b4526e545f87fb7e059ac47fb4 flex_layout(align_items: :center, justify_content: :space_between) do |heading| heading.with_column(flex: 1) do flex_layout(align_items: :center) do |title| From db0dde49508231b060f8a83c069e0ab0f5a71508 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 12:44:44 +0100 Subject: [PATCH 35/44] change margin top value for hidden participants --- .../components/meetings/sidebar/details_component.html.erb | 2 +- .../meetings/sidebar/participants_component.html.erb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index 5b46f6e98efa..74b62bd97367 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -85,7 +85,7 @@ end end end - details.with_row(mt: 2, display: [:block, :block, :none, :none, :none]) do + details.with_row(mt: 2, display: [:block, :none, :none, :none, :none]) do render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) end end diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 5ca810c36a4d..10df70997d33 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -48,7 +48,7 @@ end end - list.with_row(mt: 2) do + list.with_row(mt: 1) do flex_layout do |flex| flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do flex_layout do |hidden_user_list| @@ -70,7 +70,7 @@ end end - participants_container.with_row(display: [:block, :block, :none, :none, :none]) do + participants_container.with_row(display: [:block, :none, :none, :none, :none]) do flex_layout do |flex| if count == 0 render(Primer::Beta::Text.new(color: :subtle)) { t("label_meeting_no_participants") } From d4054f287f97537baf578fe988a3c5eaa18698bb Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 12:58:36 +0100 Subject: [PATCH 36/44] remove duplicated code and unnecessary files --- .../meetings-sidebar-details.controller.ts | 51 ------------------- modules/meeting/app/components/_index.sass | 1 - .../sidebar/details_component.html.erb | 2 +- .../meetings/sidebar/details_component.rb | 31 ----------- .../meetings/sidebar/details_component.sass | 12 ----- 5 files changed, 1 insertion(+), 96 deletions(-) delete mode 100644 frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts delete mode 100644 modules/meeting/app/components/meetings/sidebar/details_component.sass diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts deleted file mode 100644 index 33c3408f387c..000000000000 --- a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-details.controller.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * -- copyright - * OpenProject is an open source project management software. - * Copyright (C) 2023 the OpenProject GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 3. - * - * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: - * Copyright (C) 2006-2013 Jean-Philippe Lang - * Copyright (C) 2010-2013 the ChiliProject Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * See COPYRIGHT and LICENSE files for more details. - * ++ - */ - -import { Controller } from '@hotwired/stimulus'; - -export default class MeetingsSidebarDetailsController extends Controller { - static targets = ['showHideButton', 'hiddenParticipants']; - declare readonly showHideButtonTarget:HTMLInputElement; - declare readonly hiddenParticipantsTarget:HTMLElement; - - connect():void { - this.showHiddenParticipants(); - } - - showHiddenParticipants():void { - this.showHideButtonTarget.addEventListener('click', () => { - if (this.hiddenParticipantsTarget.classList.contains('d-none')) { - this.hiddenParticipantsTarget.classList.remove('d-none'); - } else { - this.hiddenParticipantsTarget.classList.add('d-none'); - } - }); - } -} diff --git a/modules/meeting/app/components/_index.sass b/modules/meeting/app/components/_index.sass index c38800880119..2f17a54aef68 100644 --- a/modules/meeting/app/components/_index.sass +++ b/modules/meeting/app/components/_index.sass @@ -1,4 +1,3 @@ @import "./meeting_agenda_items/item_component/show_component.sass" @import "./meeting_agenda_items/form_component.sass" @import "./meetings/sidebar/state_component.sass" -@import "./meetings/sidebar/details_component.sass" diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index 74b62bd97367..a8a75b710db5 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -1,5 +1,5 @@ <%= - component_wrapper(data: wrapper_data_attributes) do + component_wrapper do flex_layout do |details_container| details_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.rb b/modules/meeting/app/components/meetings/sidebar/details_component.rb index 436af43a8eca..3954f729b1f4 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.rb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.rb @@ -40,13 +40,6 @@ def initialize(meeting:) private - def wrapper_data_attributes - { - controller: 'meetings-sidebar-details', - 'application-target': 'dynamic' - } - end - def render_truncated_location render(Primer::Beta::Truncate.new) do |component| component.with_item(max_width: 250) do @@ -54,30 +47,6 @@ def render_truncated_location end end end - - def render_participant(participant) - flex_layout(align_items: :center) do |flex| - flex.with_column(classes: 'ellipsis') do - render(Users::AvatarComponent.new(user: participant.user, - size: :medium, - classes: 'op-principal_flex')) - end - render_participant_state(participant, flex) - end - end - - def render_participant_state(participant, flex) - if participant.attended? - flex.with_column(ml: 1) do - render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_attended").capitalize } - end - elsif participant.invited? - flex.with_column(ml: 1) do - render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) { t("description_invite").capitalize } - end - end - end - def render_meeting_attribute_row(icon, &) flex_layout(align_items: :center, justify_content: :space_between) do |flex| flex.with_column do diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.sass b/modules/meeting/app/components/meetings/sidebar/details_component.sass deleted file mode 100644 index c980f3d981f8..000000000000 --- a/modules/meeting/app/components/meetings/sidebar/details_component.sass +++ /dev/null @@ -1,12 +0,0 @@ -@import 'helpers' -.op-meeting-sidebar-details-participants - display: none - &-button - padding: 0 !important - color: var(--content-link-color) - - - -@media screen and (max-width: $breakpoint-sm) - .op-meeting-sidebar-details-participants - display: block !important \ No newline at end of file From 7430dfec26f98db226d6351fda633735ed8bef0f Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 13:34:45 +0100 Subject: [PATCH 37/44] use system argument instead of custom classes --- .../sidebar/participants_component.html.erb | 14 +++++++------- .../meetings/sidebar/state_component.html.erb | 4 ++-- .../meetings/sidebar/state_component.sass | 4 +--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index 10df70997d33..d63449e4fcd7 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -48,9 +48,9 @@ end end - list.with_row(mt: 1) do + list.with_row do flex_layout do |flex| - flex.with_row(classes: 'd-none', data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do + flex.with_row(display: :none, data: { 'meetings-sidebar-participants-target': "hiddenParticipants" }) do flex_layout do |hidden_user_list| @meeting.invited_or_attended_participants.sort[MAX_SHOWN_PARTICIPANTS..].each do |participant| hidden_user_list.with_row(mt: 1) do @@ -59,7 +59,7 @@ end end end - flex.with_row do + flex.with_row(mt: 1) do render (Primer::Beta::Button.new(scheme: :invisible, data: { 'meetings-sidebar-participants-target': "showHideButton" })) { I18n.t('label_meeting_show_hide_participants', count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } @@ -73,9 +73,9 @@ participants_container.with_row(display: [:block, :none, :none, :none, :none]) do flex_layout do |flex| if count == 0 - render(Primer::Beta::Text.new(color: :subtle)) { t("label_meeting_no_participants") } + render(Primer::Beta::Text.new) { t("label_meeting_no_participants") } else - flex.with_row(display: :none, data: { 'meetings-sidebar-participants-target': "hiddenMobileParticipants" }) do + flex.with_row(mb: 1, display: :none, data: { 'meetings-sidebar-participants-target': "hiddenMobileParticipants" }) do flex_layout do |details| @meeting.invited_or_attended_participants.sort.each do |participant| details.with_row(mt: 1) do @@ -86,10 +86,10 @@ end flex.with_row do flex.with_column do - render(Primer::Beta::Octicon.new('people', color: :subtle, mr: 1)) + render(Primer::Beta::Octicon.new('people', mr: 1)) end flex.with_column do - render(Primer::Beta::Text.new(color: :subtle, mr: 1)) { t('label_meeting_count_participants', count: @meeting.invited_or_attended_participants.count) } + render(Primer::Beta::Text.new(mr: 1)) { t('label_meeting_count_participants', count: @meeting.invited_or_attended_participants.count) } end flex.with_column(data: { 'meetings-sidebar-participants-target': "showHideMobileButton" }) do render(Primer::Beta::Link.new(href: "#", target: "_blank")) do diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb index 8da7b29921b3..d1d111d9fb4c 100644 --- a/modules/meeting/app/components/meetings/sidebar/state_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/state_component.html.erb @@ -24,7 +24,7 @@ end if edit_enabled? - open_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do + open_state.with_row(mt: [0, 3, 3, 3, 3]) do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |open_state_actions| @@ -72,7 +72,7 @@ end if edit_enabled? - closed_state.with_row(mt: 3, classes: 'op-meeting-sidebar-state-edit') do + closed_state.with_row(mt: [0, 3, 3, 3, 3]) do form_for(@meeting, method: "put", url: change_state_meeting_path(@meeting), data: { 'turbo-stream': true }) do |f| flex_layout do |closed_state_actions| diff --git a/modules/meeting/app/components/meetings/sidebar/state_component.sass b/modules/meeting/app/components/meetings/sidebar/state_component.sass index 53744633bafb..341b9bb00b73 100644 --- a/modules/meeting/app/components/meetings/sidebar/state_component.sass +++ b/modules/meeting/app/components/meetings/sidebar/state_component.sass @@ -4,6 +4,4 @@ .op-meeting-sidebar-state flex-direction: row !important justify-content: space-between - align-items: center - &-edit - margin-top: 0 !important \ No newline at end of file + align-items: center \ No newline at end of file From fb4731d289a06c9dfef10ace1ebfb59e06a13e4d Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 13:47:47 +0100 Subject: [PATCH 38/44] change class name for changing template of closed meeting --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.rb | 4 ++-- .../meeting_agenda_items/item_component/show_component.sass | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 8576682ddef8..1a1699f53bd8 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout((meeting_open? ? 'op-meeting-agenda-item' : 'closed-meeting op-meeting-agenda-item'), tag: :div) do |grid| + grid_layout('op-meeting-agenda-item', classes: (meeting_closed? ? 'op-meeting-agenda-item--closed' : ''), tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb index 2439735528a1..8c546a3f6d91 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.rb @@ -49,8 +49,8 @@ def edit_enabled? @meeting.open? && User.current.allowed_in_project?(:manage_agendas, @meeting.project) end - def meeting_open? - @meeting.open? + def meeting_closed? + !@meeting.open? end def edit_action_item(menu) menu.with_item(label: t("label_edit"), diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index cac0facf4883..2c966791827a 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -26,7 +26,7 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener - &.closed-meeting + &--closed grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" From 51e5f81ae2b33dbb5f2e63acac65cc43b45a3110 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Mon, 13 Nov 2023 13:59:12 +0100 Subject: [PATCH 39/44] remove unnecessary identifier for closed meeting --- .../item_component/show_component.html.erb | 2 +- .../meeting_agenda_items/item_component/show_component.sass | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb index 1a1699f53bd8..0f20cae8da0d 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.html.erb @@ -1,5 +1,5 @@ <%= - grid_layout('op-meeting-agenda-item', classes: (meeting_closed? ? 'op-meeting-agenda-item--closed' : ''), tag: :div) do |grid| + grid_layout('op-meeting-agenda-item', tag: :div) do |grid| if drag_and_drop_enabled? grid.with_area(:'drag-handle', tag: :div) do render(Primer::OpenProject::DragHandle.new(classes: 'handle')) diff --git a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass index 2c966791827a..7edefae0ac34 100644 --- a/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass +++ b/modules/meeting/app/components/meeting_agenda_items/item_component/show_component.sass @@ -4,7 +4,7 @@ $meeting-agenda-item--author-width: 300px .op-meeting-agenda-item display: grid - grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) 40px + grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) fit-content(40px) grid-template-areas: "drag-handle content duration author actions" ". notes notes notes notes" &--drag-handle, @@ -26,10 +26,6 @@ $meeting-agenda-item--author-width: 300px &--content @include text-shortener - &--closed - grid-template-columns: 20px auto 1fr minmax(auto, $meeting-agenda-item--author-width) - grid-template-areas: "drag-handle content duration author" ". notes notes notes notes" - @media screen and (max-width: $breakpoint-lg) grid-template-columns: 20px auto 1fr 50px grid-template-areas: "drag-handle content content actions" ". author author duration" ". notes notes notes" From beb4df1cd4cf72d4a36f013a807c9b5b85768739 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 14 Nov 2023 08:18:02 +0100 Subject: [PATCH 40/44] fix failing feature test --- .../controllers/concerns/meetings/agenda_component_streams.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb index cb1677b6f1f9..e37741c13280 100644 --- a/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb +++ b/modules/meeting/app/controllers/concerns/meetings/agenda_component_streams.rb @@ -165,9 +165,9 @@ def remove_item_via_turbo_stream(meeting_agenda_item: @meeting_agenda_item, clea update_show_items_via_turbo_stream remove_via_turbo_stream( component: MeetingAgendaItems::ItemComponent.new( - state:, + state: :show, meeting_agenda_item:, - display_notes_input: + display_notes_input: nil ) ) end From af1dfad0ed717caa22b0eee374f8e3fd25c9fb59 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 14 Nov 2023 14:49:19 +0100 Subject: [PATCH 41/44] remove participant component from details component --- .../app/components/meetings/sidebar/details_component.html.erb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb index a8a75b710db5..86da51680f2f 100644 --- a/modules/meeting/app/components/meetings/sidebar/details_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/details_component.html.erb @@ -85,9 +85,6 @@ end end end - details.with_row(mt: 2, display: [:block, :none, :none, :none, :none]) do - render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) - end end end end From 047c824dff177383b813002d16f21885fc7bf4af Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 14 Nov 2023 15:16:04 +0100 Subject: [PATCH 42/44] undo changes to show participants inline --- ...eetings-sidebar-participants.controller.ts | 15 +------- .../sidebar/participants_component.html.erb | 37 ++----------------- .../meetings/sidebar_component.html.erb | 2 +- 3 files changed, 5 insertions(+), 49 deletions(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts index 1e0d75b8c4c8..19972443ccfb 100644 --- a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -31,15 +31,12 @@ import { Controller } from '@hotwired/stimulus'; export default class MeetingsSidebarParticipantsController extends Controller { - static targets = ['showHideButton', 'hiddenParticipants', 'showHideMobileButton', 'hiddenMobileParticipants']; + static targets = ['showHideButton', 'hiddenParticipants']; declare readonly showHideButtonTarget:HTMLInputElement; declare readonly hiddenParticipantsTarget:HTMLElement; - declare readonly showHideMobileButtonTarget:HTMLInputElement; - declare readonly hiddenMobileParticipantsTarget:HTMLElement; connect():void { this.showHiddenParticipants(); - this.showHiddenMobileParticipants(); } showHiddenParticipants():void { @@ -51,14 +48,4 @@ export default class MeetingsSidebarParticipantsController extends Controller { } }); } - - showHiddenMobileParticipants():void { - this.showHideMobileButtonTarget.addEventListener('click', () => { - if (this.hiddenMobileParticipantsTarget.classList.contains('d-none')) { - this.hiddenMobileParticipantsTarget.classList.remove('d-none'); - } else { - this.hiddenMobileParticipantsTarget.classList.add('d-none'); - } - }); - } } diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index d63449e4fcd7..c87f86ee5267 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -1,7 +1,7 @@ <%= component_wrapper(data: wrapper_data_attributes) do flex_layout do |participants_container| - participants_container.with_row(hide: :sm) do + participants_container.with_row do flex_layout(align_items: :center, justify_content: :space_between) do |heading| heading.with_column(flex: 1) do flex_layout(align_items: :center) do |title| @@ -29,7 +29,7 @@ end end - participants_container.with_row(mt: 2, hide: :sm) do + participants_container.with_row(mt: 2) do if count == 0 render(Primer::Beta::Text.new(color: :subtle)) { t("label_meeting_no_participants") } elsif count <= MAX_SHOWN_PARTICIPANTS @@ -70,39 +70,8 @@ end end - participants_container.with_row(display: [:block, :none, :none, :none, :none]) do - flex_layout do |flex| - if count == 0 - render(Primer::Beta::Text.new) { t("label_meeting_no_participants") } - else - flex.with_row(mb: 1, display: :none, data: { 'meetings-sidebar-participants-target': "hiddenMobileParticipants" }) do - flex_layout do |details| - @meeting.invited_or_attended_participants.sort.each do |participant| - details.with_row(mt: 1) do - render_participant(participant) - end - end - end - end - flex.with_row do - flex.with_column do - render(Primer::Beta::Octicon.new('people', mr: 1)) - end - flex.with_column do - render(Primer::Beta::Text.new(mr: 1)) { t('label_meeting_count_participants', count: @meeting.invited_or_attended_participants.count) } - end - flex.with_column(data: { 'meetings-sidebar-participants-target': "showHideMobileButton" }) do - render(Primer::Beta::Link.new(href: "#", target: "_blank")) do - I18n.t('label_meeting_show_hide_all_participants') - end - end - end - end - end - end - if @meeting.editable? - participants_container.with_row(mt: 3, hide: :sm) do + participants_container.with_row(mt: 3) do render(Primer::Beta::Button.new( scheme: :link, color: :default, diff --git a/modules/meeting/app/components/meetings/sidebar_component.html.erb b/modules/meeting/app/components/meetings/sidebar_component.html.erb index 565f3705a58d..182e5b13787a 100644 --- a/modules/meeting/app/components/meetings/sidebar_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar_component.html.erb @@ -3,7 +3,7 @@ render(Primer::OpenProject::BorderGrid.new) do |border_grid| border_grid.with_row { render(Meetings::Sidebar::DetailsComponent.new(meeting: @meeting)) } border_grid.with_row { render(Meetings::Sidebar::StateComponent.new(meeting: @meeting)) } - border_grid.with_row(hide: :sm) { render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) } + border_grid.with_row { render(Meetings::Sidebar::ParticipantsComponent.new(meeting: @meeting)) } end end %> From 43a0277aa8f145c7007155e821d108887f70a5e7 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 14 Nov 2023 15:37:41 +0100 Subject: [PATCH 43/44] remove unnecessary methods and strings --- .../meetings-sidebar-participants.controller.ts | 16 +++++----------- .../sidebar/participants_component.html.erb | 5 +++-- modules/meeting/config/locales/en.yml | 2 -- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts index 19972443ccfb..061508d40e8d 100644 --- a/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/meetings-sidebar-participants.controller.ts @@ -35,17 +35,11 @@ export default class MeetingsSidebarParticipantsController extends Controller { declare readonly showHideButtonTarget:HTMLInputElement; declare readonly hiddenParticipantsTarget:HTMLElement; - connect():void { - this.showHiddenParticipants(); - } - showHiddenParticipants():void { - this.showHideButtonTarget.addEventListener('click', () => { - if (this.hiddenParticipantsTarget.classList.contains('d-none')) { - this.hiddenParticipantsTarget.classList.remove('d-none'); - } else { - this.hiddenParticipantsTarget.classList.add('d-none'); - } - }); + if (this.hiddenParticipantsTarget.classList.contains('d-none')) { + this.hiddenParticipantsTarget.classList.remove('d-none'); + } else { + this.hiddenParticipantsTarget.classList.add('d-none'); + } } } diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index c87f86ee5267..d4dbcf6a5a7a 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -61,8 +61,9 @@ end flex.with_row(mt: 1) do render (Primer::Beta::Button.new(scheme: :invisible, - data: { 'meetings-sidebar-participants-target': "showHideButton" })) { I18n.t('label_meeting_show_hide_participants', - count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } + data: { 'meetings-sidebar-participants-target': "showHideButton", + action: 'click->meetings-sidebar-participants#showHiddenParticipants keydown.enter->meetings-sidebar-participants#showHiddenParticipants'})) + { I18n.t('label_meeting_show_hide_participants', count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } end end end diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index f0d7e537bb97..8edaad09090b 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -188,8 +188,6 @@ en: label_meeting_manage_participants: "Manage participants" label_meeting_no_participants: "No participants" label_meeting_show_hide_participants: "Show/hide %{count} more" - label_meeting_show_hide_all_participants: "Show/hide all" - label_meeting_count_participants: "%{count} participants" label_meeting_add_participants: "Add participants" text_meeting_not_editable_anymore: "This meeting is not editable anymore." From 56963e7c3b82f6d2867f8830d898bba5721b5140 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Wed, 15 Nov 2023 11:14:37 +0100 Subject: [PATCH 44/44] fix unit test error --- .../meetings/sidebar/participants_component.html.erb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb index d4dbcf6a5a7a..13482b57ae98 100644 --- a/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb +++ b/modules/meeting/app/components/meetings/sidebar/participants_component.html.erb @@ -60,10 +60,12 @@ end end flex.with_row(mt: 1) do - render (Primer::Beta::Button.new(scheme: :invisible, - data: { 'meetings-sidebar-participants-target': "showHideButton", - action: 'click->meetings-sidebar-participants#showHiddenParticipants keydown.enter->meetings-sidebar-participants#showHiddenParticipants'})) - { I18n.t('label_meeting_show_hide_participants', count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } + render (Primer::Beta::Button.new( + scheme: :invisible, + data: { 'meetings-sidebar-participants-target': "showHideButton", + action: 'click->meetings-sidebar-participants#showHiddenParticipants keydown.enter->meetings-sidebar-participants#showHiddenParticipants' + } + )) { I18n.t('label_meeting_show_hide_participants', count: @meeting.invited_or_attended_participants.count - MAX_SHOWN_PARTICIPANTS) } end end end