diff --git a/frontend/src/app/shared/components/datepicker/datepicker.modal.service.ts b/frontend/src/app/shared/components/datepicker/datepicker.modal.service.ts index 6162d796d9..0d0b3aef93 100644 --- a/frontend/src/app/shared/components/datepicker/datepicker.modal.service.ts +++ b/frontend/src/app/shared/components/datepicker/datepicker.modal.service.ts @@ -39,15 +39,20 @@ import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { ApiV3Filter } from 'core-app/shared/helpers/api-v3/api-v3-filter-builder'; import { WorkPackageChangeset } from 'core-app/features/work-packages/components/wp-edit/work-package-changeset'; import { + defaultIfEmpty, + filter, map, shareReplay, + switchMap, } from 'rxjs/operators'; import { combineLatest, Observable, + of, } from 'rxjs'; import { HalResource } from 'core-app/features/hal/resources/hal-resource'; import { IHALCollection } from 'core-app/core/apiv3/types/hal-collection.type'; +import isNewResource from 'core-app/features/hal/helpers/is-new-resource'; @Injectable() export class DatepickerModalService { @@ -55,31 +60,37 @@ export class DatepickerModalService { private changeset:WorkPackageChangeset = this.locals.changeset as WorkPackageChangeset; - precedingWorkPackages$:Observable<{ id:string, dueDate?:string, date?:string }[]> = this - .apiV3Service - .work_packages - .signalled( - ApiV3Filter('precedes', '=', [this.changeset.id]), - [ - 'elements/id', - 'elements/dueDate', - 'elements/date', - ], - ) + precedingWorkPackages$:Observable<{ id:string, dueDate?:string, date?:string }[]> = of(this.changeset) .pipe( + filter((changeset) => !isNewResource(changeset.pristineResource)), + switchMap((changeset) => this + .apiV3Service + .work_packages + .signalled( + ApiV3Filter('precedes', '=', [changeset.id]), + [ + 'elements/id', + 'elements/dueDate', + 'elements/date', + ], + )), map((collection:IHALCollection<{ id:string }>) => collection._embedded.elements || []), + defaultIfEmpty([]), shareReplay(1), ); - followingWorkPackages$:Observable<{ id:string }[]> = this - .apiV3Service - .work_packages - .signalled( - ApiV3Filter('follows', '=', [this.changeset.id]), - ['elements/id'], - ) + followingWorkPackages$:Observable<{ id:string }[]> = of(this.changeset) .pipe( + filter((changeset) => !isNewResource(changeset.pristineResource)), + switchMap((changeset) => this + .apiV3Service + .work_packages + .signalled( + ApiV3Filter('follows', '=', [changeset.id]), + ['elements/id'], + )), map((collection:IHALCollection<{ id:string }>) => collection._embedded.elements || []), + defaultIfEmpty([]), shareReplay(1), ); diff --git a/spec/features/work_packages/new/new_work_package_datepicker_spec.rb b/spec/features/work_packages/new/new_work_package_datepicker_spec.rb new file mode 100644 index 0000000000..a53a79f98f --- /dev/null +++ b/spec/features/work_packages/new/new_work_package_datepicker_spec.rb @@ -0,0 +1,66 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2022 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. +#++ + +require 'spec_helper' +require 'features/page_objects/notification' +require 'features/work_packages/details/inplace_editor/shared_examples' +require 'features/work_packages/shared_contexts' +require 'support/edit_fields/edit_field' +require 'features/work_packages/work_packages_page' + +describe 'New work package datepicker', + with_settings: { date_format: '%Y-%m-%d' }, + js: true, selenium: true do + let(:project) { create :project_with_types, public: true } + let(:user) { create :admin } + + let(:wp_page_create) { Pages::FullWorkPackageCreate.new(project:) } + let(:start_date) { wp_page_create.edit_field(:combinedDate) } + + before do + login_as(user) + + wp_page_create.visit! + end + + it 'can open and select the datepicker' do + start_date.input_element.click + + start = (Time.zone.today - 1.day).iso8601 + start_date.activate_start_date_within_modal + start_date.datepicker.set_date start, true + + due = (Time.zone.today + 1.day).iso8601 + start_date.activate_due_date_within_modal + start_date.datepicker.set_date due, true + + start_date.save! + start_date.expect_inactive! + start_date.expect_value "#{start} - #{due}" + end +end diff --git a/spec/support/edit_fields/date_edit_field.rb b/spec/support/edit_fields/date_edit_field.rb index 0fa9f322f6..720003b72c 100644 --- a/spec/support/edit_fields/date_edit_field.rb +++ b/spec/support/edit_fields/date_edit_field.rb @@ -50,6 +50,12 @@ class DateEditField < EditField end end + def activate_start_date_within_modal + within_modal do + find('[data-qa-selector="op-datepicker-modal--start-date-field"]').click + end + end + def activate_due_date_within_modal within_modal do find('[data-qa-selector="op-datepicker-modal--end-date-field"]').click