diff --git a/frontend/src/app/components/user/current-user.service.ts b/frontend/src/app/components/user/current-user.service.ts index 390bdf0c80..1d281208a9 100644 --- a/frontend/src/app/components/user/current-user.service.ts +++ b/frontend/src/app/components/user/current-user.service.ts @@ -33,4 +33,8 @@ export class CurrentUserService { public get isLoggedIn() { return jQuery('meta[name=current_user]').length; } + + public get userId() { + return jQuery('meta[name=current_user]').data('id'); + } } diff --git a/frontend/src/app/components/wp-edit-form/work-package-filter-values.ts b/frontend/src/app/components/wp-edit-form/work-package-filter-values.ts index f8ff15c2c1..7d524446d0 100644 --- a/frontend/src/app/components/wp-edit-form/work-package-filter-values.ts +++ b/frontend/src/app/components/wp-edit-form/work-package-filter-values.ts @@ -3,11 +3,12 @@ import {CollectionResource} from 'core-app/modules/hal/resources/collection-reso import {FormResource} from 'core-app/modules/hal/resources/form-resource'; import {WorkPackageChangeset} from './work-package-changeset'; import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; -import {all} from "@uirouter/core"; +import {CurrentUserService} from "core-components/user/current-user.service"; export class WorkPackageFilterValues { - constructor(private changeset:WorkPackageChangeset, + constructor(private currentUser:CurrentUserService, + private changeset:WorkPackageChangeset, private filters:QueryFilterInstanceResource[], private excluded:string[] = []) { @@ -63,6 +64,10 @@ export class WorkPackageFilterValues { return value; } + if (value instanceof HalResource && value.$href === '/api/v3/users/me' && this.currentUser.isLoggedIn) { + return value.$copy({ href: `/api/v3/users/${this.currentUser.userId}` }); + } + return undefined; } diff --git a/frontend/src/app/components/wp-inline-create/wp-inline-create.component.ts b/frontend/src/app/components/wp-inline-create/wp-inline-create.component.ts index c5bd6f5b3c..bd35dcf18a 100644 --- a/frontend/src/app/components/wp-inline-create/wp-inline-create.component.ts +++ b/frontend/src/app/components/wp-inline-create/wp-inline-create.component.ts @@ -63,6 +63,7 @@ import {I18nService} from 'core-app/modules/common/i18n/i18n.service'; import {FocusHelperService} from 'core-app/modules/common/focus/focus-helper'; import {IWorkPackageEditingServiceToken} from "../wp-edit-form/work-package-editing.service.interface"; import {IWorkPackageCreateServiceToken} from "core-components/wp-new/wp-create.service.interface"; +import {CurrentUserService} from "core-components/user/current-user.service"; @Component({ selector: '[wpInlineCreate]', @@ -99,6 +100,7 @@ export class WorkPackageInlineCreateComponent implements OnInit, OnChanges, OnDe readonly I18n:I18nService, readonly tableState:TableState, readonly wpCacheService:WorkPackageCacheService, + readonly currentUser:CurrentUserService, @Inject(IWorkPackageEditingServiceToken) protected wpEditing:WorkPackageEditingService, @Inject(IWorkPackageCreateServiceToken) protected wpCreate:WorkPackageCreateService, readonly wpTableColumns:WorkPackageTableColumnsService, @@ -188,7 +190,7 @@ export class WorkPackageInlineCreateComponent implements OnInit, OnChanges, OnDe const wp = this.currentWorkPackage = changeset.workPackage; // Apply filter values - const filter = new WorkPackageFilterValues(changeset, this.tableState.query.value!.filters); + const filter = new WorkPackageFilterValues(this.currentUser, changeset, this.tableState.query.value!.filters); filter.applyDefaultsFromFilters().then(() => { this.wpEditing.updateValue('new', changeset); this.wpCacheService.updateWorkPackage(this.currentWorkPackage!); diff --git a/frontend/src/app/components/wp-new/wp-create.controller.ts b/frontend/src/app/components/wp-new/wp-create.controller.ts index 539e37b199..abbed46867 100644 --- a/frontend/src/app/components/wp-new/wp-create.controller.ts +++ b/frontend/src/app/components/wp-new/wp-create.controller.ts @@ -48,6 +48,7 @@ import { IWorkPackageEditingServiceToken } from "../wp-edit-form/work-package-editing.service.interface"; import {IWorkPackageCreateServiceToken} from "core-components/wp-new/wp-create.service.interface"; +import {CurrentUserService} from "core-app/components/user/current-user.service"; @Injectable() @@ -68,6 +69,7 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { readonly I18n:I18nService, readonly titleService:OpTitleService, readonly injector:Injector, + readonly currentUser:CurrentUserService, protected wpNotificationsService:WorkPackageNotificationService, protected states:States, @Inject(IWorkPackageCreateServiceToken) protected wpCreate:WorkPackageCreateService, @@ -153,7 +155,7 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { } return this.wpCreate.createNewTypedWorkPackage(stateParams.projectPath, type).then(changeset => { - const filter = new WorkPackageFilterValues(changeset, this.wpTableFilters.current, ['type']); + const filter = new WorkPackageFilterValues(this.currentUser, changeset, this.wpTableFilters.current, ['type']); return filter.applyDefaultsFromFilters().then(() => changeset); }); } diff --git a/frontend/src/app/modules/hal/resources/hal-resource.ts b/frontend/src/app/modules/hal/resources/hal-resource.ts index 36dc11b9f3..b819940303 100644 --- a/frontend/src/app/modules/hal/resources/hal-resource.ts +++ b/frontend/src/app/modules/hal/resources/hal-resource.ts @@ -112,10 +112,10 @@ export class HalResource { * @param {HalResource} other * @returns A HalResource with the identitical copied source of other. */ - public $copy():T { + public $copy(source:Object = {}):T { let clone:HalResourceClass = this.constructor as any; - return new clone(this.injector, this.$plain(), this.$loaded, this.halInitializer, this.$halType); + return new clone(this.injector, _.merge(this.$plain(), source), this.$loaded, this.halInitializer, this.$halType); } public $plain():any { diff --git a/spec/features/my/assigned_to_me_embedded_table_spec.rb b/spec/features/my/assigned_to_me_embedded_table_spec.rb new file mode 100644 index 0000000000..a49a15239d --- /dev/null +++ b/spec/features/my/assigned_to_me_embedded_table_spec.rb @@ -0,0 +1,84 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +# +# 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-2017 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 docs/COPYRIGHT.rdoc for more details. +#++ + +require 'spec_helper' + +describe 'Assigned to me embedded query on my page', type: :feature, js: true do + let!(:type) { FactoryBot.create :type } + let!(:priority) { FactoryBot.create :default_priority } + let!(:project) { FactoryBot.create :project, types: [type] } + let!(:open_status) { FactoryBot.create :default_status } + + let(:role) { FactoryBot.create(:role, permissions: %i[view_work_packages add_work_packages]) } + + let(:user) do + FactoryBot.create(:user, + member_in_project: project, + member_through_role: role) + end + + before do + login_as user + visit my_page_path + end + + it 'can create a new ticket with correct me values (Regression test #28488)' do + expect(page).to have_selector('.widget-box--header-title', text: 'Work packages assigned to me') + + embedded_table = Pages::EmbeddedWorkPackagesTable.new(find('#left')) + embedded_table.click_inline_create + + subject_field = embedded_table.edit_field(nil, :subject) + subject_field.expect_active! + + subject_field.set_value 'Assigned to me' + subject_field.save! + + + # Set project + project_field = embedded_table.edit_field(nil, :project) + project_field.expect_active! + + project_field.set_value project.name + + # Set type + type_field = embedded_table.edit_field(nil, :type) + type_field.expect_active! + type_field.set_value type.name + + embedded_table.expect_notification( + message: 'Successful creation. Click here to open this work package in fullscreen view.' + ) + + wp = WorkPackage.last + expect(wp.subject).to eq('Assigned to me') + expect(wp.assigned_to_id).to eq(user.id) + + embedded_table.expect_work_package_listed wp + end +end diff --git a/spec/support/pages/embedded_work_packages_table.rb b/spec/support/pages/embedded_work_packages_table.rb index 1c3a0c6a69..74468222af 100644 --- a/spec/support/pages/embedded_work_packages_table.rb +++ b/spec/support/pages/embedded_work_packages_table.rb @@ -31,15 +31,15 @@ require 'support/pages/work_packages_table' module Pages class EmbeddedWorkPackagesTable < WorkPackagesTable - attr_reader :context + attr_reader :container - def initialize(context, project = nil) + def initialize(container, project = nil) super(project) - @context = context + @container = container end def table_container - context.find('.work-package-table') + container.find('.work-package-table') end end end diff --git a/spec/support/pages/work_packages_table.rb b/spec/support/pages/work_packages_table.rb index c99944f672..5d10cc5f45 100644 --- a/spec/support/pages/work_packages_table.rb +++ b/spec/support/pages/work_packages_table.rb @@ -112,8 +112,8 @@ module Pages # there is a delay on travis where inline create can be clicked. sleep 3 - find('.wp-inline-create--add-link').click - expect(page).to have_selector('.wp-inline-create-row', wait: 10) + container.find('.wp-inline-create--add-link').click + expect(container).to have_selector('.wp-inline-create-row', wait: 10) end def create_wp_split_screen(type) @@ -229,6 +229,12 @@ module Pages ".wp-row-#{work_package.id}" end + protected + + def container + page + end + private def path