@netgrif/components-core 6.2.1 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/commons/schema.d.ts +1 -0
  2. package/esm2020/assets/i18n/de.json +9 -8
  3. package/esm2020/assets/i18n/en.json +2 -1
  4. package/esm2020/assets/i18n/sk.json +2 -1
  5. package/esm2020/commons/schema.mjs +1 -1
  6. package/esm2020/lib/authorization/permission/access.service.mjs +2 -2
  7. package/esm2020/lib/authorization/role/role-guard.service.mjs +36 -11
  8. package/esm2020/lib/data-fields/file-field/abstract-file-field.component.mjs +6 -3
  9. package/esm2020/lib/data-fields/file-list-field/abstract-file-list-field.component.mjs +5 -2
  10. package/esm2020/lib/data-fields/number-field/currency-number-field/abstract-currency-number-field.component.mjs +3 -2
  11. package/esm2020/lib/navigation/navigation-double-drawer/abstract-navigation-double-drawer.mjs +7 -4
  12. package/esm2020/lib/resources/engine-endpoint/task-resource.service.mjs +3 -3
  13. package/esm2020/lib/search/models/category/case/case-dataset.mjs +7 -4
  14. package/esm2020/lib/search/search-operand-input-component/abstract-search-operand-input.component.mjs +3 -3
  15. package/esm2020/lib/side-menu/content-components/new-case/abstract-new-case.component.mjs +22 -11
  16. package/esm2020/lib/task-content/field-component-resolver/abstract-field-component-resolver.component.mjs +2 -3
  17. package/fesm2015/netgrif-components-core.mjs +96 -47
  18. package/fesm2015/netgrif-components-core.mjs.map +1 -1
  19. package/fesm2020/netgrif-components-core.mjs +96 -47
  20. package/fesm2020/netgrif-components-core.mjs.map +1 -1
  21. package/lib/authorization/role/role-guard.service.d.ts +2 -1
  22. package/lib/data-fields/number-field/currency-number-field/abstract-currency-number-field.component.d.ts +1 -0
  23. package/lib/navigation/navigation-double-drawer/abstract-navigation-double-drawer.d.ts +1 -1
  24. package/lib/resources/engine-endpoint/task-resource.service.d.ts +2 -1
  25. package/lib/search/search-operand-input-component/abstract-search-operand-input.component.d.ts +1 -1
  26. package/package.json +1 -1
  27. package/src/assets/i18n/de.json +9 -8
  28. package/src/assets/i18n/en.json +2 -1
  29. package/src/assets/i18n/sk.json +2 -1
@@ -1187,7 +1187,8 @@ var en = {
1187
1187
  errThird: "Color is required.",
1188
1188
  noNets: "No allowed Nets",
1189
1189
  createCase: "Successful create new case",
1190
- defaultCaseName: "with default case name"
1190
+ defaultCaseName: "with default case name",
1191
+ createCaseError: "A new case was created, but an error occurred while executing actions"
1191
1192
  },
1192
1193
  user: {
1193
1194
  assign: "User Assign",
@@ -1665,7 +1666,8 @@ var sk = {
1665
1666
  errThird: "Farba je povinné pole.",
1666
1667
  noNets: "Žiadne povolené siete",
1667
1668
  createCase: "Úspešne vytvorený nový prípad",
1668
- defaultCaseName: "s prednastaveným názvom prípadu"
1669
+ defaultCaseName: "s prednastaveným názvom prípadu",
1670
+ createCaseError: "Nový prípad vytvorený, nastala však chyba pri vykonávaní akcií"
1669
1671
  },
1670
1672
  user: {
1671
1673
  assign: "Priradiť používateľa",
@@ -1943,8 +1945,8 @@ var forms = {
1943
1945
  enterEmail: "Ihre E-Mail Adresse eingeben"
1944
1946
  },
1945
1947
  login: {
1946
- length: "Das Benützername muss mindestens 4 Zeichen enthalten",
1947
- login: "Benützername",
1948
+ length: "Das Benutzername muss mindestens 4 Zeichen enthalten",
1949
+ login: "Benutzername",
1948
1950
  wrongCredentials: "Falsche Anmeldeinformationen!",
1949
1951
  loginButton: "Anmelden",
1950
1952
  reset: "Kennwort wiederherstellen",
@@ -2143,14 +2145,15 @@ var de = {
2143
2145
  errThird: "Sie müssen eine Farbe auswählen.",
2144
2146
  noNets: "Es gibt keine erlaubte Netze",
2145
2147
  createCase: "Neuen Fall würde erfolgreich erzeugt",
2146
- defaultCaseName: "mit einem Standardfallnamen"
2148
+ defaultCaseName: "mit einem Standardfallnamen",
2149
+ createCaseError: "Neuer Fall wurde erstellt, aber beim Ausführen von Aktionen ist ein Fehler aufgetreten"
2147
2150
  },
2148
2151
  user: {
2149
- assign: "Benützer zuweisen",
2150
- choose: "Benützer auswählen",
2151
- noUser: "Es gibt keine Benützer",
2152
- err: "Beim laden der Benützer ist eine Fehler aufgetreten",
2153
- showcase: "Benützeransichtmodus ist nicht ausgewählt!"
2152
+ assign: "Benutzer zuweisen",
2153
+ choose: "Benutzer auswählen",
2154
+ noUser: "Es gibt keine Benutzer",
2155
+ err: "Beim laden der Benutzer ist eine Fehler aufgetreten",
2156
+ showcase: "Die Benutzeransicht ist nicht gesetzt!"
2154
2157
  },
2155
2158
  ldapGroup: {
2156
2159
  choose: "LDAP-Gruppe suchen",
@@ -6284,9 +6287,9 @@ class TaskResourceService extends AbstractResourceService {
6284
6287
  * Delete file from the task
6285
6288
  * DELETE
6286
6289
  */
6287
- deleteFile(taskId, fieldId, name) {
6290
+ deleteFile(taskId, fieldId, name, param) {
6288
6291
  const url = !!name ? 'task/' + taskId + '/file/' + fieldId + '/' + name : 'task/' + taskId + '/file/' + fieldId;
6289
- return this._resourceProvider.delete$(url, this.SERVER_URL).pipe(map(r => this.changeType(r, undefined)));
6292
+ return this._resourceProvider.delete$(url, this.SERVER_URL, param).pipe(map(r => this.changeType(r, undefined)));
6290
6293
  }
6291
6294
  /**
6292
6295
  * Download task file preview for field value
@@ -6613,7 +6616,9 @@ class AbstractFileFieldComponent extends AbstractDataFieldComponent {
6613
6616
  this._log.error('File cannot be deleted. No task is set to the field.');
6614
6617
  return;
6615
6618
  }
6616
- this._taskResourceService.deleteFile(this.taskId, this.dataField.stringId).pipe(take(1)).subscribe(response => {
6619
+ let param = new HttpParams();
6620
+ param = param.set("parentTaskId", this.resolveParentTaskId());
6621
+ this._taskResourceService.deleteFile(this.taskId, this.dataField.stringId, undefined, param).pipe(take(1)).subscribe(response => {
6617
6622
  if (response.success) {
6618
6623
  const filename = this.dataField.value.name;
6619
6624
  this.dataField.value = {};
@@ -6697,7 +6702,7 @@ class AbstractFileFieldComponent extends AbstractDataFieldComponent {
6697
6702
  if (!this.checkFileBeforeDownload()) {
6698
6703
  return;
6699
6704
  }
6700
- this._taskResourceService.downloadFile(this.taskId, this.dataField.stringId).subscribe(response => {
6705
+ this._taskResourceService.downloadFile(this.resolveParentTaskId(), this.dataField.stringId).subscribe(response => {
6701
6706
  if (!response.type || response.type !== ProgressType.DOWNLOAD) {
6702
6707
  this._log.debug(`File [${this.dataField.stringId}] ${this.dataField.value.name} was successfully downloaded`);
6703
6708
  this.initDownloadFile(response);
@@ -7004,7 +7009,9 @@ class AbstractFileListFieldComponent extends AbstractDataFieldComponent {
7004
7009
  this._log.error('File cannot be deleted. No task is set to the field.');
7005
7010
  return;
7006
7011
  }
7007
- this._taskResourceService.deleteFile(this.taskId, this.dataField.stringId, fileName).pipe(take(1)).subscribe((response) => {
7012
+ let param = new HttpParams();
7013
+ param = param.set("parentTaskId", this.resolveParentTaskId());
7014
+ this._taskResourceService.deleteFile(this.taskId, this.dataField.stringId, fileName, param).pipe(take(1)).subscribe((response) => {
7008
7015
  if (response.success) {
7009
7016
  const changedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(response.outcome);
7010
7017
  this.dataField.emitChangedFields(changedFieldsMap);
@@ -7300,6 +7307,7 @@ class AbstractCurrencyNumberFieldComponent extends AbstractNumberErrorsComponent
7300
7307
  this._currencyPipe = _currencyPipe;
7301
7308
  this.NUMBER_TYPE = 'number';
7302
7309
  this.TEXT_TYPE = 'text';
7310
+ this.WHITESPACE = ' ';
7303
7311
  }
7304
7312
  ngAfterViewInit() {
7305
7313
  this.fieldType = this.TEXT_TYPE;
@@ -7307,7 +7315,7 @@ class AbstractCurrencyNumberFieldComponent extends AbstractNumberErrorsComponent
7307
7315
  this.numberField.valueChanges().subscribe(value => {
7308
7316
  if (value !== undefined) {
7309
7317
  if (this.fieldType === this.TEXT_TYPE) {
7310
- this.transformedValue = this.transformCurrency(value.toString());
7318
+ this.transformedValue = this.transformCurrency(value.toString()) + this.WHITESPACE;
7311
7319
  }
7312
7320
  }
7313
7321
  else {
@@ -11084,14 +11092,17 @@ class CaseDataset extends Category {
11084
11092
  return resolver.getIndex(datafield.fieldId, SearchIndex.BOOLEAN);
11085
11093
  case 'file':
11086
11094
  case 'fileList':
11087
- return resolver.getIndex(datafield.fieldId, SearchIndex.FILE_NAME, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring));
11095
+ return resolver.getIndex(datafield.fieldId, SearchIndex.FILE_NAME, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring)
11096
+ || this.isSelectedOperator(IsNull));
11088
11097
  case 'user':
11089
11098
  case 'userList':
11090
11099
  return resolver.getIndex(datafield.fieldId, SearchIndex.USER_ID);
11091
11100
  case 'i18n':
11092
- return resolver.getIndex(datafield.fieldId, SearchIndex.TEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring));
11101
+ return resolver.getIndex(datafield.fieldId, SearchIndex.TEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring)
11102
+ || this.isSelectedOperator(IsNull));
11093
11103
  default:
11094
- return resolver.getIndex(datafield.fieldId, SearchIndex.FULLTEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring));
11104
+ return resolver.getIndex(datafield.fieldId, SearchIndex.FULLTEXT, this.isSelectedOperator(Equals) || this.isSelectedOperator(NotEquals) || this.isSelectedOperator(Substring)
11105
+ || this.isSelectedOperator(IsNull));
11095
11106
  }
11096
11107
  }
11097
11108
  get inputPlaceholder() {
@@ -20047,16 +20058,27 @@ class AbstractNewCaseComponent {
20047
20058
  };
20048
20059
  this._caseResourceService.createCase(newCase)
20049
20060
  .subscribe((response) => {
20050
- this._snackBarService.openSuccessSnackBar(response.outcome.message === undefined
20051
- ? this._translate.instant('side-menu.new-case.createCase') + ' ' + newCase.title
20052
- : response.outcome.message);
20053
- this._sideMenuControl.close({
20054
- opened: false,
20055
- message: response.outcome.message === undefined
20056
- ? 'Confirm new case setup'
20057
- : response.outcome.message,
20058
- data: response.outcome.aCase
20059
- });
20061
+ if (!!response.outcome) {
20062
+ this._snackBarService.openSuccessSnackBar(response.outcome.message === undefined
20063
+ ? this._translate.instant('side-menu.new-case.createCase') + ' ' + newCase.title
20064
+ : response.outcome.message);
20065
+ this._sideMenuControl.close({
20066
+ opened: false,
20067
+ message: response.outcome.message === undefined
20068
+ ? 'Confirm new case setup'
20069
+ : response.outcome.message,
20070
+ data: response.outcome.aCase
20071
+ });
20072
+ }
20073
+ else if (!!response.error) {
20074
+ this._snackBarService.openWarningSnackBar(this._translate.instant('side-menu.new-case.createCaseError') + ' ' + newCase.title);
20075
+ this._sideMenuControl.close({
20076
+ opened: false,
20077
+ message: response.error === undefined
20078
+ ? 'Confirm new case setup'
20079
+ : response.error
20080
+ });
20081
+ }
20060
20082
  }, error => this._snackBarService.openErrorSnackBar(error.message ? error.message : error));
20061
20083
  }
20062
20084
  }
@@ -23410,16 +23432,35 @@ class RoleGuardService {
23410
23432
  return this.canAccessView(view, state.url.toString());
23411
23433
  }
23412
23434
  canAccessView(view, url) {
23413
- if (typeof view.access !== 'string' && view.access.hasOwnProperty('role')) {
23414
- const allowedRoles = this.parseRoleConstraints(view.access.role, url);
23415
- return allowedRoles.some(constraint => {
23416
- if (constraint.roleIdentifier) {
23417
- return this._userService.hasRoleByIdentifier(constraint.roleIdentifier, constraint.processIdentifier);
23435
+ if (typeof view.access !== 'string' && (view.access.hasOwnProperty('role') || view.access.hasOwnProperty('bannedRole'))) {
23436
+ if (view.access.hasOwnProperty('role') && view.access.hasOwnProperty('bannedRole')) {
23437
+ const bannedRoles = this.parseRoleConstraints(view.access.bannedRole, url);
23438
+ const allowedRoles = this.parseRoleConstraints(view.access.role, url);
23439
+ if (bannedRoles.some(role => this.decideAccessByRole(role))) {
23440
+ return false;
23418
23441
  }
23419
- else {
23420
- return this._userService.hasRoleByName(constraint.roleName, constraint.processIdentifier);
23442
+ if (allowedRoles.length === 0) {
23443
+ this._log.warn(`View at '${url}' defines role access constraint with an empty array!`
23444
+ + ` No users will be allowed to enter this view!`);
23421
23445
  }
23422
- });
23446
+ return allowedRoles.some(role => this.decideAccessByRole(role)); // user was not denied access by a banned role, they need at least one allowed role
23447
+ }
23448
+ if (view.access.hasOwnProperty('bannedRole')) {
23449
+ const bannedRoles = this.parseRoleConstraints(view.access.bannedRole, url);
23450
+ return !bannedRoles.some(constraint => {
23451
+ return this.decideAccessByRole(constraint);
23452
+ });
23453
+ }
23454
+ if (view.access.hasOwnProperty('role')) {
23455
+ const allowedRoles = this.parseRoleConstraints(view.access.role, url);
23456
+ if (allowedRoles.length === 0) {
23457
+ this._log.warn(`View at '${url}' defines role access constraint with an empty array!`
23458
+ + ` No users will be allowed to enter this view!`);
23459
+ }
23460
+ return allowedRoles.some(constraint => {
23461
+ return this.decideAccessByRole(constraint);
23462
+ });
23463
+ }
23423
23464
  }
23424
23465
  throw new Error('Role guard is declared for a view with no role guard configuration!'
23425
23466
  + ` Add role guard configuration for view at ${url}, or remove the guard.`);
@@ -23430,8 +23471,6 @@ class RoleGuardService {
23430
23471
  }
23431
23472
  if (Array.isArray(roleConstrains)) {
23432
23473
  if (roleConstrains.length === 0) {
23433
- this._log.warn(`View at '${viewUrl}' defines role access constraint with an empty array!`
23434
- + ` No users will be allowed to enter this view!`);
23435
23474
  return [];
23436
23475
  }
23437
23476
  if (typeof roleConstrains[0] === 'string') {
@@ -23469,6 +23508,14 @@ class RoleGuardService {
23469
23508
  return { processIdentifier: constraint.processId, roleIdentifier: constraint.roleId };
23470
23509
  });
23471
23510
  }
23511
+ decideAccessByRole(constraint) {
23512
+ if (constraint.roleIdentifier) {
23513
+ return this._userService.hasRoleByIdentifier(constraint.roleIdentifier, constraint.processIdentifier);
23514
+ }
23515
+ else {
23516
+ return this._userService.hasRoleByName(constraint.roleName, constraint.processIdentifier);
23517
+ }
23518
+ }
23472
23519
  }
23473
23520
  RoleGuardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleGuardService, deps: [{ token: RedirectService }, { token: UserService }, { token: ConfigurationService }, { token: LoggerService }], target: i0.ɵɵFactoryTarget.Injectable });
23474
23521
  RoleGuardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleGuardService, providedIn: AuthenticationModule });
@@ -23676,7 +23723,7 @@ class AccessService {
23676
23723
  * @returns whether the user passes the role guard condition for accessing the specified view
23677
23724
  */
23678
23725
  passesRoleGuard(view, url) {
23679
- return !view.access.hasOwnProperty('role') || this._roleGuard.canAccessView(view, url);
23726
+ return (!view.access.hasOwnProperty('role') && !view.access.hasOwnProperty('bannedRole')) || this._roleGuard.canAccessView(view, url);
23680
23727
  }
23681
23728
  /**
23682
23729
  * @param view the view whose access permissions we want to check
@@ -25146,15 +25193,18 @@ class AbstractNavigationDoubleDrawerComponent {
25146
25193
  id: filter.stringId,
25147
25194
  resource: filter
25148
25195
  };
25149
- const resolvedRoles = this.resolveAccessRoles(filter);
25196
+ const resolvedRoles = this.resolveAccessRoles(filter, 'allowed_roles');
25197
+ const resolvedBannedRoles = this.resolveAccessRoles(filter, 'banned_roles');
25150
25198
  if (!!resolvedRoles)
25151
25199
  item.access['role'] = resolvedRoles;
25200
+ if (!!resolvedBannedRoles)
25201
+ item.access['bannedRole'] = resolvedBannedRoles;
25152
25202
  if (!this._accessService.canAccessView(item, item.routingPath))
25153
25203
  return;
25154
25204
  return item;
25155
25205
  }
25156
- resolveAccessRoles(filter) {
25157
- const allowedRoles = filter.immediateData.find(f => f.stringId === 'allowed_roles')?.options;
25206
+ resolveAccessRoles(filter, roleType) {
25207
+ const allowedRoles = filter.immediateData.find(f => f.stringId === roleType)?.options;
25158
25208
  if (!allowedRoles || Object.keys(allowedRoles).length === 0)
25159
25209
  return undefined;
25160
25210
  const roles = [];
@@ -28426,7 +28476,7 @@ class AbstractSearchOperandInputComponent {
28426
28476
  }
28427
28477
  return this._filteredOptions$;
28428
28478
  }
28429
- get isInputFilled() {
28479
+ isInputFilled() {
28430
28480
  if (!this._inputConfirmed) {
28431
28481
  return false;
28432
28482
  }
@@ -28439,7 +28489,7 @@ class AbstractSearchOperandInputComponent {
28439
28489
  return;
28440
28490
  }
28441
28491
  this._initialExpansion = false;
28442
- if (!this.isInputFilled) {
28492
+ if (!this.isInputFilled()) {
28443
28493
  setTimeout(() => {
28444
28494
  input.nativeElement.focus();
28445
28495
  });
@@ -31559,8 +31609,7 @@ class AbstractFieldComponentResolverComponent {
31559
31609
  return this.gridElement.item;
31560
31610
  }
31561
31611
  getTaskId() {
31562
- const referencedTaskId = this.taskContentService.getReferencedFieldTask(this.getDataField().stringId);
31563
- return referencedTaskId ?? this.taskContentService.task.stringId;
31612
+ return this.taskContentService.task.stringId;
31564
31613
  }
31565
31614
  isField() {
31566
31615
  return this.gridElement.type !== TaskElementType.BLANK && this.gridElement.type !== TaskElementType.DATA_GROUP_TITLE;