From 2e521a49e3bfe9328378bd76db2afa8b9bd1ad3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Fri, 15 Sep 2017 10:42:06 +0200 Subject: [PATCH] [26304] Save inline-create and split view together (#5923) We only have the one `new` work package and changeset, so we can't handle multiple views creating different work packages. [ci skip] --- .../wp-edit-field-group.directive.ts | 27 ++++- .../wp-inline-create.directive.ts | 11 +- .../inline_create/parallel_creation_spec.rb | 109 ++++++++++++++++++ spec/support/pages/work_packages_table.rb | 8 ++ .../work_packages/work_package_field.rb | 2 +- 5 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 spec/features/work_packages/table/inline_create/parallel_creation_spec.rb diff --git a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts index 8b0429f3e5..fa9f64b0ae 100644 --- a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts +++ b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts @@ -37,9 +37,10 @@ import {scopeDestroyed$} from '../../../helpers/angular-rx-utils'; import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageTableSelection} from '../../wp-fast-table/state/wp-table-selection.service'; import {WorkPackageNotificationService} from '../wp-notification.service'; +import {WorkPackageCreateService} from './../../wp-create/wp-create.service'; export class WorkPackageEditFieldGroupController { - public workPackage:WorkPackageResourceInterface + public workPackage:WorkPackageResourceInterface; public successState?:string; public inEditMode:boolean; public form:WorkPackageEditForm; @@ -50,6 +51,7 @@ export class WorkPackageEditFieldGroupController { constructor(protected $scope:ng.IScope, protected $state:ng.ui.IStateService, protected states:States, + protected wpCreate:WorkPackageCreateService, protected wpEditing:WorkPackageEditingService, protected wpNotificationsService:WorkPackageNotificationService, protected wpTableSelection:WorkPackageTableSelection, @@ -76,7 +78,7 @@ export class WorkPackageEditFieldGroupController { this.stop(); } }); - + $scope.$on('$destroy', () => { this.unregisterListener(); this.form.destroy(); @@ -87,6 +89,16 @@ export class WorkPackageEditFieldGroupController { const context = new SingleViewEditContext(this); this.form = WorkPackageEditForm.createInContext(context, this.workPackage, this.inEditMode); + // Stop editing whenever a work package was saved + if (this.inEditMode && this.workPackage.isNew) { + this.wpCreate.onNewWorkPackage() + .takeUntil(scopeDestroyed$(this.$scope)) + .subscribe((wp:WorkPackageResourceInterface) => { + this.form.editMode = false; + this.stopEditingAndLeave(wp, true); + }); + } + this.states.workPackages.get(this.workPackage.id) .values$() .takeUntil(scopeDestroyed$(this.$scope)) @@ -143,7 +155,18 @@ export class WorkPackageEditFieldGroupController { }); } + /** + * Handle onSave from form and single view. Since we get a separate event + * for new work packages, ignore them and only stop editing on non-new WPs. + * + */ public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResourceInterface) { + if (!isInitial) { + this.stopEditingAndLeave(savedWorkPackage, false); + } + } + + private stopEditingAndLeave(savedWorkPackage:WorkPackageResourceInterface, isInitial:boolean) { this.wpEditing.stopEditing(this.workPackage.id); if (this.successState) { diff --git a/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts b/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts index 00b7b6321b..f308baf817 100644 --- a/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts +++ b/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts @@ -90,15 +90,18 @@ export class WorkPackageInlineCreateController { // Remove temporary rows on creation of new work package scopedObservable(this.$scope, this.wpCreate.onNewWorkPackage()) .subscribe((wp:WorkPackageResourceInterface) => { - - if (this.currentWorkPackage === wp) { - // Remove this row and add another - this.table.editing.stopEditing('new'); + if (this.currentWorkPackage && this.currentWorkPackage === wp) { + // Add next row this.removeWorkPackageRow(); this.addWorkPackageRow(); // Focus on the last inserted id this.states.focusedWorkPackage.putValue(wp.id, 'Added in inline create'); + } else { + // Remove current row + this.table.editing.stopEditing('new'); + this.removeWorkPackageRow(); + this.showRow(); } }); diff --git a/spec/features/work_packages/table/inline_create/parallel_creation_spec.rb b/spec/features/work_packages/table/inline_create/parallel_creation_spec.rb new file mode 100644 index 0000000000..7990ed5f76 --- /dev/null +++ b/spec/features/work_packages/table/inline_create/parallel_creation_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper' + +describe 'Parallel work package creation spec', js: true do + let(:type) { FactoryGirl.create(:type) } + let(:types) { [type] } + + let(:permissions) { %i(view_work_packages add_work_packages)} + let(:role) { FactoryGirl.create :role, permissions: permissions } + let(:user) do + FactoryGirl.create :user, + member_in_project: project, + member_through_role: role + end + let(:status) { FactoryGirl.create(:default_status) } + let(:workflow) do + FactoryGirl.create :workflow, + type_id: type.id, + old_status: status, + new_status: FactoryGirl.create(:status), + role: role + end + + let!(:project) { FactoryGirl.create(:project, is_public: true, types: types) } + let!(:priority) { FactoryGirl.create :priority, is_default: true } + let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } + + before do + workflow + login_as user + end + + def new_work_package_in_both(subject, description) + # Enable inline-create + wp_table.click_inline_create + subject_field = wp_table.edit_field(nil, :subject) + subject_field.expect_active! + subject_field.set_value subject + + # Create in split screen + split = wp_table.create_wp_split_screen type.name + description_field = WorkPackageTextAreaField.new split, 'description' + description_field.expect_active! + description_field.set_value description + end + + scenario 'with a new work package in split and inline create, both are saved' do + # Expect table to be empty + wp_table.visit! + wp_table.expect_no_work_package_listed + + # Open split screen and inline create + new_work_package_in_both 'Some subject', 'My description!' + + # Save in inline create + expect(page).to have_selector('.wp-inline-create-row') + expect(page).to have_selector('.wp--row', count: 1) + + subject_field = wp_table.edit_field(nil, :subject) + subject_field.save! + + # Since the WP was started inline, a new row is entered + expect(page).to have_selector('.wp-inline-create-row') + page.find('.wp-table--cancel-create-link').click + expect(page).to have_selector('.wp--row', count: 1) + + wp_table.expect_notification( + message: 'Successful creation. Click here to open this work package in fullscreen view.' + ) + wp_table.dismiss_notification! + + # Get the last work package + wp1 = WorkPackage.last + expect(wp1.subject).to eq 'Some subject' + expect(wp1.description).to eq 'My description!' + + wp_table.expect_work_package_listed wp1 + + # Both are saved + created_split = ::Pages::SplitWorkPackage.new wp1, project + subject_field = created_split.edit_field :subject + subject_field.expect_inactive! + subject_field.expect_state_text 'Some subject' + + # Open split screen and inline create + new_work_package_in_both 'New subject', 'New description' + + # Inline create still open + expect(page).to have_selector('.wp-inline-create-row') + + # Save in split screen + new_split = ::Pages::SplitWorkPackageCreate.new project: project + subject_field = new_split.edit_field :subject + subject_field.expect_active! + subject_field.expect_value 'New subject' + subject_field.save! + + expect(page).to have_selector('.wp-inline-create-row') + expect(page).to have_selector('.wp--row', count: 3) + wp_table.expect_notification( + message: 'Successful creation.' + ) + wp_table.dismiss_notification! + + # Get the last work package + wp2 = WorkPackage.last + expect(wp2.subject).to eq 'New subject' + expect(wp2.description).to eq 'New description' + end +end diff --git a/spec/support/pages/work_packages_table.rb b/spec/support/pages/work_packages_table.rb index ff091314f7..681897f383 100644 --- a/spec/support/pages/work_packages_table.rb +++ b/spec/support/pages/work_packages_table.rb @@ -96,6 +96,14 @@ module Pages expect(page).to have_selector('.wp-inline-create-row') end + def create_wp_split_screen(type) + find('.add-work-package:not([disabled])', text: 'Create').click + + find('#types-context-menu .menu-item', text: type, wait: 10).click + + SplitWorkPackageCreate.new(project: project) + end + def open_split_view(work_package) split_page = SplitWorkPackage.new(work_package, project) diff --git a/spec/support/work_packages/work_package_field.rb b/spec/support/work_packages/work_package_field.rb index 5186b4dbc6..770ffcb229 100644 --- a/spec/support/work_packages/work_package_field.rb +++ b/spec/support/work_packages/work_package_field.rb @@ -78,7 +78,7 @@ class WorkPackageField end def expect_inactive! - expect(page).to have_no_selector("#{@selector} #{field_type}") + expect(field_container).to have_no_selector("#{field_type}") end def expect_invalid