diff --git a/app/models/journal.rb b/app/models/journal.rb index 28e3195b639..ec4ace6e18b 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -49,6 +49,7 @@ class Journal < ApplicationRecord register_journal_formatter OpenProject::JournalFormatter::AgendaItemDuration register_journal_formatter OpenProject::JournalFormatter::AgendaItemPosition register_journal_formatter OpenProject::JournalFormatter::AgendaItemTitle + register_journal_formatter OpenProject::JournalFormatter::AllocatedTime register_journal_formatter OpenProject::JournalFormatter::Attachment register_journal_formatter OpenProject::JournalFormatter::Cause register_journal_formatter OpenProject::JournalFormatter::CustomComment diff --git a/modules/resource_management/app/components/resource_allocations/allocation_step/footer_component.rb b/modules/resource_management/app/components/resource_allocations/allocation_step/footer_component.rb new file mode 100644 index 00000000000..e964d93f5dd --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/allocation_step/footer_component.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module AllocationStep + class FooterComponent < ApplicationComponent + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def wrapper_key + ResourceAllocations::NewDialogComponent::FOOTER_ID + end + + def call + component_wrapper do + component_collection do |buttons| + buttons.with_component( + Primer::Beta::Button.new( + data: { "close-dialog-id": ResourceAllocations::NewDialogComponent::DIALOG_ID }, + mr: 1 + ) + ) { I18n.t(:button_cancel) } + + buttons.with_component( + Primer::Beta::Button.new( + scheme: :primary, + form: ResourceAllocations::NewDialogComponent::FORM_ID, + type: :submit + ) + ) { I18n.t("resource_management.allocate_resource_dialog.submit") } + end + end + end + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.html.erb b/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.html.erb new file mode 100644 index 00000000000..bcb428e6c9d --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.html.erb @@ -0,0 +1,16 @@ +<%= + component_wrapper do + primer_form_with( + model: @allocation, + scope: :resource_allocation, + url: project_resource_allocations_path(@project), + method: :post, + html: { + data: { turbo_stream: true }, + id: ResourceAllocations::NewDialogComponent::FORM_ID + } + ) do |f| + render(form_list_component(f)) + end + end +%> diff --git a/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.rb b/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.rb new file mode 100644 index 00000000000..817af14a69f --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/allocation_step/form_component.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module AllocationStep + class FormComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def initialize(allocation:, project:, allocation_kind:) + super + @allocation = allocation + @project = project + @allocation_kind = allocation_kind + end + + def wrapper_key + ResourceAllocations::NewDialogComponent::BODY_ID + end + + private + + def filter_based? + @allocation_kind.to_s == "filter" + end + + def dialog_id + ResourceAllocations::NewDialogComponent::DIALOG_ID + end + + def form_list_component(form) + prepends = if filter_based? + [ + ResourceAllocations::Forms::FilterNameForm.new(form), + ::Filters::FilterFormComponent.new( + builder: form, + query: @allocation.candidate_query, + wrap_with_controller: true, + hidden_input_name: "filters", + output_format: :json, + autocomplete_append_to: "##{dialog_id}" + ) + ] + else + [ + ResourceAllocations::Forms::PrincipalForm.new( + form, + project: @project, + dialog_id: dialog_id + ) + ] + end + + Primer::Forms::FormList.new( + *prepends, + ResourceAllocations::Forms::WorkPackageForm.new(form, project: @project, dialog_id: dialog_id), + ResourceAllocations::Forms::DateRangeForm.new(form, dialog_id: dialog_id), + ResourceAllocations::Forms::HoursForm.new(form), + ResourceAllocations::Forms::AllocationKindForm.new(form, allocation_kind: @allocation_kind) + ) + end + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/kind_step/footer_component.rb b/modules/resource_management/app/components/resource_allocations/kind_step/footer_component.rb new file mode 100644 index 00000000000..19f2e10dac6 --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/kind_step/footer_component.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module KindStep + class FooterComponent < ApplicationComponent + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def wrapper_key + ResourceAllocations::NewDialogComponent::FOOTER_ID + end + + def call + component_wrapper do + component_collection do |buttons| + buttons.with_component( + Primer::Beta::Button.new( + data: { "close-dialog-id": ResourceAllocations::NewDialogComponent::DIALOG_ID }, + mr: 1 + ) + ) { I18n.t(:button_cancel) } + + buttons.with_component( + Primer::Beta::Button.new( + scheme: :primary, + form: ResourceAllocations::NewDialogComponent::FORM_ID, + type: :submit + ) + ) { I18n.t("button_next") } + end + end + end + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/kind_step/form_component.html.erb b/modules/resource_management/app/components/resource_allocations/kind_step/form_component.html.erb new file mode 100644 index 00000000000..d00fc391d0d --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/kind_step/form_component.html.erb @@ -0,0 +1,14 @@ +<%= + component_wrapper do + primer_form_with( + url: step_project_resource_allocations_path(@project), + method: :get, + html: { + data: { turbo_stream: true }, + id: ResourceAllocations::NewDialogComponent::FORM_ID + } + ) do |f| + render(ResourceAllocations::Forms::KindSelectForm.new(f, work_package: @work_package)) + end + end +%> diff --git a/modules/resource_management/app/components/resource_allocations/kind_step/form_component.rb b/modules/resource_management/app/components/resource_allocations/kind_step/form_component.rb new file mode 100644 index 00000000000..de71e0d771f --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/kind_step/form_component.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module KindStep + class FormComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def initialize(project:, work_package: nil) + super + @project = project + @work_package = work_package + end + + def wrapper_key + ResourceAllocations::NewDialogComponent::BODY_ID + end + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/new_dialog_component.html.erb b/modules/resource_management/app/components/resource_allocations/new_dialog_component.html.erb new file mode 100644 index 00000000000..34fa57f69e6 --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/new_dialog_component.html.erb @@ -0,0 +1,55 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 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. + +++#%> + +<%= + render( + Primer::Alpha::Dialog.new( + id: DIALOG_ID, + title:, + size: :large, + classes: "Overlay--size-large-portrait", + data: { "keep-open-on-submit": true } + ) + ) do |dialog| + dialog.with_header(variant: :large) + + dialog.with_body(classes: "Overlay-body_autocomplete_height") do + render( + ResourceAllocations::KindStep::FormComponent.new( + project: @project, + work_package: @work_package + ) + ) + end + + dialog.with_footer do + render(ResourceAllocations::KindStep::FooterComponent.new) + end + end +%> diff --git a/modules/resource_management/app/components/resource_allocations/new_dialog_component.rb b/modules/resource_management/app/components/resource_allocations/new_dialog_component.rb new file mode 100644 index 00000000000..fabd0ba9d8b --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/new_dialog_component.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + class NewDialogComponent < ApplicationComponent + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + DIALOG_ID = "allocate-resource-dialog" + FORM_ID = "allocate-resource-form" + FOOTER_ID = "allocate-resource-footer" + # Shared by both step forms so swapping step 1 for step 2 targets the same + # Turbo stream wrapper. + BODY_ID = "allocate-resource-dialog-body" + + def initialize(project:, work_package: nil) + super + + @project = project + @work_package = work_package + end + + private + + def title + I18n.t("resource_management.allocate_resource_dialog.title") + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/outside_dates_step/footer_component.rb b/modules/resource_management/app/components/resource_allocations/outside_dates_step/footer_component.rb new file mode 100644 index 00000000000..bd4ed31cf92 --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/outside_dates_step/footer_component.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module OutsideDatesStep + class FooterComponent < ApplicationComponent + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def wrapper_key + ResourceAllocations::NewDialogComponent::FOOTER_ID + end + + def call + component_wrapper(:footer_layout, align_items: :center, flex: 1) do |footer| + footer.with_column(mr: :auto) do + render( + Primer::Beta::Button.new( + scheme: :invisible, + form: ResourceAllocations::NewDialogComponent::FORM_ID, + type: :submit, + name: "back", + value: "1" + ) + ) do |button| + button.with_leading_visual_icon(icon: :"arrow-left") + I18n.t(:button_back) + end + end + + footer.with_column(mr: 1) do + render( + Primer::Beta::Button.new( + data: { "close-dialog-id": ResourceAllocations::NewDialogComponent::DIALOG_ID } + ) + ) { I18n.t(:button_cancel) } + end + + footer.with_column do + render( + Primer::Beta::Button.new( + scheme: :danger, + form: ResourceAllocations::NewDialogComponent::FORM_ID, + type: :submit, + name: "confirmed", + value: "1" + ) + ) { I18n.t("resource_management.allocate_resource_dialog.submit") } + end + end + end + + private + + # Renders the turbo-stream wrapper as a Primer flex container so the footer + # layout uses system arguments instead of inline styles. Receives the + # wrapper arguments (including the `id`) from `component_wrapper`. + def footer_layout(system_arguments, &) + flex_layout(**system_arguments, &) + end + end + end +end diff --git a/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.html.erb b/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.html.erb new file mode 100644 index 00000000000..da2d780be3d --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.html.erb @@ -0,0 +1,38 @@ +<%= + component_wrapper do + flex_layout(align_items: :center, text_align: :center, p: 3) do |body| + body.with_row(mb: 2) do + render(Primer::Beta::Octicon.new(:calendar, size: :medium, color: :danger)) + end + + body.with_row(mb: 2) do + render(Primer::Beta::Heading.new(tag: :h2, font_size: 4)) { heading } + end + + body.with_row(mb: 1) do + render(Primer::Beta::Text.new(tag: :p, color: :muted, m: 0)) { description } + end + + body.with_row do + render(Primer::Beta::Text.new(tag: :p, color: :muted, m: 0)) { confirmation } + end + + body.with_row do + form_with( + url: project_resource_allocations_path(@project), + method: :post, + id: ResourceAllocations::NewDialogComponent::FORM_ID, + data: { turbo_stream: true } + ) do + safe_join( + [ + hidden_field_tag("allocation_kind", @allocation_kind), + (hidden_field_tag("filters", @filters) if @filters.present?), + *@form_values.map { |name, value| hidden_field_tag("resource_allocation[#{name}]", value) } + ].compact + ) + end + end + end + end +%> diff --git a/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.rb b/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.rb new file mode 100644 index 00000000000..3e029a18505 --- /dev/null +++ b/modules/resource_management/app/components/resource_allocations/outside_dates_step/form_component.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 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. +#++ + +module ResourceAllocations + module OutsideDatesStep + class FormComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + def initialize(allocation:, project:, allocation_kind:, form_values:, filters: nil) + super + @allocation = allocation + @project = project + @allocation_kind = allocation_kind + @form_values = form_values + @filters = filters + end + + def wrapper_key + ResourceAllocations::NewDialogComponent::BODY_ID + end + + private + + def heading + I18n.t("resource_management.allocate_resource_dialog.outside_dates.title") + end + + def description + I18n.t( + "resource_management.allocate_resource_dialog.outside_dates.description", + resource_dates: date_range(@allocation.start_date, @allocation.end_date), + work_package_dates: date_range(@allocation.entity_start_date, @allocation.entity_due_date) + ) + end + + def confirmation + I18n.t("resource_management.allocate_resource_dialog.outside_dates.confirm_#{@allocation.schedule_violation}") + end + + def date_range(from_date, to_date) + "#{format_or_dash(from_date)} - #{format_or_dash(to_date)}" + end + + def format_or_dash(date) + date.present? ? helpers.format_date(date) : "—" + end + end + end +end diff --git a/modules/resource_management/app/components/resource_planner_views/configure_step/footer_component.rb b/modules/resource_management/app/components/resource_planner_views/configure_step/footer_component.rb index f0ff80515ce..e933e1bdb4e 100644 --- a/modules/resource_management/app/components/resource_planner_views/configure_step/footer_component.rb +++ b/modules/resource_management/app/components/resource_planner_views/configure_step/footer_component.rb @@ -68,10 +68,8 @@ module ResourcePlannerViews private - # When a `cancel_href` is passed, Cancel becomes a link that navigates - # away — used by the new-planner flow so dismissing step 2 lands the - # user on a page that reflects the just-created planner. Without one, - # Cancel just dismisses the dialog (standalone "+ Add view" flow). + # The new-planner flow passes a `cancel_href` so dismissing step 2 still + # lands on the just-created planner rather than just closing the dialog. def cancel_button if @cancel_href Primer::Beta::Button.new(tag: :a, href: @cancel_href, mr: 1) diff --git a/modules/resource_management/app/components/resource_planner_views/configure_step/form_component.rb b/modules/resource_management/app/components/resource_planner_views/configure_step/form_component.rb index 2925b5148c9..1121b4c2872 100644 --- a/modules/resource_management/app/components/resource_planner_views/configure_step/form_component.rb +++ b/modules/resource_management/app/components/resource_planner_views/configure_step/form_component.rb @@ -30,13 +30,10 @@ module ResourcePlannerViews module ConfigureStep - # Renders the "Configure view" form (name + filter mode). Used both for - # the new-view dialog (step 2) and for the edit dialog. Callers - # pass the form `url`, HTTP `method`, and the model to bind to. The - # `form_id` lets the surrounding dialog wire its submit button to this - # form via `