From 01dfe0cff39384ad19d6a7f7dea8d544cca90fe7 Mon Sep 17 00:00:00 2001 From: Pavel Balashou Date: Tue, 19 Mar 2024 16:22:05 +0100 Subject: [PATCH] [#53394] OAuth flow causes loss of already selected option while adding a storage to a project https://community.openproject.org/work_packages/53394 --- .../project-storage-form.controller.ts | 9 ++++- .../admin/project_storages_controller.rb | 34 +++++++++---------- .../set_attributes_service.rb | 8 ++--- .../features/manage_project_storage_spec.rb | 6 ++-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/frontend/src/stimulus/controllers/dynamic/project-storage-form.controller.ts b/frontend/src/stimulus/controllers/dynamic/project-storage-form.controller.ts index 09cde52c2dec..f2b7bb0c8b3e 100644 --- a/frontend/src/stimulus/controllers/dynamic/project-storage-form.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/project-storage-form.controller.ts @@ -111,6 +111,7 @@ export default class ProjectStorageFormController extends Controller { } this.toggleFolderDisplay(this.folderModeValue); + this.setProjectFolderModeQueryParam(this.folderModeValue); }); } @@ -158,8 +159,8 @@ export default class ProjectStorageFormController extends Controller { } this.folderModeValue = mode; - this.toggleFolderDisplay(mode); + this.setProjectFolderModeQueryParam(mode); } private get modalService():Observable { @@ -208,6 +209,12 @@ export default class ProjectStorageFormController extends Controller { ); } + private setProjectFolderModeQueryParam(mode:string) { + const url = new URL(window.location.href); + url.searchParams.set('storages_project_storage[project_folder_mode]', mode); + window.history.replaceState(window.history.state, '', url); + } + private toggleFolderDisplay(value:string):void { // If the manual radio button is selected, show the manual folder selection section if (this.hasProjectFolderSectionTarget && value === 'manual') { diff --git a/modules/storages/app/controllers/storages/admin/project_storages_controller.rb b/modules/storages/app/controllers/storages/admin/project_storages_controller.rb index ebab6e43cfac..60dbbfe08419 100644 --- a/modules/storages/app/controllers/storages/admin/project_storages_controller.rb +++ b/modules/storages/app/controllers/storages/admin/project_storages_controller.rb @@ -55,25 +55,25 @@ def index @project_storages = Storages::ProjectStorage.where(project: @project).includes(:storage) # Render the list storages using ViewComponents in the /app/components folder which defines # the ways rows are rendered in a table layout. - render '/storages/project_settings/index' + render "/storages/project_settings/index" end # Show a HTML page with a form in order to create a new ProjectStorage # Called by: When a user clicks on the "+New" button in Project -> Settings -> File Storages def new @available_storages = available_storages - @project_storage = ::Storages::ProjectStorages::SetAttributesService - .new(user: current_user, - model: Storages::ProjectStorage.new, - contract_class: EmptyContract) - .call(project: @project, - storage: @available_storages.find do |storage| - storage.id.to_s == params.dig(:storages_project_storage, :storage_id) - end) - .result + project_folder_mode = Storages::ProjectStorage.project_folder_modes.values.find do |mode| + mode == params.dig(:storages_project_storage, :project_folder_mode) + end + storage = @available_storages.find { |s| s.id.to_s == params.dig(:storages_project_storage, :storage_id) } + @project_storage = + ::Storages::ProjectStorages::SetAttributesService + .new(user: current_user, model: Storages::ProjectStorage.new, contract_class: EmptyContract) + .call(project: @project, storage:, project_folder_mode:) + .result @last_project_folders = {} - render template: '/storages/project_settings/new' + render template: "/storages/project_settings/new" end # Create a new ProjectStorage object. @@ -89,7 +89,7 @@ def create redirect_to_project_storages_path_with_oauth_access_grant_confirmation else @available_storages = available_storages - render '/storages/project_settings/new' + render "/storages/project_settings/new" end end @@ -128,7 +128,7 @@ def edit .pluck(:mode, :origin_folder_id) .to_h - render '/storages/project_settings/edit' + render "/storages/project_settings/edit" end # Update is similar to create above @@ -145,7 +145,7 @@ def update redirect_to project_settings_project_storages_path else @project_storage = @object - render '/storages/project_settings/edit' + render "/storages/project_settings/edit" end end @@ -167,7 +167,7 @@ def destroy def destroy_info @project_storage_to_destroy = @object - render '/storages/project_settings/destroy_info' + render "/storages/project_settings/destroy_info" end private @@ -178,7 +178,7 @@ def permitted_storage_settings_params # "params" is an instance of ActionController::Parameters params .require(:storages_project_storage) - .permit('storage_id', 'project_folder_mode', 'project_folder_id') + .permit("storage_id", "project_folder_mode", "project_folder_id") .to_h .reverse_merge(project_id: @project.id) end @@ -212,7 +212,7 @@ def redirect_to_project_storages_path_with_nudge_modal def oauth_access_grant_nudge_modal(authorized: false) { - type: 'Storages::Admin::OAuthAccessGrantNudgeModalComponent', + type: "Storages::Admin::OAuthAccessGrantNudgeModalComponent", parameters: { project_storage: @project_storage.id, authorized: diff --git a/modules/storages/app/services/storages/project_storages/set_attributes_service.rb b/modules/storages/app/services/storages/project_storages/set_attributes_service.rb index 4abf33871cc6..fd814e1115dd 100644 --- a/modules/storages/app/services/storages/project_storages/set_attributes_service.rb +++ b/modules/storages/app/services/storages/project_storages/set_attributes_service.rb @@ -26,17 +26,17 @@ # See COPYRIGHT and LICENSE files for more details. #++ -# Used by: CreateService when setting attributes module Storages::ProjectStorages class SetAttributesService < ::BaseServices::SetAttributes - def set_default_attributes(_params) + def set_default_attributes(params) project_storage = model storage = project_storage.storage project_storage.creator ||= user - project_storage.project_folder_mode ||= - if storage.present? && storage.automatic_management_enabled? + if params[:project_folder_mode].present? + params[:project_folder_mode] + elsif storage.present? && storage.automatic_management_enabled? "automatic" else "inactive" diff --git a/modules/storages/spec/features/manage_project_storage_spec.rb b/modules/storages/spec/features/manage_project_storage_spec.rb index f022db3f0f53..3d4ed0a8eef9 100644 --- a/modules/storages/spec/features/manage_project_storage_spec.rb +++ b/modules/storages/spec/features/manage_project_storage_spec.rb @@ -151,7 +151,8 @@ # Press Edit icon to change the project folder mode to inactive page.find('.icon.icon-edit').click expect(page).to have_current_path edit_project_settings_project_storage_path(project_id: project, - id: Storages::ProjectStorage.last) + id: Storages::ProjectStorage.last, + storages_project_storage: {project_folder_mode: 'manual'}) expect(page).to have_text('Edit the file storage to this project') expect(page).to have_no_select('storages_project_storage_storage_id') expect(page).to have_text(storage.name) @@ -170,7 +171,8 @@ # Click Edit icon again but cancel the edit page.find('.icon.icon-edit').click expect(page).to have_current_path edit_project_settings_project_storage_path(project_id: project, - id: Storages::ProjectStorage.last) + id: Storages::ProjectStorage.last, + storages_project_storage: {project_folder_mode: 'inactive'}) expect(page).to have_text('Edit the file storage to this project') page.click_link('Cancel') expect(page).to have_current_path project_settings_project_storages_path(project)