From a2caedcdb70392132b7f505dd9ebd2df135c4c23 Mon Sep 17 00:00:00 2001 From: ulferts Date: Wed, 6 Apr 2022 16:07:28 +0200 Subject: [PATCH] allows selecting items to copy from a template project --- .../copy-project/copy-project.component.ts | 2 +- .../new-project/new-project.component.ts | 12 ++++++-- spec/features/projects/template_spec.rb | 28 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/features/projects/components/copy-project/copy-project.component.ts b/frontend/src/app/features/projects/components/copy-project/copy-project.component.ts index c53ce0aed6..dc36d1ecd4 100644 --- a/frontend/src/app/features/projects/components/copy-project/copy-project.component.ts +++ b/frontend/src/app/features/projects/components/copy-project/copy-project.component.ts @@ -84,6 +84,6 @@ export class CopyProjectComponent extends UntilDestroyedMixin implements OnInit } private isMeta(property:string|undefined):boolean { - return !!property && (property.startsWith('copy') || property == 'sendNotifications'); + return !!property && (property.startsWith('copy') || property === 'sendNotifications'); } } diff --git a/frontend/src/app/features/projects/components/new-project/new-project.component.ts b/frontend/src/app/features/projects/components/new-project/new-project.component.ts index 4c7e2a7617..c59618750b 100644 --- a/frontend/src/app/features/projects/components/new-project/new-project.component.ts +++ b/frontend/src/app/features/projects/components/new-project/new-project.component.ts @@ -39,6 +39,7 @@ export class NewProjectComponent extends UntilDestroyedMixin implements OnInit { use_template: this.I18n.t('js.project.use_template'), no_template_selected: this.I18n.t('js.project.no_template_selected'), advancedSettingsLabel: this.I18n.t('js.forms.advanced_settings'), + copySettingsLabel: this.I18n.t('js.project.copy.copy_options'), }; hiddenFields:string[] = [ @@ -88,10 +89,15 @@ export class NewProjectComponent extends UntilDestroyedMixin implements OnInit { this.resourcePath = this.apiV3Service.projects.path; this.fieldGroups = [{ name: this.text.advancedSettingsLabel, - fieldsFilter: (field) => !['name', 'parent', 'sendNotifications'].includes(field.templateOptions?.property as string) + fieldsFilter: (field) => !['name', 'parent'].includes(field.templateOptions?.property as string) + && !this.isMeta(field.templateOptions?.property) && !(field.templateOptions?.required && !field.templateOptions.hasDefault && field.templateOptions.payloadValue == null), + }, + { + name: this.text.copySettingsLabel, + fieldsFilter: (field:IOPFormlyFieldSettings) => this.isMeta(field.templateOptions?.property), }]; if (this.uIRouterGlobals.params.parent_id) { @@ -128,8 +134,8 @@ export class NewProjectComponent extends UntilDestroyedMixin implements OnInit { return !!key && (this.hiddenFields.includes(key) || this.isMeta(key)); } - private isMeta(key:string):boolean { - return key.startsWith('_meta.'); + private isMeta(property:string|undefined):boolean { + return !!property && (property.startsWith('copy') || property === 'sendNotifications'); } private setParentAsPayload(parentId:string) { diff --git a/spec/features/projects/template_spec.rb b/spec/features/projects/template_spec.rb index 214a6b311a..5bbc1b427e 100644 --- a/spec/features/projects/template_spec.rb +++ b/spec/features/projects/template_spec.rb @@ -72,6 +72,10 @@ describe 'Project templates', type: :feature, js: true do let(:status_field_selector) { 'ckeditor-augmented-textarea[textarea-selector="#project_status_explanation"]' } let(:status_description) { ::Components::WysiwygEditor.new status_field_selector } + let!(:other_user) do + create(:user, member_in_project: template, member_through_role: role) + end + let(:name_field) { ::FormFields::InputFormField.new :name } let(:template_field) { ::FormFields::SelectFormField.new :use_template } let(:status_field) { ::FormFields::SelectFormField.new :status } @@ -86,9 +90,15 @@ describe 'Project templates', type: :feature, js: true do name_field.set_value 'Foo bar' + expect(page) + .not_to have_content('COPY OPTIONS') + template_field.select_option 'My template' - sleep 1 + # Only when a template is selected, the options are displayed. + # Using this to know when the copy form has been fetched from the backend. + expect(page) + .to have_content('COPY OPTIONS') # It keeps the name name_field.expect_value 'Foo bar' @@ -98,16 +108,19 @@ describe 'Project templates', type: :feature, js: true do page.find('.op-fieldset--toggle', text: 'ADVANCED SETTINGS').click status_field.expect_selected 'ON TRACK' - # It does not show the copy meta flags - expect(page).to have_no_selector('[data-qa-field-name="copyMembers"]') - - # But shows the send notifications field - expect(page).to have_selector('[data-qa-field-name="sendNotifications"]') # Update status to off track status_field.select_option 'Off track' parent_field.select_option other_project.name + page.find('.op-fieldset--toggle', text: 'COPY OPTIONS').click + + # Now shows the send notifications field. + expect(page).to have_selector('[data-qa-field-name="sendNotifications"]') + + # And allows to deselect copying the members. + uncheck 'Members' + page.find('button:not([disabled])', text: 'Save').click expect(page).to have_content I18n.t(:label_copy_project) @@ -127,7 +140,8 @@ describe 'Project templates', type: :feature, js: true do project = Project.find_by identifier: 'foo-bar' expect(project.name).to eq 'Foo bar' expect(project).not_to be_templated - expect(project.users.first).to eq current_user + # Does not include the member excluded from being copied but sets the copying user as member. + expect(project.users).to match_array(current_user) expect(project.enabled_module_names.sort).to eq(template.enabled_module_names.sort) wp_source = template.work_packages.first.attributes.except(*%w[id author_id project_id updated_at created_at])