From d0ad4a467902b01309372d73994b1311e3fa9201 Mon Sep 17 00:00:00 2001 From: chvostek Date: Thu, 11 Dec 2025 11:04:05 +0100 Subject: [PATCH 01/10] [NAE-2285] Group as a value of userlists - update tests - switch user/userList field type to actor/actorList type - add attribute fullName to UserValue to render group in the field --- .../user-field/models/user-field.ts | 1 + .../user-field/models/user-value.spec.ts | 2 +- .../user-field/models/user-value.ts | 6 +++-- .../models/user-list-value.spec.ts | 6 ++--- .../user-list-field/models/user-list-value.ts | 3 ++- .../abstract-search-mode.component.spec.ts | 2 +- .../abstract/panel-with-immediate-data.ts | 6 ++--- .../models/category/case/case-dataset.ts | 6 ++--- .../category/case/case-simple-dataset.ts | 6 ++--- .../lib/search/models/datafield-map-key.ts | 4 ++-- .../src/lib/search/models/search-index.ts | 2 +- ...stract-multi-user-assign.component.spec.ts | 6 ++--- ...ct-base-user-assign-list.component.spec.ts | 2 +- ...t-multi-user-assign-list.component.spec.ts | 2 +- ...stract-multi-user-assign-list.component.ts | 4 ++-- ...t-multi-user-assign-item.component.spec.ts | 2 +- ...bstract-user-assign-list.component.spec.ts | 2 +- .../abstract-user-assign-list.component.ts | 2 +- ...bstract-user-assign-item.component.spec.ts | 2 +- .../task-content/model/field-type-resource.ts | 4 ++-- .../services/field-converter.service.spec.ts | 6 ++--- .../services/field-converter.service.ts | 22 +++++++++---------- .../task/services/delegate-task.service.ts | 2 +- .../src/lib/view/abstract/sortable-view.ts | 4 ++-- 24 files changed, 54 insertions(+), 50 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-field.ts b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-field.ts index f479a86118..412e8289af 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-field.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-field.ts @@ -7,6 +7,7 @@ import {Component, ComponentPrefixes} from '../../models/component'; import {Validation} from '../../models/validation'; export class UserField extends DataField { + // todo rebranding to actor-field constructor(stringId: string, title: string, behavior: Behavior, value: UserValue, private _roles: Array, placeholder?: string, description?: string, layout?: Layout, validations?: Array, component?: Component, parentTaskId?: string) { diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.spec.ts b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.spec.ts index b843c45d1f..aed7114823 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.spec.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.spec.ts @@ -4,7 +4,7 @@ import {TestBed} from '@angular/core/testing'; describe('UserValue', () => { it('should create an instance', () => { let user: UserValue; - user = new UserValue('0', 'realmID0', 'name', 'surname', 'mail'); + user = new UserValue('0', 'realmID0', 'name', 'surname', 'name surname','mail'); expect(user.id).toEqual('0'); expect(user.firstName).toEqual('name'); expect(user.lastName).toEqual('surname'); diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.ts b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.ts index 0100b736a9..c32e889751 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-field/models/user-value.ts @@ -10,9 +10,11 @@ export class UserValue { * @param _realmId the id of the selected user realm * @param _firstName the first name of the selected user * @param _lastName the surname of the selected user + * @param _fullName the full name of the selected user * @param _username email of the selected user */ - constructor(private _id: string, private _realmId: string, private _firstName: string, private _lastName: string, private _username: string) { + constructor(private _id: string, private _realmId: string, private _firstName: string, private _lastName: string, + private _fullName: string, private _username: string) { } get id(): string { @@ -32,7 +34,7 @@ export class UserValue { } get fullName(): string { - return this._firstName + ' ' + this._lastName; + return this._fullName; } get username(): string { diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.spec.ts b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.spec.ts index 9d7a3ac0e8..e672c6a129 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.spec.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.spec.ts @@ -6,7 +6,7 @@ import {expect} from "@ngbracket/ngx-layout/_private-utils/testing"; describe('UserListValue', () => { it('should create an instance', () => { let user: UserListValue; - user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'mail')]])); + user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'name surname', 'mail')]])); expect(user.userValues.get('0').id).toEqual('0'); expect(user.userValues.get('0').firstName).toEqual('name'); expect(user.userValues.get('0').lastName).toEqual('surname'); @@ -16,13 +16,13 @@ describe('UserListValue', () => { it('should get last', () => { let user: UserListValue; - user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'mail')]])); + user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'name surname', 'mail')]])); expect(user.getLast().id === '0').toBeTruthy(); }); it('should remove', () => { let user: UserListValue; - user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'mail')]])); + user = new UserListValue(new Map([['0', new UserValue('0', 'realmID0','name', 'surname', 'name surname', 'mail')]])); expect(user.userValues.size === 1).toBeTruthy(); user.removeUserValue('0'); expect(user.userValues.size === 0).toBeTruthy(); diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts index 8c70a5898b..1d4d2297bb 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts @@ -6,6 +6,7 @@ import { UserValue } from '../../user-field/models/user-value'; export class UserListValue { + // todo rebranding to actor-list-field private _userValues: Map; @@ -31,7 +32,7 @@ export class UserListValue { public getLast(): UserValue { if (this._userValues.size == 0) { - return new UserValue('', '', '', '', ''); + return new UserValue('', '', '', '', '', ''); } return Array.from(this._userValues.values()).pop(); } diff --git a/projects/netgrif-components-core/src/lib/header/header-modes/search-mode/abstract-search-mode.component.spec.ts b/projects/netgrif-components-core/src/lib/header/header-modes/search-mode/abstract-search-mode.component.spec.ts index 9acd103e83..426ca3bcdd 100644 --- a/projects/netgrif-components-core/src/lib/header/header-modes/search-mode/abstract-search-mode.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/header/header-modes/search-mode/abstract-search-mode.component.spec.ts @@ -84,7 +84,7 @@ describe('AbstractSearchModeComponent', () => { })); it('should transform UserValue into id', fakeAsync(() => { - component.formControls[0].setValue(new UserValue('7', 'realmID0', '', '', '')); + component.formControls[0].setValue(new UserValue('7', 'realmID0', '', '', '','')); tick(600); expect(headerSpy).toHaveBeenCalledWith(0, '7'); })); diff --git a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts index 9d6dd56440..dbdef32e24 100644 --- a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts +++ b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts @@ -68,9 +68,9 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa icon: 'file_copy', type: immediate.type }; - case 'userList': - return {value: immediate.value?.userValues.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type}; - case 'user': + case 'actorList': + return {value: immediate.value?.actorValues.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type}; + case 'actor': return {value: immediate.value.fullName, icon: 'account_circle', type: immediate.type}; case 'boolean': return { diff --git a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts index 3f8202c32a..6daccce65b 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts @@ -173,8 +173,8 @@ export class CaseDataset extends Category implements AutocompleteOpti this._operatorService.getOperator(Equals), this._operatorService.getOperator(NotEquals) ]; - case 'user': - case 'userList': + case 'actor': + case 'actorList': return [ this._operatorService.getOperator(Equals), this._operatorService.getOperator(NotEquals), @@ -261,7 +261,7 @@ export class CaseDataset extends Category implements AutocompleteOpti || this.isSelectedOperator(IsNull)); case 'user': case 'userList': - return resolver.getIndex(datafield.fieldId, SearchIndex.USER_ID); + return resolver.getIndex(datafield.fieldId, SearchIndex.ACTOR_ID); case 'i18n': return resolver.getIndex(datafield.fieldId, SearchIndex.TEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring) || this.isSelectedOperator(IsNull)); diff --git a/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts b/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts index a5e42592e2..0cadd861ec 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts @@ -89,9 +89,9 @@ export class CaseSimpleDataset extends NoConfigurationCategory { case 'fileList': this._elasticKeyword = resolver.getIndex(this._fieldId, SearchIndex.FILE_NAME, this.isSelectedOperator(Substring)); break; - case 'user': - case 'userList': - this._elasticKeyword = resolver.getIndex(this._fieldId, SearchIndex.USER_ID); + case 'actor': + case 'actorList': + this._elasticKeyword = resolver.getIndex(this._fieldId, SearchIndex.ACTOR_ID); break; case 'i18n': this._elasticKeyword = resolver.getIndex(this._fieldId, SearchIndex.TEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring)) diff --git a/projects/netgrif-components-core/src/lib/search/models/datafield-map-key.ts b/projects/netgrif-components-core/src/lib/search/models/datafield-map-key.ts index e57b017e55..ebdabec6b8 100644 --- a/projects/netgrif-components-core/src/lib/search/models/datafield-map-key.ts +++ b/projects/netgrif-components-core/src/lib/search/models/datafield-map-key.ts @@ -46,9 +46,9 @@ export class DatafieldMapKey implements SearchAutocompleteOption { return 'check_box'; case 'number': return 'looks_one'; - case 'user': + case 'actor': return 'person'; - case 'userList': + case 'actorList': return 'people'; case 'dateTime': return 'schedule'; diff --git a/projects/netgrif-components-core/src/lib/search/models/search-index.ts b/projects/netgrif-components-core/src/lib/search/models/search-index.ts index 5c204be2b7..75ad2db708 100644 --- a/projects/netgrif-components-core/src/lib/search/models/search-index.ts +++ b/projects/netgrif-components-core/src/lib/search/models/search-index.ts @@ -70,5 +70,5 @@ export enum SearchIndex { * * Used by User and UserListFields */ - USER_ID = 'userIdValue', + ACTOR_ID = 'actorIdValue', } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/abstract-multi-user-assign.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/abstract-multi-user-assign.component.spec.ts index 4b67dbdf35..f48bdefffd 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/abstract-multi-user-assign.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/abstract-multi-user-assign.component.spec.ts @@ -53,16 +53,16 @@ describe('AbstractMultiUserAssignComponent', () => { }); it('should select', () => { - component.userWasSelected(new UserValue('0', 'realmID0', '', '', '')); + component.userWasSelected(new UserValue('0', 'realmID0', '', '', '','')); expect(component.currentUsers).toBeTruthy(); expect(component.currentUsers.find(u => u.id === '0')).toBeTruthy() }); it('should unselect', () => { - component.userWasSelected(new UserValue('0', 'realmID0', '', '', '')); + component.userWasSelected(new UserValue('0', 'realmID0', '', '', '','')); expect(component.currentUsers).toBeTruthy(); expect(component.currentUsers.find(u => u.id === '0')).toBeTruthy() - component.userWasUnselected(new UserValue('0', 'realmID0', '', '', '')); + component.userWasUnselected(new UserValue('0', 'realmID0', '', '', '','')); expect(component.currentUsers.length === 0).toBeTruthy(); }); diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/base-user-assign-list/abstract-base-user-assign-list.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/base-user-assign-list/abstract-base-user-assign-list.component.spec.ts index 8fd5852575..6e0b26f26f 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/base-user-assign-list/abstract-base-user-assign-list.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/base-user-assign-list/abstract-base-user-assign-list.component.spec.ts @@ -81,6 +81,6 @@ class TestUserComponent extends AbstractBaseUserAssignListComponent implements O template: '' }) class TestWrapperComponent { - injectedData = {roles: [], value: new UserValue('5', 'realmID0','admin', 'netgrif', 'super@netgrif.com')} as UserListInjectedData; + injectedData = {roles: [], value: new UserValue('5', 'realmID0','admin', 'netgrif', 'admin netgrif', 'super@netgrif.com')} as UserListInjectedData; formControl = new FormControl(); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.spec.ts index 3271dc7ee8..8a9f3e8f3a 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.spec.ts @@ -75,6 +75,6 @@ class TestUserComponent extends AbstractMultiUserAssignListComponent { template: '' }) class TestWrapperComponent { - injectedData = {roles: [], value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'super@netgrif.com')} as UserListInjectedData; + injectedData = {roles: [], value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'admin netgrif', 'super@netgrif.com')} as UserListInjectedData; formControl = new FormControl(); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.ts index e22369ef45..fa6728c5b9 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/abstract-multi-user-assign-list.component.ts @@ -59,10 +59,10 @@ export abstract class AbstractMultiUserAssignListComponent extends AbstractBaseU const index = this._currentlySelectedUsers.indexOf(selectedUser.id); if (index > -1) { this._currentlySelectedUsers.splice(index, 1); - this.userUnselected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.username)); + this.userUnselected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.fullName, selectedUser.username)); } else { this._currentlySelectedUsers.push(selectedUser.id); - this.userSelected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.username)); + this.userSelected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.fullName, selectedUser.username)); } this._selectedUsers$.next([...this._currentlySelectedUsers]); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/multi-user-assign-item/abstract-multi-user-assign-item.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/multi-user-assign-item/abstract-multi-user-assign-item.component.spec.ts index 49c241db0f..09f24bd8f9 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/multi-user-assign-item/abstract-multi-user-assign-item.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/multi-user-assign-list/multi-user-assign-item/abstract-multi-user-assign-item.component.spec.ts @@ -53,5 +53,5 @@ class TestUserComponent extends AbstractMultiUserAssignItemComponent { template: '' }) class TestWrapperComponent { - user = new UserValue('0', 'realmID0', '', '', ''); + user = new UserValue('0', 'realmID0', '', '', '', ''); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.spec.ts index bb6c152041..265230b5eb 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.spec.ts @@ -70,7 +70,7 @@ class TestUserComponent extends AbstractUserAssignListComponent { class TestWrapperComponent { injectedData = { roles: [], - value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'super@netgrif.com') + value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'admin netgrif','super@netgrif.com') } as UserListInjectedData; formControl = new FormControl(); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.ts index 378ff8d260..2749a3b9e8 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/abstract-user-assign-list.component.ts @@ -74,7 +74,7 @@ export abstract class AbstractUserAssignListComponent extends AbstractBaseUserAs * @param selectedUser [UserValue]{@link UserValue} */ public select(selectedUser: UserListItem): void { - this.userSelected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.username)); + this.userSelected.emit(new UserValue(selectedUser.id, selectedUser.realmId, selectedUser.firstName, selectedUser.lastName, selectedUser.fullName, selectedUser.username)); this._markSelectedUser(selectedUser); } diff --git a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/abstract-user-assign-item.component.spec.ts b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/abstract-user-assign-item.component.spec.ts index 3c27635c4b..8a4fb269dd 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/abstract-user-assign-item.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/abstract-user-assign-item.component.spec.ts @@ -53,5 +53,5 @@ class TestUserComponent extends AbstractUserAssignItemComponent { template: '' }) class TestWrapperComponent { - user = new UserValue('0', 'realmID0', '', '', ''); + user = new UserValue('0', 'realmID0', '', '', '',''); } diff --git a/projects/netgrif-components-core/src/lib/task-content/model/field-type-resource.ts b/projects/netgrif-components-core/src/lib/task-content/model/field-type-resource.ts index 234078bfac..3ad095beb1 100644 --- a/projects/netgrif-components-core/src/lib/task-content/model/field-type-resource.ts +++ b/projects/netgrif-components-core/src/lib/task-content/model/field-type-resource.ts @@ -9,8 +9,8 @@ export enum FieldTypeResource { MULTICHOICE = 'multichoice', DATE = 'date', DATE_TIME = 'dateTime', - USER = 'user', - USER_LIST = 'userList', + ACTOR = 'actor', + ACTOR_LIST = 'actorList', BUTTON = 'button', FILE = 'file', FILE_LIST = 'fileList', diff --git a/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.spec.ts b/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.spec.ts index 7b85e07da2..ac40d9ce94 100644 --- a/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.spec.ts +++ b/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.spec.ts @@ -56,7 +56,7 @@ describe('FieldConvertorService', () => { expect(service.formatValueForBackend(service.toClass(dataField), date)) .toEqual(date.format('YYYY-MM-DD')); - dataField.type = FieldTypeResource.USER; + dataField.type = FieldTypeResource.ACTOR; expect(service.formatValueForBackend(service.toClass(dataField), {id: 5})).toEqual(5); dataField.type = FieldTypeResource.DATE_TIME; @@ -122,9 +122,9 @@ describe('FieldConvertorService', () => { dataField.value = [2020, 3, 3, 3, 30] as any; expect(service.resolveType(service.toClass(dataField))).toEqual('dateTime'); - dataField.type = FieldTypeResource.USER; + dataField.type = FieldTypeResource.ACTOR; dataField.value = {id: 5, name: 'name', surname: 'surname', email: 'mail'} as any; - expect(service.resolveType(service.toClass(dataField))).toEqual('user'); + expect(service.resolveType(service.toClass(dataField))).toEqual('actor'); dataField.type = FieldTypeResource.BUTTON; dataField.value = 0 as any; diff --git a/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.ts b/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.ts index 20807c9afe..39ec158165 100644 --- a/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.ts +++ b/projects/netgrif-components-core/src/lib/task-content/services/field-converter.service.ts @@ -79,18 +79,18 @@ export class FieldConverterService { return new DateTimeField(item.stringId, item.name, dateTime, item.behavior, item.placeholder, item.description, item.layout, item.validations, item.component, item.parentTaskId); } - case FieldTypeResource.USER: { + case FieldTypeResource.ACTOR: { let user; if (item.value) { - user = new UserValue(item.value.id, item.value.realmId, item.value.firstName, item.value.lastName, item.value.username); + user = new UserValue(item.value.id, item.value.realmId, item.value.firstName, item.value.lastName, item.value.fullName, item.value.username); } return new UserField(item.stringId, item.name, item.behavior, user, item.roles, item.placeholder, item.description, item.layout, item.validations, item.component, item.parentTaskId); } - case FieldTypeResource.USER_LIST: { + case FieldTypeResource.ACTOR_LIST: { let userListValue = new UserListValue(new Map()); if (item.value) { - item.value.userValues.forEach(u => userListValue.addUserValue(new UserValue(u.id, u.realmId, u.firstName, u.lastName, u.username))); + item.value.actorValues.forEach(u => userListValue.addUserValue(new UserValue(u.id, u.realmId, u.firstName, u.lastName, u.fullName, u.username))); } return new UserListField(item.stringId, item.name, item.behavior, userListValue, item.roles, item.placeholder, item.description, item.layout, item.validations, item.component, item.parentTaskId); @@ -143,9 +143,9 @@ export class FieldConverterService { } else if (item instanceof FileListField) { return FieldTypeResource.FILE_LIST; } else if (item instanceof UserField) { - return FieldTypeResource.USER; + return FieldTypeResource.ACTOR; } else if (item instanceof UserListField) { - return FieldTypeResource.USER_LIST; + return FieldTypeResource.ACTOR_LIST; } else if (item instanceof TaskRefField) { return FieldTypeResource.TASK_REF; } else if (item instanceof EnumerationField || item instanceof MultichoiceField) { @@ -179,10 +179,10 @@ export class FieldConverterService { return value.format('YYYY-MM-DD'); } } - if (this.resolveType(field) === FieldTypeResource.USER) { + if (this.resolveType(field) === FieldTypeResource.ACTOR) { return value.id; } - if (this.resolveType(field) === FieldTypeResource.USER_LIST) { + if (this.resolveType(field) === FieldTypeResource.ACTOR_LIST) { return [...value.userValues.keys()]; } if (this.resolveType(field) === FieldTypeResource.DATE_TIME) { @@ -292,8 +292,8 @@ export class FieldConverterService { if (this.resolveType(field) === FieldTypeResource.DATE) { return moment(new Date(value[0], value[1] - 1, value[2])); } - if (this.resolveType(field) === FieldTypeResource.USER) { - return new UserValue(value.id, value.realmId, value.firstName, value.lastName, value.username); + if (this.resolveType(field) === FieldTypeResource.ACTOR) { + return new UserValue(value.id, value.realmId, value.firstName, value.lastName, value.fullName, value.username); } if (this.resolveType(field) === FieldTypeResource.DATE_TIME) { return moment(new Date(value[0], value[1] - 1, value[2], value[3], value[4])); @@ -309,7 +309,7 @@ export class FieldConverterService { }); return array; } - if (this.resolveType(field) === FieldTypeResource.USER_LIST && !!value) { + if (this.resolveType(field) === FieldTypeResource.ACTOR_LIST && !!value) { return new UserListValue(new Map(value.userValues.map(v => [v.id, v]))); } return value; diff --git a/projects/netgrif-components-core/src/lib/task/services/delegate-task.service.ts b/projects/netgrif-components-core/src/lib/task/services/delegate-task.service.ts index cbb27207f1..c0de944bda 100644 --- a/projects/netgrif-components-core/src/lib/task/services/delegate-task.service.ts +++ b/projects/netgrif-components-core/src/lib/task/services/delegate-task.service.ts @@ -78,7 +78,7 @@ export class DelegateTaskService extends TaskHandlingService { roles: Object.keys(this._safeTask.roles).filter(role => this._safeTask.roles[role]['assign'] !== undefined && this._safeTask.roles[role]['assign']), value: !this._safeTask.userId ? undefined : new UserValue( - this._safeTask.userId, '', '', '', '' + this._safeTask.userId, '', '', '', '', '' ), negativeRoles: Object.keys(this._safeTask.roles).filter(role => this._safeTask.roles[role]['assign'] !== undefined && !this._safeTask.roles[role]['assign']) diff --git a/projects/netgrif-components-core/src/lib/view/abstract/sortable-view.ts b/projects/netgrif-components-core/src/lib/view/abstract/sortable-view.ts index 42e24d51be..4dbead2479 100644 --- a/projects/netgrif-components-core/src/lib/view/abstract/sortable-view.ts +++ b/projects/netgrif-components-core/src/lib/view/abstract/sortable-view.ts @@ -69,8 +69,8 @@ export abstract class AbstractSortableViewComponent implements OnDestroy { case 'date': case 'dateTime': return this._resolver.getIndex(this._lastHeaderSearchState.fieldIdentifier, SearchIndex.TIMESTAMP); - case 'user': - case 'userList': + case 'actor': + case 'actorList': return this._resolver.getIndex(this._lastHeaderSearchState.fieldIdentifier, SearchIndex.FULL_NAME, true); default: return this._resolver.getIndex(this._lastHeaderSearchState.fieldIdentifier, SearchIndex.FULLTEXT, true); From 9615a347cad7efd73ad7a2d6eaf171e3d27f7442 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 09:30:30 +0100 Subject: [PATCH 02/10] [NAE-2285] Group as a value of userlists - fix tests --- .../admin-impersonate-item.component.spec.ts | 2 +- .../admin-impersonate-list.component.spec.ts | 2 +- .../multi-user-assign-item.component.spec.ts | 2 +- .../multi-user-assign-list.component.spec.ts | 2 +- .../user-assign-item/user-assign-item.component.spec.ts | 2 +- .../user-assign-list/user-assign-list.component.spec.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-item/admin-impersonate-item.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-item/admin-impersonate-item.component.spec.ts index 84785daaa7..e4b7434ab3 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-item/admin-impersonate-item.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-item/admin-impersonate-item.component.spec.ts @@ -39,5 +39,5 @@ describe('AdminImpersonateItemComponent', () => { template: '' }) class TestWrapperComponent { - user = new UserValue('0', 'realmID0', '', '', ''); + user = new UserValue('0', 'realmID0', '', '', '', ''); } diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-list.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-list.component.spec.ts index b4a50d6cb5..c744efc7b7 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-list.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/admin-impersonate/admin-impersonate-list/admin-impersonate-list.component.spec.ts @@ -63,7 +63,7 @@ describe('AdminImpersonateListComponent', () => { class TestWrapperComponent { injectedData = { roles: [], - value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'super@netgrif.com') + value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'admin netgrif', 'super@netgrif.com') } as UserListInjectedData; formControl = new FormControl(); } diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-item/multi-user-assign-item.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-item/multi-user-assign-item.component.spec.ts index 98737085af..0e9e69488d 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-item/multi-user-assign-item.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-item/multi-user-assign-item.component.spec.ts @@ -42,5 +42,5 @@ describe('MultiUserAssignItemComponent', () => { template: '' }) class TestWrapperComponent { - user = new UserValue('0', 'realmID0', '', '', ''); + user = new UserValue('0', 'realmID0', '', '', '', ''); } diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-list.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-list.component.spec.ts index 46abacd1b5..cc7f69ea6d 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-list.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/multi-user-assign/multi-user-assign-list/multi-user-assign-list.component.spec.ts @@ -63,7 +63,7 @@ describe('MultiUserAssignListComponent', () => { class TestWrapperComponent { injectedData = { roles: [], - value: new UserListValue(new Map([['5', new UserValue('5', 'realmID0', 'admin', 'netgrif', 'super@netgrif.com')]])) + value: new UserListValue(new Map([['5', new UserValue('5', 'realmID0', 'admin', 'netgrif', 'admin netgrif','super@netgrif.com')]])) } as UserListInjectedData; formControl = new FormControl(); } diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/user-assign-item.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/user-assign-item.component.spec.ts index 9da6c5e6b2..0035ad4fbd 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/user-assign-item.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-item/user-assign-item.component.spec.ts @@ -39,5 +39,5 @@ describe('UserAssignItemComponent', () => { template: '' }) class TestWrapperComponent { - user = new UserValue('0', 'realmID0', '', '', ''); + user = new UserValue('0', 'realmID0', '', '', '', ''); } diff --git a/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-list.component.spec.ts b/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-list.component.spec.ts index 096f76f53e..1e6daa89fb 100644 --- a/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-list.component.spec.ts +++ b/projects/netgrif-components/src/lib/side-menu/content-components/user-assign/user-assign-list/user-assign-list.component.spec.ts @@ -63,7 +63,7 @@ describe('UserAssignListComponent', () => { class TestWrapperComponent { injectedData = { roles: [], - value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'super@netgrif.com') + value: new UserValue('5', 'realmID0', 'admin', 'netgrif', 'admin netgrif', 'super@netgrif.com') } as UserListInjectedData; formControl = new FormControl(); } From a05ab5716f7219f31da8cd9106614af27b90e92f Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 09:35:39 +0100 Subject: [PATCH 03/10] [NAE-2285] Group as a value of userlists - update todo comment --- .../lib/data-fields/user-list-field/models/user-list-value.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts index 1d4d2297bb..9c3308d8da 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/user-list-field/models/user-list-value.ts @@ -6,7 +6,7 @@ import { UserValue } from '../../user-field/models/user-value'; export class UserListValue { - // todo rebranding to actor-list-field + // TODO: rebranding to actor-list-field private _userValues: Map; From 551480f88a902db8cc25ee99acfa9622ad42c6e3 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 09:37:36 +0100 Subject: [PATCH 04/10] [NAE-2285] Group as a value of userlists - add optional chaining --- .../src/lib/panel/abstract/panel-with-immediate-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts index dbdef32e24..9d3de8bc93 100644 --- a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts +++ b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts @@ -71,7 +71,7 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa case 'actorList': return {value: immediate.value?.actorValues.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type}; case 'actor': - return {value: immediate.value.fullName, icon: 'account_circle', type: immediate.type}; + return {value: immediate.value?.fullName, icon: 'account_circle', type: immediate.type}; case 'boolean': return { value: this._translate.instant('dataField.values.boolean.' + immediate.value), From 1b6d657b7af175716de2226510b15784a5746bb4 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 09:40:41 +0100 Subject: [PATCH 05/10] [NAE-2285] Group as a value of userlists - fix switch cases --- .../src/lib/search/models/category/case/case-dataset.ts | 6 +++--- .../lib/search/models/category/case/case-simple-dataset.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts index 6daccce65b..928909e0e9 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.ts @@ -78,7 +78,7 @@ export class CaseDataset extends Category implements AutocompleteOpti return SearchInputType.NUMBER; case 'boolean': return SearchInputType.BOOLEAN; - case 'user': + case 'actor': return SearchInputType.AUTOCOMPLETE; default: return SearchInputType.TEXT; @@ -259,8 +259,8 @@ export class CaseDataset extends Category implements AutocompleteOpti return resolver.getIndex(datafield.fieldId, SearchIndex.FILE_NAME, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring) || this.isSelectedOperator(IsNull)); - case 'user': - case 'userList': + case 'actor': + case 'actorList': return resolver.getIndex(datafield.fieldId, SearchIndex.ACTOR_ID); case 'i18n': return resolver.getIndex(datafield.fieldId, SearchIndex.TEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring) diff --git a/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts b/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts index 0cadd861ec..dc0ee2f3ac 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/case/case-simple-dataset.ts @@ -115,7 +115,7 @@ export class CaseSimpleDataset extends NoConfigurationCategory { return this._operatorService.getOperator(Equals); case 'boolean': return this._operatorService.getOperator(Equals); - case 'user': + case 'actor': return this._operatorService.getOperator(Equals); case 'date': return this._operatorService.getOperator(EqualsDate); From c545d313e5320ca7a12145b892453c95baf42a0e Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 09:46:17 +0100 Subject: [PATCH 06/10] [NAE-2285] Group as a value of userlists - fix case-dataset.spec.ts --- .../models/category/case/case-dataset.spec.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.spec.ts b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.spec.ts index 69dc01d6d6..e8df9675ab 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.spec.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/case/case-dataset.spec.ts @@ -83,8 +83,8 @@ describe('CaseDataset', () => { {stringId: 'multichoice_mapField', title: 'title', type: 'multichoice_map'}, {stringId: 'fileField', title: 'title', type: 'file'}, {stringId: 'fileListField', title: 'title', type: 'fileList'}, - {stringId: 'userListField', title: 'title', type: 'userList'}, - {stringId: 'userField', title: 'title', type: 'user'}, + {stringId: 'actorListField', title: 'title', type: 'actorList'}, + {stringId: 'actorField', title: 'title', type: 'actor'}, {stringId: 'dateField', title: 'title', type: 'date'}, {stringId: 'dateTimeField', title: 'title', type: 'dateTime'}, ]; @@ -142,9 +142,9 @@ describe('CaseDataset', () => { expect(metadata.values).toEqual([v]); }, operatorService); }); - it('userList field search', (done) => { + it('actorList field search', (done) => { const v = 'value'; - serializationTest(done, category, Equals, 'userList', v, (metadata) => { + serializationTest(done, category, Equals, 'actorList', v, (metadata) => { expect(metadata.values).toEqual([v]); }, operatorService); }); @@ -160,9 +160,9 @@ describe('CaseDataset', () => { expect(metadata.values).toEqual([v]); }, operatorService); }); - it('user field search', (done) => { + it('actor field search', (done) => { const v = mockUserSearchValue('Test User', '7'); - serializationTest(done, category, Equals, 'user', v, (metadata) => { + serializationTest(done, category, Equals, 'actor', v, (metadata) => { const mockedSerializedValue = mockUserSearchValue('Test User', '7'); delete mockedSerializedValue.icon; expect(metadata.values).toEqual([mockedSerializedValue]); @@ -223,9 +223,9 @@ describe('CaseDataset', () => { deserializationTest(done, category, Equals, 'fileList', v, (d, c) => valueObjectsComparison(d, c), operatorService, allowedNets$); }); - it('userList field search', (done) => { + it('actorList field search', (done) => { const v = 'value'; - deserializationTest(done, category, Equals, 'userList', v, (d, c) => valueObjectsComparison(d, c), + deserializationTest(done, category, Equals, 'actorList', v, (d, c) => valueObjectsComparison(d, c), operatorService, allowedNets$); }); it('number field search', (done) => { @@ -238,9 +238,9 @@ describe('CaseDataset', () => { deserializationTest(done, category, Equals, 'boolean', v, (d, c) => valueObjectsComparison(d, c), operatorService, allowedNets$); }); - it('user field search', (done) => { + it('actor field search', (done) => { const v = mockUserSearchValue('Test User', '7'); - deserializationTest(done, category, Equals, 'user', v, (d, c) => valueObjectsComparison(d, c), + deserializationTest(done, category, Equals, 'actor', v, (d, c) => valueObjectsComparison(d, c), operatorService, allowedNets$); }); it('date field search', (done) => { From ca94343897e0cd0231b512080a31b3ed80d0f0e8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 7 Jan 2026 10:03:47 +0100 Subject: [PATCH 07/10] [NAE-2285] Group as a value of userlists - add optional check - fix typo in function name --- .../src/lib/panel/abstract/panel-with-immediate-data.ts | 2 +- .../create-view-prompt/schematic-create-sidenav-prompt.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts index 9d3de8bc93..5945dde083 100644 --- a/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts +++ b/projects/netgrif-components-core/src/lib/panel/abstract/panel-with-immediate-data.ts @@ -69,7 +69,7 @@ export abstract class AbstractPanelWithImmediateDataComponent extends AbstractPa type: immediate.type }; case 'actorList': - return {value: immediate.value?.actorValues.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type}; + return {value: immediate.value?.actorValues?.map(obj => obj.fullName).join(', '), icon: 'account_circle', type: immediate.type}; case 'actor': return {value: immediate.value?.fullName, icon: 'account_circle', type: immediate.type}; case 'boolean': diff --git a/projects/netgrif-components/schematics/view/create-view-prompt/schematic-create-sidenav-prompt.ts b/projects/netgrif-components/schematics/view/create-view-prompt/schematic-create-sidenav-prompt.ts index fabc5a3a1c..4f613881ed 100644 --- a/projects/netgrif-components/schematics/view/create-view-prompt/schematic-create-sidenav-prompt.ts +++ b/projects/netgrif-components/schematics/view/create-view-prompt/schematic-create-sidenav-prompt.ts @@ -32,13 +32,13 @@ export function checkJsonParamsForSidenav(args: CreateViewArguments, addViewToSe } } if (sidenav.user !== undefined || sidenav.navigation !== undefined || sidenav.quickPanel !== undefined) { - sidenav = addDefaultVaulues(sidenav); + sidenav = addDefaultValues(sidenav); } } return sidenav; } -function addDefaultVaulues(sidenav: SidenavPromptOptions): SidenavPromptOptions { +function addDefaultValues(sidenav: SidenavPromptOptions): SidenavPromptOptions { if (sidenav.user === undefined) sidenav.user = false; if (sidenav.quickPanel === undefined) From e1f60c3d70373552170f967b50ece9523d297bad Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 6 Feb 2026 14:38:46 +0100 Subject: [PATCH 08/10] [NAE-2285] Group as a value of userlists - fix task authorization - fix case authorization --- .../src/app/doc/panels/panels.component.ts | 2 +- .../permission/permission.service.ts | 33 +++++++++++++++---- .../abstract-case-panel.component.spec.ts | 2 +- .../src/lib/resources/interface/case.ts | 4 +-- .../utility/tests/utility/create-mock-case.ts | 2 +- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/projects/nae-example-app/src/app/doc/panels/panels.component.ts b/projects/nae-example-app/src/app/doc/panels/panels.component.ts index 87e588f285..abb9ed4c84 100644 --- a/projects/nae-example-app/src/app/doc/panels/panels.component.ts +++ b/projects/nae-example-app/src/app/doc/panels/panels.component.ts @@ -68,7 +68,7 @@ export class PanelsComponent implements OnInit { stringId: null, petriNetId: null, permissions: {}, - users: {} + actors: {} }; this.workflow = { stringId: 'ID', diff --git a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts index 803e6672ee..64bc718c45 100644 --- a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts +++ b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts @@ -6,6 +6,7 @@ import {UserService} from '../../user/services/user.service'; import {Case} from '../../resources/interface/case'; import {PetriNetReferenceWithPermissions} from '../../process/petri-net-reference-with-permissions'; import {Permissions, PermissionType, UserPermissions} from '../../process/permissions'; +import {User} from "../../user/models/user"; @Injectable({ providedIn: 'root' @@ -31,7 +32,7 @@ export class PermissionService { } const rolePermValue = this.checkRolePerms(case_.permissions, permission); - const userPermValue = this.checkUserPerms(case_.users, permission); + const userPermValue = this.checkUserPerms(case_.actors, permission); return this.resolvePermissions(rolePermValue, userPermValue); } @@ -108,14 +109,34 @@ export class PermissionService { public checkUserPerms(users: UserPermissions, permission): boolean | undefined { let userPermValue: boolean; if (!!users) { - const loggedUserId = this._userService.user.getSelfOrImpersonated().id; - Object.keys(users).forEach(user => { - if (user === loggedUserId && users[user][permission] !== undefined) { - userPermValue = userPermValue === undefined ? - users[user][permission] : userPermValue && users[user][permission]; + const loggedUser: User = this._userService.user.getSelfOrImpersonated(); + Object.keys(users).forEach(actorId => { + if (actorId !== loggedUser.id && !loggedUser.nextGroups?.includes(actorId)) { + return; + } + let currentUserPermission: boolean = this.getPermissionByUserOrGroup(users, permission, loggedUser) + if (currentUserPermission !== undefined) { + userPermValue = userPermValue === undefined ? currentUserPermission : userPermValue && currentUserPermission; } }); } return userPermValue; } + + protected getPermissionByUserOrGroup(permissions: UserPermissions, permission, loggedUser: User): boolean | undefined { + let userPermValue: boolean; + if (permissions[loggedUser.id] !== undefined) { + userPermValue = permissions[loggedUser.id][permission]; + } + if (loggedUser.nextGroups === undefined || loggedUser.nextGroups.length === 0) { + return userPermValue; + } + loggedUser.nextGroups.forEach(function(groupId) { + if (permissions[groupId] !== undefined && permissions[groupId][permission] !== undefined) { + userPermValue = userPermValue === undefined ? + permissions[groupId][permission] : userPermValue && permissions[groupId][permission]; + } + }) + return userPermValue; + } } diff --git a/projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.spec.ts b/projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.spec.ts index b20f908721..086f2f5feb 100644 --- a/projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.spec.ts @@ -142,7 +142,7 @@ class TestWrapperComponent { delete: true } }, - users: {}, + actors: {}, color: 'color', creationDate: [], lastModified: [], diff --git a/projects/netgrif-components-core/src/lib/resources/interface/case.ts b/projects/netgrif-components-core/src/lib/resources/interface/case.ts index a09d6c0f6d..d9b94c6896 100644 --- a/projects/netgrif-components-core/src/lib/resources/interface/case.ts +++ b/projects/netgrif-components-core/src/lib/resources/interface/case.ts @@ -122,8 +122,8 @@ export interface Case { /** * **Example:** {} */ - users?: UserPermissions; - userRefs?: UserRefs; + actors?: UserPermissions; + actorRefs?: UserRefs; /** * **Example:** [] */ diff --git a/projects/netgrif-components-core/src/lib/utility/tests/utility/create-mock-case.ts b/projects/netgrif-components-core/src/lib/utility/tests/utility/create-mock-case.ts index b1508aaf80..ec75d00663 100644 --- a/projects/netgrif-components-core/src/lib/utility/tests/utility/create-mock-case.ts +++ b/projects/netgrif-components-core/src/lib/utility/tests/utility/create-mock-case.ts @@ -35,6 +35,6 @@ export function createMockCase(stringId = 'stringId', stringId, petriNetId, permissions: {}, - users: {} + actors: {} }; } From 9b6e4b56d7228f76baceca4bb2f7c740dc4e0f16 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 6 Feb 2026 17:42:24 +0100 Subject: [PATCH 09/10] [NAE-2285] Group as a value of userlists - make rabbit happy --- .../src/lib/authorization/permission/permission.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts index 64bc718c45..b90542f9bf 100644 --- a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts +++ b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts @@ -110,14 +110,17 @@ export class PermissionService { let userPermValue: boolean; if (!!users) { const loggedUser: User = this._userService.user.getSelfOrImpersonated(); + const processedActorIds: Array = [] Object.keys(users).forEach(actorId => { - if (actorId !== loggedUser.id && !loggedUser.nextGroups?.includes(actorId)) { + if (userPermValue === false || processedActorIds.includes(actorId) + || actorId !== loggedUser.id && !loggedUser.nextGroups?.includes(actorId)) { return; } let currentUserPermission: boolean = this.getPermissionByUserOrGroup(users, permission, loggedUser) if (currentUserPermission !== undefined) { userPermValue = userPermValue === undefined ? currentUserPermission : userPermValue && currentUserPermission; } + loggedUser.nextGroups !== undefined ? processedActorIds.push(actorId, ...loggedUser.nextGroups) : processedActorIds.push(actorId) }); } return userPermValue; @@ -128,7 +131,7 @@ export class PermissionService { if (permissions[loggedUser.id] !== undefined) { userPermValue = permissions[loggedUser.id][permission]; } - if (loggedUser.nextGroups === undefined || loggedUser.nextGroups.length === 0) { + if (loggedUser.nextGroups === undefined || loggedUser.nextGroups.length === 0 || userPermValue === false) { return userPermValue; } loggedUser.nextGroups.forEach(function(groupId) { From 8b4ac4966feb731696d6bd6f86d7575336e31ab0 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 6 Feb 2026 18:06:06 +0100 Subject: [PATCH 10/10] [NAE-2285] Group as a value of userlists - make rabbit happy --- .../src/lib/authorization/permission/permission.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts index b90542f9bf..96d003e526 100644 --- a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts +++ b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.ts @@ -110,17 +110,17 @@ export class PermissionService { let userPermValue: boolean; if (!!users) { const loggedUser: User = this._userService.user.getSelfOrImpersonated(); - const processedActorIds: Array = [] + const processedActorIds: Array = []; Object.keys(users).forEach(actorId => { if (userPermValue === false || processedActorIds.includes(actorId) || actorId !== loggedUser.id && !loggedUser.nextGroups?.includes(actorId)) { return; } - let currentUserPermission: boolean = this.getPermissionByUserOrGroup(users, permission, loggedUser) + let currentUserPermission: boolean = this.getPermissionByUserOrGroup(users, permission, loggedUser); if (currentUserPermission !== undefined) { userPermValue = userPermValue === undefined ? currentUserPermission : userPermValue && currentUserPermission; } - loggedUser.nextGroups !== undefined ? processedActorIds.push(actorId, ...loggedUser.nextGroups) : processedActorIds.push(actorId) + loggedUser.nextGroups !== undefined ? processedActorIds.push(actorId, ...loggedUser.nextGroups) : processedActorIds.push(actorId); }); } return userPermValue;