From 45359017caa0e3ff8eabc7c7365c422f9b2b87f6 Mon Sep 17 00:00:00 2001 From: Judith Roth Date: Wed, 26 Jun 2024 17:55:25 +0200 Subject: [PATCH 01/11] [#55960] Refactor admin storages settings edit to use a header component https://community.openproject.org/work_packages/55960 --- .../admin/edit_form_header_component.html.erb | 47 ++++++++++++++++ .../admin/edit_form_header_component.rb | 54 +++++++++++++++++++ .../storages/admin/storages/edit.html.erb | 33 ++---------- 3 files changed, 106 insertions(+), 28 deletions(-) create mode 100644 modules/storages/app/components/storages/admin/edit_form_header_component.html.erb create mode 100644 modules/storages/app/components/storages/admin/edit_form_header_component.rb diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb new file mode 100644 index 000000000000..bb456bdc598a --- /dev/null +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb @@ -0,0 +1,47 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-2024 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::OpenProject::PageHeader.new) do |header| + header.with_title(test_selector: 'storage-new-page-header--title') do + render OpTurbo::FrameComponent.new(@storage, context: :edit_storage_header) do + label_storage_name_with_provider_label + end + end + header.with_breadcrumbs(breadcrumbs_items) + header.with_action_button(scheme: :danger, + mobile_icon: :trash, + mobile_label: I18n.t("button_delete"), + type: :submit, + aria: { label: I18n.t("storages.label_delete_storage") }, + test_selector: "storage-delete-button") do |button| + button.with_leading_visual_icon(icon: :trash) + I18n.t("button_delete") + end + end +%> diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.rb b/modules/storages/app/components/storages/admin/edit_form_header_component.rb new file mode 100644 index 000000000000..21dcae49cf1c --- /dev/null +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.rb @@ -0,0 +1,54 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 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 Storages + module Admin + class EditFormHeaderComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent + def initialize(storage:) + super + @storage = storage + end + + def label_storage_name_with_provider_label + "#{h(@storage.name)} #{label_storage_provider_part}".html_safe # rubocop:disable Rails/OutputSafety + end + + def label_storage_provider_part + render(Primer::Beta::Text.new(tag: :span, font_weight: :light, color: :muted)) do + "(#{I18n.t("storages.provider_types.#{h(@storage.short_provider_type)}.name")})" + end + end + + def breadcrumbs_items + [{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_storages_path, text: t("project_module_storages") }, + @storage.name] + end + end + end +end diff --git a/modules/storages/app/views/storages/admin/storages/edit.html.erb b/modules/storages/app/views/storages/admin/storages/edit.html.erb index b5d320e8349a..83eb999e4e76 100644 --- a/modules/storages/app/views/storages/admin/storages/edit.html.erb +++ b/modules/storages/app/views/storages/admin/storages/edit.html.erb @@ -27,13 +27,6 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<% - label_storage_provider_part = render(Primer::Beta::Text.new(tag: :span, font_weight: :light, color: :muted)) do - "(#{I18n.t("storages.provider_types.#{@storage.short_provider_type}.name")})" - end - label_storage_name_with_provider_label = "#{@storage.name} #{label_storage_provider_part}".html_safe -%> - <% html_title t(:label_administration), t("project_module_storages"), t('label_edit_x', x: @storage.name) %> <%= primer_form_with( @@ -41,27 +34,11 @@ See COPYRIGHT and LICENSE files for more details. url: confirm_destroy_admin_settings_storage_path(@storage), method: :get ) do %> - <%= render(Primer::OpenProject::PageHeader.new) do |header| %> - <% header.with_title(test_selector: 'storage-new-page-header--title') do %> - <%= render OpTurbo::FrameComponent.new(@storage, context: :edit_storage_header) do %> - <%= label_storage_name_with_provider_label %> - <% end %> - <% end %> - - <% header.with_breadcrumbs([{href: admin_index_path, text: t("label_administration")}, - {href: admin_settings_storages_path, text: t("project_module_storages")}, - @storage.name]) %> - - <% header.with_action_button(scheme: :danger, - mobile_icon: :trash, - mobile_label: I18n.t("button_delete"), - type: :submit, - aria: { label: I18n.t("storages.label_delete_storage") }, - test_selector: "storage-delete-button") do |button| - button.with_leading_visual_icon(icon: :trash) - I18n.t("button_delete") - end %> - <% end %> + <%= + render(Storages::Admin::EditFormHeaderComponent.new( + storage: @storage + )) + %> <% end %> <% display_sidebar = @storage.provider_type_one_drive? || @storage.automatic_management_enabled? %> From 50a605b5ac2e887313b3e3a7e497dc2d5d5f2fbd Mon Sep 17 00:00:00 2001 From: Judith Roth Date: Fri, 28 Jun 2024 13:13:23 +0200 Subject: [PATCH 02/11] [#55960] Add the "Enabled in Projects" tab in storage edit view https://community.openproject.org/work_packages/55960 --- .../edit_form_header_component.html.erb | 2 +- config/locales/en.yml | 3 +- .../admin/edit_form_header_component.html.erb | 15 ++++++++ .../admin/edit_form_header_component.rb | 13 ++++++- .../storages/admin/storages_controller.rb | 4 ++- .../storages/admin/storages/edit.html.erb | 3 +- .../admin/storages/project_mappings.html.erb | 36 +++++++++++++++++++ modules/storages/config/routes.rb | 1 + 8 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 modules/storages/app/views/storages/admin/storages/project_mappings.html.erb diff --git a/app/components/settings/project_custom_fields/edit_form_header_component.html.erb b/app/components/settings/project_custom_fields/edit_form_header_component.html.erb index d77783af62a1..d4802f1b25ff 100644 --- a/app/components/settings/project_custom_fields/edit_form_header_component.html.erb +++ b/app/components/settings/project_custom_fields/edit_form_header_component.html.erb @@ -43,7 +43,7 @@ See COPYRIGHT and LICENSE files for more details. selected: project_custom_field_project_mappings_selected?, href: project_mappings_admin_settings_project_custom_field_path(@custom_field) ) do |tab| - tab.with_text { I18n.t("projects.settings.project_custom_fields.project_mappings.header") } + tab.with_text { t(:label_project_mappings) } end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index ca2765992e2d..c1211ea786ca 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -337,8 +337,6 @@ Project attributes and sections are defined in the diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.rb b/modules/storages/app/components/storages/admin/edit_form_header_component.rb index 21dcae49cf1c..f6a923e06e40 100644 --- a/modules/storages/app/components/storages/admin/edit_form_header_component.rb +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.rb @@ -29,9 +29,20 @@ module Storages module Admin class EditFormHeaderComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent - def initialize(storage:) + TAB_NAVS = %i[ + edit + project_mappings + ].freeze + + def initialize(storage:, selected:) super @storage = storage + @selected = selected + end + + def tab_selected?(tab_name) + TAB_NAVS.include?(tab_name) && + tab_name == @selected end def label_storage_name_with_provider_label diff --git a/modules/storages/app/controllers/storages/admin/storages_controller.rb b/modules/storages/app/controllers/storages/admin/storages_controller.rb index bacb294a174d..f084e2ffb1ea 100644 --- a/modules/storages/app/controllers/storages/admin/storages_controller.rb +++ b/modules/storages/app/controllers/storages/admin/storages_controller.rb @@ -46,7 +46,7 @@ class Storages::Admin::StoragesController < ApplicationController before_action :require_admin before_action :find_model_object, only: %i[show_oauth_application destroy edit edit_host confirm_destroy update - change_health_notifications_enabled replace_oauth_application] + change_health_notifications_enabled replace_oauth_application project_mappings] before_action :ensure_valid_provider_type_selected, only: %i[select_provider] before_action :require_ee_token_for_one_drive, only: %i[select_provider] @@ -208,6 +208,8 @@ def replace_oauth_application end end + def project_mappings; end + def default_breadcrumb; end def show_local_breadcrumb diff --git a/modules/storages/app/views/storages/admin/storages/edit.html.erb b/modules/storages/app/views/storages/admin/storages/edit.html.erb index 83eb999e4e76..8d8e7f2d2d1d 100644 --- a/modules/storages/app/views/storages/admin/storages/edit.html.erb +++ b/modules/storages/app/views/storages/admin/storages/edit.html.erb @@ -36,7 +36,8 @@ See COPYRIGHT and LICENSE files for more details. ) do %> <%= render(Storages::Admin::EditFormHeaderComponent.new( - storage: @storage + storage: @storage, + selected: :edit )) %> <% end %> diff --git a/modules/storages/app/views/storages/admin/storages/project_mappings.html.erb b/modules/storages/app/views/storages/admin/storages/project_mappings.html.erb new file mode 100644 index 000000000000..7dbce9141416 --- /dev/null +++ b/modules/storages/app/views/storages/admin/storages/project_mappings.html.erb @@ -0,0 +1,36 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-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. + +++#%> + +<%= + render(Storages::Admin::EditFormHeaderComponent.new( + storage: @storage, + selected: :project_mappings + ) + ) +%> diff --git a/modules/storages/config/routes.rb b/modules/storages/config/routes.rb index 04b2d533977b..3654c773320e 100644 --- a/modules/storages/config/routes.rb +++ b/modules/storages/config/routes.rb @@ -58,6 +58,7 @@ patch :change_health_notifications_enabled get :confirm_destroy delete :replace_oauth_application + get :project_mappings end get :upsale, on: :collection From c4ad0f65542b58cbe05a37a428d9d8fef3183b6f Mon Sep 17 00:00:00 2001 From: Judith Roth Date: Tue, 2 Jul 2024 16:29:50 +0200 Subject: [PATCH 03/11] [#55960] Hide changes behind feature flag --- .../admin/edit_form_header_component.html.erb | 26 ++++++++++--------- .../lib/open_project/storages/engine.rb | 1 + 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb index 7439ade12a64..0cb7dd59ff70 100644 --- a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb @@ -43,19 +43,21 @@ See COPYRIGHT and LICENSE files for more details. button.with_leading_visual_icon(icon: :trash) I18n.t("button_delete") end - header.with_tab_nav(label: nil, test_selector: :project_attribute_detail_header) do |tab_nav| - tab_nav.with_tab( - selected: tab_selected?(:edit), - href: edit_admin_settings_storage_path(@storage) - ) do |tab| - tab.with_text { t(:label_details) } - end + if OpenProject::FeatureDecisions.enable_storage_for_multiple_projects_active? + header.with_tab_nav(label: nil, test_selector: :project_attribute_detail_header) do |tab_nav| + tab_nav.with_tab( + selected: tab_selected?(:edit), + href: edit_admin_settings_storage_path(@storage) + ) do |tab| + tab.with_text { t(:label_details) } + end - tab_nav.with_tab( - selected: tab_selected?(:project_mappings), - href: project_mappings_admin_settings_storage_path(@storage) - ) do |tab| - tab.with_text { t(:label_project_mappings) } + tab_nav.with_tab( + selected: tab_selected?(:project_mappings), + href: project_mappings_admin_settings_storage_path(@storage) + ) do |tab| + tab.with_text { t(:label_project_mappings) } + end end end end diff --git a/modules/storages/lib/open_project/storages/engine.rb b/modules/storages/lib/open_project/storages/engine.rb index a0115a9ffa4f..55b9948111dd 100644 --- a/modules/storages/lib/open_project/storages/engine.rb +++ b/modules/storages/lib/open_project/storages/engine.rb @@ -48,6 +48,7 @@ def self.permissions initializer "openproject_storages.feature_decisions" do OpenProject::FeatureDecisions.add :storage_file_picking_select_all + OpenProject::FeatureDecisions.add :enable_storage_for_multiple_projects end initializer "openproject_storages.event_subscriptions" do From 15095e4e1cacbc25710f927496ec07e2bceb0633 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Tue, 2 Jul 2024 18:59:36 +0300 Subject: [PATCH 04/11] [#55966] Define "Enabled in Projects" as a fully qualified nested resource https://community.openproject.org/work_packages/55966 The storages controller is already overloaded, defined a nested controller instead that can much more easily follow rails CRUD conventions. --- .../admin/edit_form_header_component.html.erb | 11 ++-- .../projects/project_storages_controller.rb | 55 +++++++++++++++++++ .../storages/admin/storages_controller.rb | 4 +- .../project_storages/index.html.erb} | 16 ++++++ modules/storages/config/routes.rb | 9 ++- 5 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb rename modules/storages/app/views/storages/admin/{storages/project_mappings.html.erb => projects/project_storages/index.html.erb} (71%) diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb index 0cb7dd59ff70..d2ee53ce85cf 100644 --- a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb @@ -52,12 +52,11 @@ See COPYRIGHT and LICENSE files for more details. tab.with_text { t(:label_details) } end - tab_nav.with_tab( - selected: tab_selected?(:project_mappings), - href: project_mappings_admin_settings_storage_path(@storage) - ) do |tab| - tab.with_text { t(:label_project_mappings) } - end + tab_nav.with_tab( + selected: tab_selected?(:project_mappings), + href: admin_settings_storage_projects_project_storages_path(@storage) + ) do |tab| + tab.with_text { t(:label_project_mappings) } end end end diff --git a/modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb b/modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb new file mode 100644 index 000000000000..467f4fda7549 --- /dev/null +++ b/modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2024 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. +#++ + +class Storages::Admin::Projects::ProjectStoragesController < ApplicationController + include OpTurbo::ComponentStream + + layout "admin" + + model_object Storages::Storage + + before_action :require_admin + before_action :find_model_object + + menu_item :external_file_storages + + def index; end + def new; end + def create; end + def show; end + def destroy; end + + private + + def find_model_object(object_id = :storage_id) + super + @storage = @object + end +end diff --git a/modules/storages/app/controllers/storages/admin/storages_controller.rb b/modules/storages/app/controllers/storages/admin/storages_controller.rb index f084e2ffb1ea..bacb294a174d 100644 --- a/modules/storages/app/controllers/storages/admin/storages_controller.rb +++ b/modules/storages/app/controllers/storages/admin/storages_controller.rb @@ -46,7 +46,7 @@ class Storages::Admin::StoragesController < ApplicationController before_action :require_admin before_action :find_model_object, only: %i[show_oauth_application destroy edit edit_host confirm_destroy update - change_health_notifications_enabled replace_oauth_application project_mappings] + change_health_notifications_enabled replace_oauth_application] before_action :ensure_valid_provider_type_selected, only: %i[select_provider] before_action :require_ee_token_for_one_drive, only: %i[select_provider] @@ -208,8 +208,6 @@ def replace_oauth_application end end - def project_mappings; end - def default_breadcrumb; end def show_local_breadcrumb diff --git a/modules/storages/app/views/storages/admin/storages/project_mappings.html.erb b/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb similarity index 71% rename from modules/storages/app/views/storages/admin/storages/project_mappings.html.erb rename to modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb index 7dbce9141416..82ce89b5aaa4 100644 --- a/modules/storages/app/views/storages/admin/storages/project_mappings.html.erb +++ b/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb @@ -34,3 +34,19 @@ See COPYRIGHT and LICENSE files for more details. ) ) %> + +<%= + render(Primer::OpenProject::SubHeader.new) do |component| + component.with_action_component do + render(Primer::Beta::Button.new( + scheme: :primary, + tag: :a, + href: new_admin_settings_storage_projects_project_storage_path(@storage), + data: { controller: "async-dialog" } + )) do |button| + button.with_leading_visual_icon(icon: 'op-include-projects') + I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") + end + end + end +%> diff --git a/modules/storages/config/routes.rb b/modules/storages/config/routes.rb index 3654c773320e..a8b268bb90b0 100644 --- a/modules/storages/config/routes.rb +++ b/modules/storages/config/routes.rb @@ -40,10 +40,16 @@ resource :automatically_managed_project_folders, controller: "/storages/admin/automatically_managed_project_folders", - only: %i[new create edit update] + only: %i[index new create edit update] resource :access_management, controller: "/storages/admin/access_management", only: %i[new create edit update] + namespace :projects do + resources :project_storages, + controller: "/storages/admin/projects/project_storages", + only: %i[index new create destroy] + end + resource :connection_validation, controller: "/storages/admin/connection_validation", only: [] do @@ -58,7 +64,6 @@ patch :change_health_notifications_enabled get :confirm_destroy delete :replace_oauth_application - get :project_mappings end get :upsale, on: :collection From 9fd6929f341d97aadec60f07791510819f9c53aa Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 3 Jul 2024 14:43:26 +0300 Subject: [PATCH 05/11] fix(Admin Menu Item): Use absolute path to mitigate routing exception red herring Without absolute paths, the routing definitions seem to implicitly scope within the current engine/namespace (not sure) Causing an exception like so: ```ruby # lib/redmine/menu_manager/menu_helper.rb:387 Redmine::MenuManager::MenuHelper#node_url: [7] pry(#<#>)> e => #"index", :controller=>"storages/webhooks/outgoing/admin", :layout=>nil, :storage_id=>"20"}> ``` --- From [@Klaus's](https://matrix.to/#/!fyQrllnnogDxQuleQW:openproject.org/$nO-kY0NegsJ9E3w-P1Lx3YtgeQeutrQ_ohR0xpsljjg?via=openproject.org) impression it seems using `namespace:` routes is the root cause. But this is still an odd and difficult bug to solve so we should probably think around improving it. Co-authored-by: Pavel Balashou --- modules/webhooks/lib/open_project/webhooks/engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/webhooks/lib/open_project/webhooks/engine.rb b/modules/webhooks/lib/open_project/webhooks/engine.rb index 4b65c8343fa1..af9f121f4a7e 100644 --- a/modules/webhooks/lib/open_project/webhooks/engine.rb +++ b/modules/webhooks/lib/open_project/webhooks/engine.rb @@ -39,7 +39,7 @@ class Engine < ::Rails::Engine author_url: "https://www.openproject.org" do menu :admin_menu, :plugin_webhooks, - { controller: "webhooks/outgoing/admin", action: :index }, + { controller: "/webhooks/outgoing/admin", action: :index }, if: Proc.new { User.current.admin? }, parent: :api_and_webhooks, caption: :"webhooks.plural" From bbe1ba7fd0d121c6a3df76d3c2eb0b0f0d0de9b2 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 3 Jul 2024 14:57:51 +0300 Subject: [PATCH 06/11] fix syntax error in template --- .../admin/edit_form_header_component.html.erb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb index d2ee53ce85cf..5697d313de96 100644 --- a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb @@ -33,7 +33,9 @@ See COPYRIGHT and LICENSE files for more details. label_storage_name_with_provider_label end end + header.with_breadcrumbs(breadcrumbs_items) + header.with_action_button(scheme: :danger, mobile_icon: :trash, mobile_label: I18n.t("button_delete"), @@ -43,6 +45,7 @@ See COPYRIGHT and LICENSE files for more details. button.with_leading_visual_icon(icon: :trash) I18n.t("button_delete") end + if OpenProject::FeatureDecisions.enable_storage_for_multiple_projects_active? header.with_tab_nav(label: nil, test_selector: :project_attribute_detail_header) do |tab_nav| tab_nav.with_tab( @@ -52,11 +55,12 @@ See COPYRIGHT and LICENSE files for more details. tab.with_text { t(:label_details) } end - tab_nav.with_tab( - selected: tab_selected?(:project_mappings), - href: admin_settings_storage_projects_project_storages_path(@storage) - ) do |tab| - tab.with_text { t(:label_project_mappings) } + tab_nav.with_tab( + selected: tab_selected?(:project_mappings), + href: admin_settings_storage_projects_project_storages_path(@storage) + ) do |tab| + tab.with_text { t(:label_project_mappings) } + end end end end From a3992db2847769024a98fcf6bd479d2d07bc037a Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 3 Jul 2024 15:03:10 +0300 Subject: [PATCH 07/11] chore(Routing): Replace with scope module for nicer routing paths --- .../storages/admin/edit_form_header_component.html.erb | 2 +- .../storages/admin/projects/project_storages/index.html.erb | 2 +- modules/storages/config/routes.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb index 5697d313de96..b5129d3b5acc 100644 --- a/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb +++ b/modules/storages/app/components/storages/admin/edit_form_header_component.html.erb @@ -57,7 +57,7 @@ See COPYRIGHT and LICENSE files for more details. tab_nav.with_tab( selected: tab_selected?(:project_mappings), - href: admin_settings_storage_projects_project_storages_path(@storage) + href: admin_settings_storage_project_storages_path(@storage) ) do |tab| tab.with_text { t(:label_project_mappings) } end diff --git a/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb b/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb index 82ce89b5aaa4..9a0850f79309 100644 --- a/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb +++ b/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb @@ -41,7 +41,7 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::Beta::Button.new( scheme: :primary, tag: :a, - href: new_admin_settings_storage_projects_project_storage_path(@storage), + href: new_admin_settings_storage_project_storage_path(@storage), data: { controller: "async-dialog" } )) do |button| button.with_leading_visual_icon(icon: 'op-include-projects') diff --git a/modules/storages/config/routes.rb b/modules/storages/config/routes.rb index a8b268bb90b0..774f79d50547 100644 --- a/modules/storages/config/routes.rb +++ b/modules/storages/config/routes.rb @@ -44,7 +44,7 @@ resource :access_management, controller: "/storages/admin/access_management", only: %i[new create edit update] - namespace :projects do + scope module: :projects do resources :project_storages, controller: "/storages/admin/projects/project_storages", only: %i[index new create destroy] From 3c4690d001a4f0e2f1b70a370fe793a04e2330f6 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Wed, 3 Jul 2024 15:44:58 +0300 Subject: [PATCH 08/11] chore(Routing): Use `storages` as module namespace to reflect nested resourcing --- .../admin/oauth_access_grant_nudge_modal_component.rb | 6 +++--- .../{projects => storages}/project_storages_controller.rb | 2 +- .../{projects => storages}/project_storages/index.html.erb | 0 modules/storages/config/routes.rb | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename modules/storages/app/controllers/storages/admin/{projects => storages}/project_storages_controller.rb (96%) rename modules/storages/app/views/storages/admin/{projects => storages}/project_storages/index.html.erb (100%) diff --git a/modules/storages/app/components/storages/admin/oauth_access_grant_nudge_modal_component.rb b/modules/storages/app/components/storages/admin/oauth_access_grant_nudge_modal_component.rb index a10707c3ff9c..85f964b48294 100644 --- a/modules/storages/app/components/storages/admin/oauth_access_grant_nudge_modal_component.rb +++ b/modules/storages/app/components/storages/admin/oauth_access_grant_nudge_modal_component.rb @@ -75,7 +75,7 @@ def body_text if authorized success_title = I18n.t("storages.oauth_grant_nudge_modal.access_granted") success_subtitle = I18n.t("storages.oauth_grant_nudge_modal.storage_ready", storage: project_storage.storage.name) - concat(render(Storages::OpenProjectStorageModalComponent::Body.new(:success, success_subtitle:, success_title:))) + concat(render(::Storages::OpenProjectStorageModalComponent::Body.new(:success, success_subtitle:, success_title:))) else I18n.t("storages.oauth_grant_nudge_modal.body", storage: project_storage.storage.name) end @@ -94,9 +94,9 @@ def confirm_button_url def find_project_storage(project_storage_record_or_id) return if project_storage_record_or_id.blank? - return project_storage_record_or_id if project_storage_record_or_id.is_a?(Storages::ProjectStorage) + return project_storage_record_or_id if project_storage_record_or_id.is_a?(::Storages::ProjectStorage) - Storages::ProjectStorage.find_by(id: project_storage_record_or_id) + ::Storages::ProjectStorage.find_by(id: project_storage_record_or_id) end end end diff --git a/modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb b/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb similarity index 96% rename from modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb rename to modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb index 467f4fda7549..7ca37caec7ce 100644 --- a/modules/storages/app/controllers/storages/admin/projects/project_storages_controller.rb +++ b/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb @@ -28,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class Storages::Admin::Projects::ProjectStoragesController < ApplicationController +class Storages::Admin::Storages::ProjectStoragesController < ApplicationController include OpTurbo::ComponentStream layout "admin" diff --git a/modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb b/modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb similarity index 100% rename from modules/storages/app/views/storages/admin/projects/project_storages/index.html.erb rename to modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb diff --git a/modules/storages/config/routes.rb b/modules/storages/config/routes.rb index 774f79d50547..963f9eb14820 100644 --- a/modules/storages/config/routes.rb +++ b/modules/storages/config/routes.rb @@ -44,9 +44,9 @@ resource :access_management, controller: "/storages/admin/access_management", only: %i[new create edit update] - scope module: :projects do + scope module: :storages do resources :project_storages, - controller: "/storages/admin/projects/project_storages", + controller: "/storages/admin/storages/project_storages", only: %i[index new create destroy] end From 9965dc256f76bbb12ea3d02b3e36f1a71d3f6510 Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Thu, 4 Jul 2024 12:55:19 +0300 Subject: [PATCH 09/11] chore: use absolute namespacing --- .../storages/admin/oauth_application_info_copy_component.rb | 4 ++-- .../app/forms/storages/admin/provider_drive_id_input_form.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/storages/app/components/storages/admin/oauth_application_info_copy_component.rb b/modules/storages/app/components/storages/admin/oauth_application_info_copy_component.rb index 4454551711af..c80bef345ac7 100644 --- a/modules/storages/app/components/storages/admin/oauth_application_info_copy_component.rb +++ b/modules/storages/app/components/storages/admin/oauth_application_info_copy_component.rb @@ -46,8 +46,8 @@ def self.wrapper_key = :storage_openproject_oauth_section def oauth_application_details_link render( Primer::Beta::Link.new( - href: Storages::Peripherals::StorageInteraction::Nextcloud::Util.join_uri_path(storage.host, - "settings/admin/openproject"), + href: ::Storages::Peripherals::StorageInteraction::Nextcloud::Util.join_uri_path(storage.host, + "settings/admin/openproject"), target: "_blank" ) ) { I18n.t("storages.instructions.oauth_application_details_link_text") } diff --git a/modules/storages/app/forms/storages/admin/provider_drive_id_input_form.rb b/modules/storages/app/forms/storages/admin/provider_drive_id_input_form.rb index 8ead4f90e7d3..614ae7b42cf9 100644 --- a/modules/storages/app/forms/storages/admin/provider_drive_id_input_form.rb +++ b/modules/storages/app/forms/storages/admin/provider_drive_id_input_form.rb @@ -31,7 +31,7 @@ class ProviderDriveIdInputForm < ApplicationForm form do |storage_form| storage_form.text_field( name: :drive_id, - label: Storages::Admin::LABEL_DRIVE_ID, + label: ::Storages::Admin::LABEL_DRIVE_ID, visually_hide_label: false, required: true, caption: caption.html_safe, # rubocop:disable Rails/OutputSafety From 84160c6c5f4c09791e506d27b3f92442f9ec105d Mon Sep 17 00:00:00 2001 From: Kabiru Mwenja Date: Thu, 4 Jul 2024 12:58:55 +0300 Subject: [PATCH 10/11] convert "Add Projects" translation to reusable label --- .../new_project_mapping_component.rb | 2 +- .../new_project_mapping_form_component.rb | 2 +- .../settings/project_custom_fields/project_mappings.html.erb | 2 +- config/locales/en.yml | 2 +- .../storages/admin/storages/project_storages/index.html.erb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb index 784dc0b8ec99..6d721c4f0b67 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.rb @@ -45,7 +45,7 @@ def render? private def title - I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") + I18n.t(:label_add_projects) end end end diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_form_component.rb b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_form_component.rb index 1693de4871fd..7a9123f455cb 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_form_component.rb +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_form_component.rb @@ -44,7 +44,7 @@ def initialize(project_mapping:, project_custom_field:) private def title - I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") + I18n.t(:label_add_projects) end def cancel_button_text diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index ed01914788ca..66e463fa57d7 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -44,7 +44,7 @@ See COPYRIGHT and LICENSE files for more details. data: { controller: "async-dialog" } )) do |button| button.with_leading_visual_icon(icon: 'op-include-projects') - I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects") + I18n.t(:label_add_projects) end end end unless @custom_field.required? diff --git a/config/locales/en.yml b/config/locales/en.yml index 2032e684fab8..27e866ef13b7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -336,7 +336,6 @@ Project attributes and sections are defined in the Date: Thu, 4 Jul 2024 13:32:35 +0300 Subject: [PATCH 11/11] chore: remove show action --- .../storages/admin/storages/project_storages_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb b/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb index 7ca37caec7ce..c666d129a808 100644 --- a/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb +++ b/modules/storages/app/controllers/storages/admin/storages/project_storages_controller.rb @@ -43,7 +43,6 @@ class Storages::Admin::Storages::ProjectStoragesController < ApplicationControll def index; end def new; end def create; end - def show; end def destroy; end private