Merge pull request #8278 from opf/fix/33072/allow-assign-to-group

Correctly load groups trough hrefs
pull/8279/head
Oliver Günther 5 years ago committed by GitHub
commit 036644d50a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      frontend/src/app/modules/boards/board/board-actions/assignee/assignee-action.service.ts
  2. 33
      frontend/src/app/modules/hal/resources/group-resource.ts
  3. 5
      frontend/src/app/modules/hal/services/hal-resource.config.ts
  4. 35
      modules/boards/spec/features/action_boards/assignee_board_spec.rb
  5. 5
      modules/boards/spec/features/support/board_index_page.rb

@ -8,19 +8,21 @@ import {I18nService} from "core-app/modules/common/i18n/i18n.service";
import {FilterOperator} from "core-components/api/api-v3/api-v3-filter-builder";
import {CreateAutocompleterComponent} from "core-app/modules/common/autocomplete/create-autocompleter.component";
import {OpContextMenuItem} from "core-components/op-context-menu/op-context-menu.types";
import {UserCacheService} from 'core-app/components/user/user-cache.service';
import {UserResource} from 'core-app/modules/hal/resources/user-resource';
import {CurrentProjectService} from 'core-app/components/projects/current-project.service';
import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource';
import {HalResourceService} from 'core-app/modules/hal/services/hal-resource.service';
import {AssigneeBoardHeaderComponent} from "core-app/modules/boards/board/board-actions/assignee/assignee-board-header.component";
import {input} from "reactivestates";
import {take} from "rxjs/operators";
@Injectable()
export class BoardAssigneeActionService implements BoardActionService {
private assignees = input<HalResource[]>();
constructor(protected boardListsService:BoardListsService,
protected I18n:I18nService,
protected userCache:UserCacheService,
protected halResourceService:HalResourceService,
protected currentProject:CurrentProjectService
) {
@ -49,15 +51,16 @@ export class BoardAssigneeActionService implements BoardActionService {
* Returns the loaded assignee
* @param query
*/
public getLoadedFilterValue(query:QueryResource):Promise<undefined|UserResource> {
public getLoadedFilterValue(query:QueryResource):Promise<undefined|HalResource> {
const href = this.getFilterHref(query);
if (href) {
const id = HalResource.idFromLink(href);
return this.userCache.require(id);
} else {
if (!href) {
return Promise.resolve(undefined);
}
return this
.getAssignees()
.then(collection => collection.find(resource => resource.href === href));
}
public canAddToQuery(query:QueryResource):Promise<boolean> {
@ -95,7 +98,8 @@ export class BoardAssigneeActionService implements BoardActionService {
queries.map(query => this.getFilterHref(query))
);
return this.getAssignees(board)
return this
.getAssignees()
.then(results =>
results.filter(assignee => !active.has(assignee.href!))
);
@ -117,17 +121,23 @@ export class BoardAssigneeActionService implements BoardActionService {
return AssigneeBoardHeaderComponent;
}
public disabledAddButtonPlaceholder(assignee:UserResource) {
public disabledAddButtonPlaceholder(assignee:HalResource) {
return undefined;
}
private getAssignees(board:Board):Promise<UserResource[]> {
private getAssignees():Promise<HalResource[]> {
const projectIdentifier = this.currentProject.identifier!;
let myData = this.halResourceService.get('/api/v3/projects/' + projectIdentifier + '/available_assignees').toPromise();
this.assignees.putFromPromiseIfPristine(() =>
this.halResourceService
.get('/api/v3/projects/' + projectIdentifier + '/available_assignees')
.toPromise()
.then((collection:CollectionResource<UserResource>) => collection.elements)
);
return myData
.then((collection:CollectionResource<UserResource>) => collection.elements);
return this.assignees
.values$()
.pipe(take(1))
.toPromise();
}
}

@ -0,0 +1,33 @@
//-- copyright
// OpenProject is an open source project management software.
// Copyright (C) 2012-2020 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 docs/COPYRIGHT.rdoc for more details.
//++
import {HalResource} from 'core-app/modules/hal/resources/hal-resource';
export class GroupResource extends HalResource {
public name:string;
}

@ -48,7 +48,6 @@ import {
HalResourceFactoryConfigInterface,
HalResourceService
} from 'core-app/modules/hal/services/hal-resource.service';
import {Injectable} from '@angular/core';
import {HalResource} from 'core-app/modules/hal/resources/hal-resource';
import {WikiPageResource} from "core-app/modules/hal/resources/wiki-page-resource";
import {MeetingContentResource} from "core-app/modules/hal/resources/meeting-content-resource";
@ -63,6 +62,7 @@ import {VersionResource} from "core-app/modules/hal/resources/version-resource";
import {MembershipResource} from "core-app/modules/hal/resources/membership-resource";
import {RoleResource} from "core-app/modules/hal/resources/role-resource";
import {ProjectResource} from "core-app/modules/hal/resources/project-resource";
import {GroupResource} from "core-app/modules/hal/resources/group-resource";
const halResourceDefaultConfig:{ [typeName:string]:HalResourceFactoryConfigInterface } = {
WorkPackage: {
@ -120,6 +120,9 @@ const halResourceDefaultConfig:{ [typeName:string]:HalResourceFactoryConfigInter
User: {
cls: UserResource
},
Group: {
cls: GroupResource
},
Collection: {
cls: CollectionResource
},

@ -32,7 +32,6 @@ require_relative './../support/board_page'
describe 'Assignee action board',
type: :feature,
driver: :firefox_headless_en,
js: true do
let(:bobself_user) do
FactoryBot.create(:user,
@ -65,6 +64,15 @@ describe 'Assignee action board',
member_through_role: role)
end
let!(:group) do
FactoryBot.create(:group, groupname: 'Grouped').tap do |group|
FactoryBot.create(:member,
principal: group,
project: project,
roles: [role])
end
end
let!(:work_package) { FactoryBot.create :work_package,
project: project,
assigned_to: bobself_user,
@ -93,22 +101,31 @@ describe 'Assignee action board',
board_page.add_list option: 'Foo Bar'
board_page.expect_list 'Foo Bar'
# Add grouped list
board_page.add_list option: 'Grouped'
board_page.expect_list 'Grouped'
board_page.board(reload: true) do |board|
expect(board.name).to eq 'Action board (assignee)'
queries = board.contained_queries
expect(queries.count).to eq(2)
expect(queries.count).to eq(3)
bob = queries.first
foo = queries.last
foo = queries.second
grouped = queries.last
expect(bob.name).to eq 'Bob Self'
expect(foo.name).to eq 'Foo Bar'
expect(grouped.name).to eq 'Grouped'
expect(bob.filters.first.name).to eq :assigned_to_id
expect(bob.filters.first.values).to eq [bobself_user.id.to_s]
expect(foo.filters.first.name).to eq :assigned_to_id
expect(foo.filters.first.values).to eq [foobar_user.id.to_s]
expect(grouped.filters.first.name).to eq :assigned_to_id
expect(grouped.filters.first.values).to eq [group.id.to_s]
end
# First, expect work package to be assigned to "Bob self"
@ -128,5 +145,17 @@ describe 'Assignee action board',
work_package.reload
expect(work_package.assigned_to).to eq(foobar_user)
# Move to group column
board_page.move_card(0, from: 'Foo Bar', to: 'Grouped')
board_page.expect_card 'Grouped', 'Some Task'
board_page.expect_card 'Foo Bar', 'Some Task', present: false
board_page.expect_card 'Bob Self', 'Some Task', present: false
# Expect to have changed the avatar
expect(page).to have_selector('.wp-card--assignee .avatar-default', text: 'GG', wait: 10)
work_package.reload
expect(work_package.assigned_to).to eq(group)
end
end

@ -66,7 +66,10 @@ module Pages
find('.button', text: 'Action board').click
end
unless expect_empty
if expect_empty
expect(page).to have_selector('.boards-list--add-item-text', wait: 10)
expect(page).to have_no_selector('.boards-list--item')
else
expect(page).to have_selector('.boards-list--item', wait: 10)
end

Loading…
Cancel
Save