diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3802e9e3e0..f485bad4f4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -63,7 +63,16 @@ You can now safely **delete all between two horizontal lines**, so the instructi ### Test Configuration - + + +| Name | Tested on | +|---------------------| --------- | +| OS | | +| Runtime | | +| Dependency Manager | | +| Framework version | | +| Run parameters | | +| Other configuration | | # Checklist: diff --git a/.github/config.yml b/.github/config.yml index bc8ebeccfd..1066a73d6f 100644 --- a/.github/config.yml +++ b/.github/config.yml @@ -1,4 +1,4 @@ PR_TITLE_REGEX: /(?:\[[A-Z]+-[0-9]+\] .+)|(?:Release [0-9]\.[0-9]\.[0-9](?:-[A-Za-z]+\.[0-9]+)?)/gi -COMMIT_MESSAGE_REGEX: /\[[A-Z]+-[0-9]+\] .+(?:\n\r? - .*)*/gim +COMMIT_MESSAGE_REGEX: /((^| )(\[[A-Z]+-[0-9]+\] .+(?:\n\r? - .*)*|(Merge branch .*. into*.*))|((Release .*)+(:?\n\r? .*)*)|(CI - Update documentation))/gim INVALID_COMMIT_MESSAGE: Commit messages are invalid. Valid format is -> [JIRA-ISSUE-KEY] Main change in the commit \n - other change in the commit -INVALID_PULL_REQUEST_MESSAGE: Pull request title is invalid -> [JIRA-ISSUE-KEY] Jira issue summary / title \ No newline at end of file +INVALID_PULL_REQUEST_MESSAGE: Pull request title is invalid -> [JIRA-ISSUE-KEY] Jira issue summary / title diff --git a/.github/workflows/master-build.yml b/.github/workflows/master-build.yml index 427bff2577..32f2714ebc 100644 --- a/.github/workflows/master-build.yml +++ b/.github/workflows/master-build.yml @@ -37,7 +37,7 @@ jobs: default_author: github_actions committer_name: Netgrif DevOps committer_email: devops@netgrif.com - message: 'Update documentation' + message: 'CI - Update documentation' diff --git a/CHANGELOG.md b/CHANGELOG.md index bbaf2452d5..8f227b6a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,28 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Full Changelog: [https://github.com/netgrif/components/commits/v6.0.0](https://github.com/netgrif/components/commits/v6.0.0) -## [6.0.1](https://github.com/netgrif/components/releases/tag/v6.0.0) (2022-02-15) +## [6.0.2](https://github.com/netgrif/components/releases/tag/v6.0.2) (2022-03-04) + +### Fixed + +- [NAE-1389] Immediate map data fields display their keys +- [NAE-1455] Navigation menu closes on small screens and cannot be reopened +- [NAE-1472] MaterialAppearance property on AbstractDataField +- [NAE-1524] Header search by author is not working +- [NAE-1529] Finish auto does not work +- [NAE-1557] Cannot clear optional enumeration +- [NAE-1574] Net role permission checking +- [NAE-1575] User select component trying open non-existing side menu component +- [NAE-1577] Task reffed change behavior does not propagate +- [NAE-1580] Grammar check +- [NAE-1583] Broken FileField/FileListField placeholder +- [NAE-1586] Virtual scroll is broken everywhere on page + +### Changed + +- [NAE-1459] Loading indicator on login and registration related components + +## [6.0.1](https://github.com/netgrif/components/releases/tag/v6.0.1) (2022-02-15) - Fixing mistake with npm registry @@ -508,7 +529,6 @@ None - [NAE-984] Destroy subscription on changedFields - ## [4.1.1](https://github.com/netgrif/components/releases/tag/4.1.1) (2020-08-20) ### Fixed diff --git a/README.md b/README.md index e909f2ccd0..d34d66aef6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=netgrif_components&metric=coverage)](https://sonarcloud.io/dashboard?id=netgrif_components) [![Known Vulnerabilities](https://snyk.io/test/github/netgrif/components/badge.svg)](https://snyk.io/test/github/netgrif/components) -Netgrif Components is an Angular library for creating SPA (Single-page application) compatible with Netgrif Application Engine. +Netgrif Components is an Angular library for creating SPA (Single-page application) compatible with [Netgrif Application Engine](https://github.com/netgrif/application-engine). The library provides all necessary tools for creating refined frontend application into NAE environment, and to create own library of Angular web components to incorporate your own personal design to the platform. diff --git a/package.json b/package.json index b2c7db1642..328d46b211 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@netgrif/components-project", - "version": "6.0.1", + "version": "6.0.2", "description": "Netgrif Application Engine Frontend project. Project includes angular libraries as base for NAE applications.", "homepage": "https://components.netgrif.com", "license": "SEE LICENSE IN LICENSE", @@ -33,6 +33,7 @@ "lint": "ng lint", "e2e": "ng e2e", "ncc:build": "ng build netgrif-components-core --prod && npm run ncc:build-schematics", + "ncc:local-build": "npm run ncc:build && npm i ./dist/netgrif-components-core --save-optional", "ncc:build-schematics": "node projects/netgrif-components-core/src/scripts/build-schematics.js", "ncc:lint": "ng lint netgrif-components-core", "ncc:spell": "cspell \"{projects/netgrif-components-core/**/*.md,projects/netgrif-components-core/src/**/*.ts}\"", @@ -55,7 +56,7 @@ "nc:typedoc": "typedoc --tsconfig projects/netgrif-components/tsconfig.lib.json projects/netgrif-components/src/public-api.ts", "nc:compodoc": "compodoc -c projects/netgrif-components/.compodocrc.json", "nc:doc": "npm run nc:compodoc && npm run nc:typedoc", - "project:local-build": "cd projects/netgrif-components-core && npm run ncc:build && cd ../netgrif-components && npm run nc:local-build", + "project:local-build": "npm run ncc:local-build && npm run nc:local-build", "project:full-test": "npm run ncc:full-test && npm run ncc:build && npm run nc:full-test", "project:start": "npm run project:local-build && ng serve", "project:sonar": "node scripts/sonar-scanner-analysis.js", diff --git a/projects/nae-example-app/src/app/doc/forms/email-form/password-form.component.ts b/projects/nae-example-app/src/app/doc/forms/email-form/password-form.component.ts index 12cf1df176..c1f7a47486 100644 --- a/projects/nae-example-app/src/app/doc/forms/email-form/password-form.component.ts +++ b/projects/nae-example-app/src/app/doc/forms/email-form/password-form.component.ts @@ -1,6 +1,13 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnDestroy, OnInit} from '@angular/core'; import {FormControl} from '@angular/forms'; -import {FormSubmitEvent, LoggerService, MessageResource, SignUpService, SnackBarService} from '@netgrif/components-core'; +import { + FormSubmitEvent, + LoadingEmitter, + LoggerService, + MessageResource, + SignUpService, + SnackBarService +} from '@netgrif/components-core'; import {Observable} from 'rxjs'; interface EndpointOption { @@ -13,13 +20,15 @@ interface EndpointOption { templateUrl: './password-form.component.html', styleUrls: ['./password-form.component.scss'] }) -export class PasswordFormComponent implements OnInit { +export class PasswordFormComponent implements OnInit, OnDestroy { readonly TITLE = 'Email submission form'; readonly DESCRIPTION = 'Ukážka email submission form...'; public endpointFormControl: FormControl; + public loading: LoadingEmitter; + public endpointOptions: Array = [ {value: 'signup', viewValue: 'Sign up'}, {value: 'forgotten', viewValue: 'Forgotten password'} @@ -27,12 +36,18 @@ export class PasswordFormComponent implements OnInit { constructor(protected _signUpService: SignUpService, protected _snackBarService: SnackBarService, protected _log: LoggerService) { this.endpointFormControl = new FormControl(this.endpointOptions[0].value); + this.loading = new LoadingEmitter(); } ngOnInit(): void { } + ngOnDestroy(): void { + this.loading.complete(); + } + callEndpoint(event: FormSubmitEvent): void { + event.loading.on(); let endpoint: Observable; if (this.endpointFormControl.value === 'signup') { endpoint = this._signUpService.invite({email: event.email, groups: [], processRoles: []}); @@ -47,6 +62,7 @@ export class PasswordFormComponent implements OnInit { } else { this._snackBarService.openSuccessSnackBar('Request success'); } + event.loading.off(); }); } } diff --git a/projects/netgrif-components-core/package.json b/projects/netgrif-components-core/package.json index 4f6452cb1a..310554aa09 100644 --- a/projects/netgrif-components-core/package.json +++ b/projects/netgrif-components-core/package.json @@ -1,6 +1,6 @@ { "name": "@netgrif/components-core", - "version": "6.0.1", + "version": "6.0.2", "description": "Netgrif Application engine frontend core Angular library", "homepage": "https://components.netgrif.com", "license": "SEE LICENSE IN LICENSE", diff --git a/projects/netgrif-components-core/src/assets/i18n/de.json b/projects/netgrif-components-core/src/assets/i18n/de.json index 9622016d0c..4a34debd69 100644 --- a/projects/netgrif-components-core/src/assets/i18n/de.json +++ b/projects/netgrif-components-core/src/assets/i18n/de.json @@ -242,6 +242,9 @@ }, "dynamicEnum": { "noData": "Keine Einträge entsprechen Ihrer Suchanfrage" + }, + "enum": { + "reset": "Rücksetzen" } }, "dialog": { diff --git a/projects/netgrif-components-core/src/assets/i18n/en.json b/projects/netgrif-components-core/src/assets/i18n/en.json index 045b17e4be..7d0f56516c 100644 --- a/projects/netgrif-components-core/src/assets/i18n/en.json +++ b/projects/netgrif-components-core/src/assets/i18n/en.json @@ -242,6 +242,9 @@ }, "dynamicEnum": { "noData": "No items match your search" + }, + "enum": { + "reset": "Reset" } }, "dialog": { diff --git a/projects/netgrif-components-core/src/assets/i18n/sk.json b/projects/netgrif-components-core/src/assets/i18n/sk.json index f36a9245d5..6146b4f3bb 100644 --- a/projects/netgrif-components-core/src/assets/i18n/sk.json +++ b/projects/netgrif-components-core/src/assets/i18n/sk.json @@ -32,7 +32,7 @@ "caseGetFailed": "Načítanie prípadov zlyhalo", "noLongerExists": "Zvolená úloha už neexistuje", "caseDeleteFailed": "Prípad sa nepodarilo vymazať", - "caseDeleteSuccess": "Prípad úspešný zmazaný", + "caseDeleteSuccess": "Prípad bol úspešne zmazaný", "rolesSuccessAssign": "Roly boli úspešne priradené vybraným používateľom" }, "view": { @@ -78,13 +78,13 @@ "errSecond": "Názov je povinné pole.", "errThird": "Farba je povinné pole.", "noNets": "Žiadne povolené siete", - "createCase": "Uspešne vytvorený nový prípad", + "createCase": "Úspešne vytvorený nový prípad", "defaultCaseName": "s prednastaveným názvom prípadu" }, "user": { "assign": "Priradiť používateľa", "choose": "Zvoľte používateľa", - "noUser": "Neexistujú žiadny používatelia", + "noUser": "Neexistujú žiadni používatelia", "err": "Nepodarilo sa načítať používateľov", "showcase": "Nebol zvolený mód zobrazenia používateľa!" }, @@ -196,7 +196,7 @@ "validations": { "required": "Toto pole je potrebné!", "requiredTrue": "Zadaná hodnota musí byť true", - "odd": "Zadané čislo musí byť nepárne", + "odd": "Zadané číslo musí byť nepárne", "even": "Zadané číslo musí byť párne", "positive": "Zadané číslo musí byť kladné", "negative": "Zadané číslo musí byť záporné", @@ -207,22 +207,22 @@ "pattern": "Zadaný text je v nesprávnom formáte", "phone": "Zadaný text musí byť tel. číslo", "email": "Zadaný text musí byť email", - "dateRange": "Zadaný dátum musí byť z rozsahu {{left}} a {{right}}", + "dateRange": "Zadaný dátum musí byť v rozsahu {{left}} a {{right}}", "weekend": "Zadaný dátum musí byť víkendový deň", "workday": "Zadaný dátum musí byť pracovný deň", "enumeration": "Musí byť vybraná jedna z možností", "min": "Zadané číslo musí byť väčšie ako {{length}}" }, "snackBar": { - "downloadFail": " stahovanie zlyhalo", - "moreFiles": "Zvolil si viac súborov ako je povolené", - "sameFiles": "Nemôžeš nahrať dva rovnaké súbory", + "downloadFail": " sťahovanie zlyhalo", + "moreFiles": "Zvolili ste si viac súborov ako je povolené", + "sameFiles": "Nemôžete nahrať dva rovnaké súbory", "fileSize": "Veľkosť súboru presiahla povolený limit", - "wontUploadSameFile": "Súbor už existuje. Ak chcete súbor aktualizovať zvoľte iný názov súboru alebo súbor odstránte", - "wontUploadSameFiles": "Vybrané súbory už boli nahrané. Ak chcete súbory aktualizovať odstránte už nahrané súbory", + "wontUploadSameFile": "Súbor už existuje. Ak chcete súbor aktualizovať, zvoľte iný názov súboru alebo súbor odstráňte", + "wontUploadSameFiles": "Vybrané súbory už boli nahrané. Ak chcete súbory aktualizovať, odstráňte už nahrané súbory", "fileUploadFailed": "Súbor sa nepodarilo nahrať", "fileDeleteFailed": "Súbor sa nepodarilo vymazať", - "maxFilesExceeded": "Je presiahnutý maximálny počet nahrateľných súborov: ", + "maxFilesExceeded": "Je presiahnutý maximálny počet nahratých súborov: ", "maxFilesSizeExceeded": "Je presiahnutá maximálna veľkosť nahrávaných súborov: ", "notSelectedUser": "Nebol vybraný žiadny používateľ", "userAssigned": "Používateľ {{userName}} bol pridelený" @@ -242,6 +242,9 @@ }, "dynamicEnum": { "noData": "Vášmu vyhľadávaniu nezodpovedajú žiadne položky" + }, + "enum": { + "reset": "Resetovať" } }, "dialog": { @@ -345,7 +348,7 @@ }, "admin": { "user-list": { - "noUsersWereFound": "Momentálne nie sú v systéme žiadny používatelia", + "noUsersWereFound": "Momentálne nie sú v systéme žiadni používatelia", "listTitle": "Používatelia" }, "process-list": { @@ -359,14 +362,14 @@ "newUser": "Nový používateľ", "orgs": "Organizácie", "selectedOrgs": "Vybrané Organizácie", - "selectedRoless": "Vybrané Role", + "selectedRoless": "Vybrané Roly", "mail": "Zadajte Email", - "noSelectedOrgs": "Nie su zvolené žiadne organizácie!", - "noSelectedRoles": "Nie su zvolené žiadne role!", + "noSelectedOrgs": "Nie sú zvolené žiadne organizácie!", + "noSelectedRoles": "Nie sú zvolené žiadne role!", "noOrgs": "Nie sú žiadne dostupné organizácie!", "version": "Verzia", "emailFieldMandatory": "Email je povinný", - "oneOrMoreOrganization": "Nový používateľ musí patriť aspoň do jenej organizácie", + "oneOrMoreOrganization": "Nový používateľ musí patriť aspoň do jednej organizácie", "inviteSent": "Pozvánka bola odoslaná", "inviteFailed": "Poslanie pozvánky zlyhalo", "invite-user": "POZVAŤ POUŽÍVATEĽA" @@ -380,7 +383,7 @@ }, "caseTree": { "newNodeDefaultName": "Nový Vrchol", - "noTaskSelected": "Momentálne nie je zvolený žiaden prípad. Pre vybranie prípadu zvoľte vrchol v strome." + "noTaskSelected": "Momentálne nie je zvolený žiadny prípad. Pre vybranie prípadu zvoľte vrchol v strome." }, "dashboard": { "cases": "prípady" diff --git a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.spec.ts b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.spec.ts index f803caf771..9fd36aed67 100644 --- a/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.spec.ts +++ b/projects/netgrif-components-core/src/lib/authorization/permission/permission.service.spec.ts @@ -212,7 +212,7 @@ describe('PermissionService', () => { {stringId: 'date', title: 'string', type: 'date', value: [2020, 1, 1, 10, 10]}, {stringId: 'string', title: 'string', type: 'string', value: 'dasdsadsad'}, {stringId: 'dateTime', title: 'string', type: 'dateTime', value: [2020, 1, 1, 10, 10]}, - {stringId: 'enum', title: 'string', type: 'enumeration', value: { defaultValue: 'dasd'}}, + {stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd'}}, ] }; expect(permissionService.hasCasePermission(case_, PermissionType.DELETE)).toBeTrue(); @@ -251,14 +251,14 @@ describe('PermissionService', () => { {stringId: 'date', title: 'string', type: 'date', value: [2020, 1, 1, 10, 10]}, {stringId: 'string', title: 'string', type: 'string', value: 'dasdsadsad'}, {stringId: 'dateTime', title: 'string', type: 'dateTime', value: [2020, 1, 1, 10, 10]}, - {stringId: 'enum', title: 'string', type: 'enumeration', value: { defaultValue: 'dasd'}}, + {stringId: 'enum', title: 'string', type: 'enumeration', value: {defaultValue: 'dasd'}}, ] }; expect(permissionService.hasCasePermission(case_, PermissionType.DELEGATE)).toBeFalse(); }); - it('should test canDo', () => { - const net = new Net( { + it('should test hasNetPermission', () => { + const net = new Net({ identifier: '', stringId: '', immediateData: [], @@ -270,21 +270,24 @@ describe('PermissionService', () => { title: '' }); net.permissions = {}; - expect(permissionService.hasNetPermission('create', net)).toBeTrue(); + expect(permissionService.hasNetPermission(PermissionType.CREATE, net)).toBeFalse(); (userService as unknown as MockUserService).user = - new User('', '', '', '', [], [{stringId: '12454sdasd', name: '', importId: ''}]); - net.permissions = {'12454sdasd': {create: true}}; - expect(permissionService.hasNetPermission('create', net)).toBeTrue(); + new User('', '', '', '', [], [{stringId: 'role1', name: '', importId: ''}]); + net.permissions = {role1: {create: true}}; + expect(permissionService.hasNetPermission(PermissionType.CREATE, net)).toBeTrue(); - net.permissions = {'12454sdasd': {create: false}}; - expect(permissionService.hasNetPermission('create', net)).toBeFalse(); + net.permissions = {role1: {create: false}}; + expect(permissionService.hasNetPermission(PermissionType.CREATE, net)).toBeFalse(); + + net.permissions = {role1: {view: true}}; + expect(permissionService.hasNetPermission(PermissionType.CREATE, net)).toBeFalse(); (userService as unknown as MockUserService).user = new User('', '', '', '', [], - [{stringId: '12454sdasd', name: '', importId: ''}, {stringId: '12454sddasdasd', name: '', importId: ''}]); - net.permissions = {'12454sdasd': {create: false}, '12454sddasdasd': {create: true}}; - expect(permissionService.hasNetPermission('create', net)).toBeFalse(); + [{stringId: 'role1', name: '', importId: ''}, {stringId: 'role2', name: '', importId: ''}]); + net.permissions = {role1: {create: false}, role2: {create: true}}; + expect(permissionService.hasNetPermission(PermissionType.CREATE, net)).toBeFalse(); }); 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 5ed6c87e54..bf2c91c338 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 @@ -51,11 +51,6 @@ export class PermissionService { this._userService.hasRoleById(role) ? net.permissions[role][action] === false : false)) { return false; } - if (!Object.keys(net.permissions).filter(role => Object.keys(net.permissions[role]) - .some(perm => perm === action)).some(role => - !!net.permissions[role][action])) { - return true; - } return Object.keys(net.permissions).some(role => this._userService.hasRoleById(role) ? !!net.permissions[role][action] : false ); diff --git a/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/enumeration-list-field/abstract-enumeration-list-field.component.ts b/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/enumeration-list-field/abstract-enumeration-list-field.component.ts index 5e059e0661..6ba2158aba 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/enumeration-list-field/abstract-enumeration-list-field.component.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/enumeration-list-field/abstract-enumeration-list-field.component.ts @@ -11,4 +11,8 @@ export abstract class AbstractEnumerationListFieldComponent implements OnInit { ngOnInit() { } + + resetEnum(): void { + this.formControlRef.reset(); + } } diff --git a/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/models/enumeration-field.ts b/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/models/enumeration-field.ts index 833832984a..ed2b28bce8 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/models/enumeration-field.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/enumeration-field/models/enumeration-field.ts @@ -71,7 +71,7 @@ export class EnumerationField extends DataField { if (this._choices === undefined || this._choices.length === 0 || control.value === '' || control.value === undefined) { return null; } - return this._choices.find(choice => choice.key === control.value) ? null : {wrongValue: true}; + return this._choices.find(choice => choice.key === control.value || control.value === null) ? null : {wrongValue: true}; } getType(): string { diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-field/abstract-file-field.component.ts b/projects/netgrif-components-core/src/lib/data-fields/file-field/abstract-file-field.component.ts index 0ea2ab83ea..efe82eb37a 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/file-field/abstract-file-field.component.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/file-field/abstract-file-field.component.ts @@ -348,7 +348,14 @@ export abstract class AbstractFileFieldComponent extends AbstractDataFieldCompon * Construct display name. */ public constructDisplayName(): string { - return this.dataField?.value?.name ?? (this.dataField?.placeholder ?? this._translate.instant('dataField.file.noFile')); + if (!!this.dataField) { + if (!!this.dataField.value && !!this.dataField.value.name) { + return this.dataField.value.name; + } else if (!!this.dataField.placeholder) { + return this.dataField.placeholder; + } + } + return this._translate.instant('dataField.file.noFile'); } /** diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/abstract-file-list-field.component.ts b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/abstract-file-list-field.component.ts index b65a4a2d68..fdb516286a 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/abstract-file-list-field.component.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/abstract-file-list-field.component.ts @@ -290,7 +290,10 @@ export abstract class AbstractFileListFieldComponent extends AbstractDataFieldCo * Construct display name. */ public constructDisplayName(): string { - return this.dataField?.placeholder ?? this._translate.instant('dataField.file.noFile'); + if (!!this.dataField && !!this.dataField.placeholder) { + return this.dataField.placeholder; + } + return this._translate.instant('dataField.file.noFile'); } protected parseResponse(): void { diff --git a/projects/netgrif-components-core/src/lib/data-fields/models/abstract-data-field.ts b/projects/netgrif-components-core/src/lib/data-fields/models/abstract-data-field.ts index e331a6cc0b..535aa03894 100644 --- a/projects/netgrif-components-core/src/lib/data-fields/models/abstract-data-field.ts +++ b/projects/netgrif-components-core/src/lib/data-fields/models/abstract-data-field.ts @@ -112,6 +112,11 @@ export abstract class DataField { */ protected _localLayout: Layout; + /** + * Listens for layout changes + */ + protected layoutSubject: BehaviorSubject; + /** * @param _stringId - ID of the data field from backend * @param _title - displayed title of the data field from backend @@ -139,6 +144,7 @@ export abstract class DataField { this._block = new Subject(); this._touch = new Subject(); this._validRequired = true; + this.layoutSubject = new BehaviorSubject(_layout); this.resetLocalLayout(); } @@ -215,6 +221,7 @@ export abstract class DataField { set layout(layout: Layout) { this._layout = layout; + this.layoutSubject.next(layout); } get layout(): Layout { @@ -323,6 +330,7 @@ export abstract class DataField { this._touch.complete(); this._block.complete(); this._initialized$.complete(); + this.layoutSubject.complete(); } public registerFormControl(formControl: FormControl): void { @@ -502,6 +510,13 @@ export abstract class DataField { } } this.materialAppearance = appearance; + + /* Listen for changes of layout in future */ + this.layoutSubject.subscribe(layout => { + if (this.layout && this.layout.appearance) { + this.materialAppearance = this.layout.appearance; + } + }); } public resolvePrevValue(value: T): void { diff --git a/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.spec.ts b/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.spec.ts index 7a9e3a27af..fca3b3acbb 100644 --- a/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.spec.ts @@ -7,6 +7,7 @@ import {Component} from '@angular/core'; import {AbstractEmailSubmissionFormComponent} from './abstract-email-submission-form.component'; import {MaterialModule} from '../../material/material.module'; import {TranslateLibModule} from '../../translate/translate-lib.module'; +import {LoadingEmitter} from '../../utility/loading-emitter'; describe('AbstractEmailSubmissionFormComponent ', () => { let component: TestPassFormComponent; @@ -37,7 +38,7 @@ describe('AbstractEmailSubmissionFormComponent ', () => { it('should submit', (done) => { component.rootFormGroup.controls['email'].setValue('login@login.sk'); component.formSubmit.subscribe( event => { - expect(event).toEqual({ email: 'login@login.sk' }); + expect(event).toEqual({ email: 'login@login.sk', loading: new LoadingEmitter() }); done(); }); component.onSubmit(); diff --git a/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.ts b/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.ts index b8b3e9a61e..dd69b898c6 100644 --- a/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.ts +++ b/projects/netgrif-components-core/src/lib/forms/email-submission/abstract-email-submission-form.component.ts @@ -1,12 +1,14 @@ import {EventEmitter, Input, OnDestroy, Output} from '@angular/core'; import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {FormSubmitEvent, HasForm} from '../has-form'; +import {LoadingEmitter} from '../../utility/loading-emitter'; export abstract class AbstractEmailSubmissionFormComponent implements HasForm, OnDestroy { public rootFormGroup: FormGroup; @Input() public displayLegalNotice = true; + public loading = new LoadingEmitter(); @Output() public formSubmit: EventEmitter; @Output() public goBackButton: EventEmitter; @@ -22,6 +24,7 @@ export abstract class AbstractEmailSubmissionFormComponent implements HasForm, O ngOnDestroy(): void { this.formSubmit.complete(); this.goBackButton.complete(); + this.loading.complete(); } public emitGoBack() { @@ -32,6 +35,6 @@ export abstract class AbstractEmailSubmissionFormComponent implements HasForm, O if (!this.rootFormGroup.valid) { return; } - this.formSubmit.emit({email: this.rootFormGroup.controls['email'].value}); + this.formSubmit.emit({email: this.rootFormGroup.controls['email'].value, loading: this.loading}); } } diff --git a/projects/netgrif-components-core/src/lib/forms/models/abstract-registration.component.ts b/projects/netgrif-components-core/src/lib/forms/models/abstract-registration.component.ts index febdc5f875..0b66709c30 100644 --- a/projects/netgrif-components-core/src/lib/forms/models/abstract-registration.component.ts +++ b/projects/netgrif-components-core/src/lib/forms/models/abstract-registration.component.ts @@ -31,6 +31,7 @@ export abstract class AbstractRegistrationComponent implements HasForm, OnDestro private _token: string; private _tokenVerified: boolean; public loadingToken: LoadingEmitter; + public loadingSubmit: LoadingEmitter; public userEmail: string; protected constructor(protected _signupService: SignUpService, @@ -43,6 +44,7 @@ export abstract class AbstractRegistrationComponent implements HasForm, OnDestro this.invalidToken = new EventEmitter(); this._tokenVerified = false; this.loadingToken = new LoadingEmitter(true); + this.loadingSubmit = new LoadingEmitter(false); } ngOnDestroy(): void { @@ -50,6 +52,7 @@ export abstract class AbstractRegistrationComponent implements HasForm, OnDestro this.register.complete(); this.invalidToken.complete(); this.loadingToken.complete(); + this.loadingSubmit.complete(); } @Input() @@ -95,10 +98,13 @@ export abstract class AbstractRegistrationComponent implements HasForm, OnDestro return; } request.token = this._token; + this.loadingSubmit.on(); this.callRegistration(request).pipe(take(1)).subscribe(message => { this.register.emit(message); + this.loadingSubmit.off(); }, error => { this.register.emit({error}); + this.loadingSubmit.off(); }); } diff --git a/projects/netgrif-components-core/src/lib/header/case-header/case-header.service.ts b/projects/netgrif-components-core/src/lib/header/case-header/case-header.service.ts index 6e543a4d9d..739abfba9b 100644 --- a/projects/netgrif-components-core/src/lib/header/case-header/case-header.service.ts +++ b/projects/netgrif-components-core/src/lib/header/case-header/case-header.service.ts @@ -40,7 +40,7 @@ export class CaseHeaderService extends AbstractHeaderService implements OnDestro new HeaderColumn(HeaderColumnType.META, CaseMetaField.VISUAL_ID, 'headers.caseMeta.visualID', 'text'), new HeaderColumn(HeaderColumnType.META, CaseMetaField.MONGO_ID, 'headers.caseMeta.mongoID', 'text', false), new HeaderColumn(HeaderColumnType.META, CaseMetaField.TITLE, 'headers.caseMeta.title', 'text'), - new HeaderColumn(HeaderColumnType.META, CaseMetaField.AUTHOR, 'headers.caseMeta.author', 'text'), + new HeaderColumn(HeaderColumnType.META, CaseMetaField.AUTHOR, 'headers.caseMeta.author', 'user'), new HeaderColumn(HeaderColumnType.META, CaseMetaField.CREATION_DATE, 'headers.caseMeta.creationDate', 'date'), ]; } diff --git a/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.spec.ts b/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.spec.ts index d494053724..e6001ca602 100644 --- a/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.spec.ts +++ b/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.spec.ts @@ -70,15 +70,17 @@ describe('AbstractNavigationDrawerComponent', () => { }); }); - it('should close', async () => { - await component.close().then(res => { - expect(res).toEqual('open'); + it('should close', (done) => { + component.close().then(res => { + expect(res).toEqual('close'); + done(); }); }); - it('should toggle', async () => { - await component.toggle().then(res => { + it('should toggle', (done) => { + component.toggle().then(res => { expect(res).toEqual('open'); + done(); }); }); diff --git a/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.ts b/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.ts index c162bf52e7..160ddc8f50 100644 --- a/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.ts +++ b/projects/netgrif-components-core/src/lib/navigation/navigation-drawer/abstract-navigation-drawer.component.ts @@ -33,7 +33,7 @@ export abstract class AbstractNavigationDrawerComponent implements OnInit, After protected _config = { mode: 'over', - opened: false, + opened: true, disableClose: false }; @@ -95,15 +95,15 @@ export abstract class AbstractNavigationDrawerComponent implements OnInit, After } open(): Promise { - if (this._fixed) { - return Promise.resolve('open'); + if (!this._sideNav.opened) { + this._sideNav.open(); } - return this._sideNav.open(); + return Promise.resolve('open'); } close(): Promise { if (this._fixed) { - return Promise.resolve('open'); + return Promise.resolve('close'); } return this._sideNav.close(); } 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 db8edf13f1..1b9c87e689 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 @@ -28,6 +28,11 @@ export abstract class PanelWithImmediateData extends PanelWithHeaderBinding impl return {value: immediate.value.defaultValue, icon: undefined, type: immediate.type}; case 'multichoice': return {value: immediate.value.map(it => it.defaultValue).join(', '), icon: undefined, type: immediate.type}; + case 'enumeration_map': + return {value: immediate.options[immediate.value].defaultValue, icon: undefined, type: immediate.type}; + case 'multichoice_map': + return {value: immediate.value.map(it => + immediate.options[it].defaultValue).join(', '), icon: undefined, type: immediate.type}; case 'file': return {value: immediate.value?.name, icon: 'insert_drive_file', type: immediate.type}; case 'fileList': diff --git a/projects/netgrif-components-core/src/lib/resources/engine-endpoint/task-resource.service.ts b/projects/netgrif-components-core/src/lib/resources/engine-endpoint/task-resource.service.ts index 7e760e835b..60d0bca58b 100644 --- a/projects/netgrif-components-core/src/lib/resources/engine-endpoint/task-resource.service.ts +++ b/projects/netgrif-components-core/src/lib/resources/engine-endpoint/task-resource.service.ts @@ -229,6 +229,7 @@ export class TaskResourceService extends AbstractResourceService implements Coun }; if (dataGroupResource.parentTaskId !== undefined) { dataGroupObject.parentTaskId = dataGroupResource.parentTaskId; + dataGroupObject.parentTransitionId = dataGroupResource.parentTransitionId; dataGroupObject.parentTaskRefId = dataGroupResource.parentTaskRefId; dataGroupObject.nestingLevel = dataGroupResource.nestingLevel; } diff --git a/projects/netgrif-components-core/src/lib/resources/interface/data-groups.ts b/projects/netgrif-components-core/src/lib/resources/interface/data-groups.ts index 244ae89290..4955d41a62 100644 --- a/projects/netgrif-components-core/src/lib/resources/interface/data-groups.ts +++ b/projects/netgrif-components-core/src/lib/resources/interface/data-groups.ts @@ -29,6 +29,10 @@ export interface DataGroup { * String id of parent task, only set if dataGroup is loaded by {@link TaskRefField} */ parentTaskId?: string; + /** + * String id of parent task, only set if dataGroup is loaded by {@link TaskRefField} + */ + parentTransitionId?: string; /** * String id of parent case, only set if dataGroup is loaded by {@link TaskRefField} */ diff --git a/projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts b/projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts index 72f1beb74e..c207fcc1e9 100644 --- a/projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts +++ b/projects/netgrif-components-core/src/lib/resources/interface/immediate-data.ts @@ -44,4 +44,8 @@ export interface ImmediateData { */ // TODO Exists only in case immediate data name?: any; + /** + * Only for enumeration_map and multichoice_map + */ + options?: { defaultValue?: string }; } diff --git a/projects/netgrif-components-core/src/lib/search/models/category/no-configuration-user-autocomplete-category.ts b/projects/netgrif-components-core/src/lib/search/models/category/no-configuration-user-autocomplete-category.ts index 4c1f59dd17..d198ee019c 100644 --- a/projects/netgrif-components-core/src/lib/search/models/category/no-configuration-user-autocomplete-category.ts +++ b/projects/netgrif-components-core/src/lib/search/models/category/no-configuration-user-autocomplete-category.ts @@ -33,7 +33,7 @@ export abstract class NoConfigurationUserAutocompleteCategory extends NoConfigur if (this.selectedOperator.numberOfOperands !== 1) { throw new Error(`Only unary operators are currently supported by the ${this._className} implementation`); } - return this.selectedOperator.createQuery(this.elasticKeywords, userInput[0], false); + return this.selectedOperator.createQuery(this.elasticKeywords, Array.isArray(userInput[0]) ? userInput[0] : userInput, false); } protected serializeOperandValue(valueFormControl: FormControl): any { diff --git a/projects/netgrif-components-core/src/lib/side-menu/services/side-menu.service.ts b/projects/netgrif-components-core/src/lib/side-menu/services/side-menu.service.ts index 4f3ca47be2..a90ce13331 100644 --- a/projects/netgrif-components-core/src/lib/side-menu/services/side-menu.service.ts +++ b/projects/netgrif-components-core/src/lib/side-menu/services/side-menu.service.ts @@ -52,6 +52,9 @@ export class SideMenuService { public open(componentOrTemplateRef: ComponentType | TemplateRef, width: SideMenuSize = SideMenuSize.MEDIUM, injectionData?: SideMenuInjectionData): SideMenuRef { + if (!this.componentIsPresent()) { + throw new Error('Side menu is not initialized'); + } if (this._sideMenuComponent.isOpened()) { throw new Error('Side menu has been already opened with another content'); } @@ -105,4 +108,8 @@ export class SideMenuService { // public toggle(isOpen?: boolean): Observable { // return from(this._sideMenu.toggle(isOpen)); // } + + private componentIsPresent(): boolean { + return !!this._sideMenuComponent; + } } diff --git a/projects/netgrif-components-core/src/lib/task-content/model/task-fields.ts b/projects/netgrif-components-core/src/lib/task-content/model/task-fields.ts new file mode 100644 index 0000000000..c320e188e6 --- /dev/null +++ b/projects/netgrif-components-core/src/lib/task-content/model/task-fields.ts @@ -0,0 +1,8 @@ +import {DataField} from '../../data-fields/models/abstract-data-field'; + +export interface TaskFields { + transitionId: string; + fields: { + [fieldId: string]: DataField; + }; +} diff --git a/projects/netgrif-components-core/src/lib/task-content/public-api.ts b/projects/netgrif-components-core/src/lib/task-content/public-api.ts index 8b0445b53d..b5702e0231 100644 --- a/projects/netgrif-components-core/src/lib/task-content/public-api.ts +++ b/projects/netgrif-components-core/src/lib/task-content/public-api.ts @@ -16,6 +16,7 @@ export * from './model/async-rendering-configuration'; export * from './model/async-rendering-configuration-injection-token'; export * from './model/subgrid'; export * from './model/split-data-group'; +export * from './model/task-fields'; /* MODULES */ export * from './task-content/abstract-task-content.component'; diff --git a/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.spec.ts b/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.spec.ts index ad26bdc0b9..08a3b265c9 100644 --- a/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.spec.ts +++ b/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.spec.ts @@ -10,6 +10,7 @@ import {SingleTaskContentService} from './single-task-content.service'; import {createMockTask} from '../../utility/tests/utility/create-mock-task'; import {createMockDataGroup} from '../../utility/tests/utility/create-mock-datagroup'; import {createMockField} from '../../utility/tests/utility/create-mock-field'; +import {TaskFields} from '../model/task-fields'; describe('TaskPanelContentService', () => { const FIELD_ID = 'field1'; @@ -50,8 +51,8 @@ describe('TaskPanelContentService', () => { }; // normally task fields index is created during processing of getData response - service.taskFieldsIndex[mockTask.stringId] = {}; - service.taskFieldsIndex[mockTask.stringId][FIELD_ID] = mockTask.dataGroups[0].fields[0]; + service.taskFieldsIndex[mockTask.stringId] = {transitionId: mockTask.transitionId, fields: {}} as TaskFields; + service.taskFieldsIndex[mockTask.stringId].fields[FIELD_ID] = mockTask.dataGroups[0].fields[0]; service.task = mockTask; service.updateFromChangedFields({ diff --git a/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.ts b/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.ts index 5157330c69..3753e90986 100644 --- a/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.ts +++ b/projects/netgrif-components-core/src/lib/task-content/services/task-content.service.ts @@ -14,6 +14,7 @@ import {DynamicEnumerationField} from '../../data-fields/enumeration-field/model import {Validation} from '../../data-fields/models/validation'; import {TaskEventOutcome} from '../../event/model/event-outcomes/task-outcomes/task-event-outcome'; import {DataField} from '../../data-fields/models/abstract-data-field'; +import {TaskFields} from '../model/task-fields'; /** * Acts as a communication interface between the Component that renders Task content and it's parent Component. @@ -35,9 +36,7 @@ export abstract class TaskContentService implements OnDestroy { protected _taskDataReloadRequest$: Subject; protected _isExpanding$: BehaviorSubject; private _taskFieldsIndex: { - [taskId: string]: { - [fieldId: string]: DataField; - } + [taskId: string]: TaskFields } = {}; private _referencedTaskAndCaseIds: { [caseId: string]: Array } = {}; @@ -86,11 +85,11 @@ export abstract class TaskContentService implements OnDestroy { } - get taskFieldsIndex(): { [p: string]: { [p: string]: DataField } } { + get taskFieldsIndex(): { [p: string]: TaskFields } { return this._taskFieldsIndex; } - set taskFieldsIndex(value: { [p: string]: { [p: string]: DataField } }) { + set taskFieldsIndex(value: { [p: string]: TaskFields }) { this._taskFieldsIndex = value; } @@ -226,8 +225,14 @@ export abstract class TaskContentService implements OnDestroy { const frontendActions = chFields.taskId === this.task.stringId && chFields[TaskContentService.FRONTEND_ACTIONS_KEY]; Object.keys(chFields).forEach(changedField => { - if (!!this.taskFieldsIndex[chFields.taskId] && !!this.taskFieldsIndex[chFields.taskId][changedField]) { - this.updateField(chFields, this.taskFieldsIndex[chFields.taskId][changedField], frontendActions); + if (!!this.taskFieldsIndex[chFields.taskId] && !!this.taskFieldsIndex[chFields.taskId].fields + && !!this.taskFieldsIndex[chFields.taskId].fields[changedField]) { + this.updateField(chFields, this.taskFieldsIndex[chFields.taskId].fields[changedField], frontendActions); + } else if (this.isFieldInTaskRef(changedField)) { + const taskId = this.getReferencedTaskId(changedField); + if (!!taskId && !!this.taskFieldsIndex[taskId] && !!this.taskFieldsIndex[taskId].fields + && !!this.taskFieldsIndex[taskId].fields[changedField]) + this.updateReferencedField(chFields, this.taskFieldsIndex[taskId].fields[changedField], frontendActions); } }); @@ -255,8 +260,10 @@ export abstract class TaskContentService implements OnDestroy { // TODO NGSD-489 fix behavior resolution field.behavior = updatedField.behavior[this._task.transitionId]; } else { - // ignore the behavior update, since it does not affect this task - return; // continue - the field does not need updating, since nothing changed + const transitionId = this.getReferencedTransitionId(field.stringId); + if (!!transitionId && transitionId !== '' && updatedField.behavior[transitionId]) + field.behavior = updatedField.behavior[transitionId]; + break; } break; case 'choices': @@ -293,6 +300,26 @@ export abstract class TaskContentService implements OnDestroy { }); } + private updateReferencedField(chFields: ChangedFields, field: DataField, frontendActions: Change): void { + if (this._fieldConverterService.resolveType(field) === FieldTypeResource.TASK_REF) { + this._taskDataReloadRequest$.next(frontendActions ? frontendActions : undefined); + return; + } + const updatedField = chFields[field.stringId]; + Object.keys(updatedField).forEach(key => { + switch (key) { + case 'behavior': + const transitionId = this.getReferencedTransitionId(field.stringId); + if (!!transitionId && transitionId !== '' && updatedField.behavior[transitionId]) + field.behavior = updatedField.behavior[transitionId]; + break; + default: + field[key] = updatedField[key]; + } + field.update(); + }); + } + /** * Performs the specific frontend action. * @@ -307,4 +334,27 @@ export abstract class TaskContentService implements OnDestroy { timer().subscribe(() => this.validateTaskData()); } } + + private isFieldInTaskRef(changedField: string): boolean { + return !!this.taskFieldsIndex && + Object.keys(this.taskFieldsIndex) + .some(taskId => taskId !== this.task.stringId && this.taskFieldsIndex[taskId].fields[changedField]); + } + + private getReferencedTransitionId(changedField: string): string { + if (!!this.taskFieldsIndex) { + const taskFieldsIndexId = Object.keys(this.taskFieldsIndex).find(taskId => + Object.keys(this.taskFieldsIndex[taskId].fields).includes(changedField)); + return this.taskFieldsIndex[taskFieldsIndexId].transitionId; + } + return undefined; + } + + private getReferencedTaskId(changedField: string): string { + if (!!this.taskFieldsIndex) { + return Object.keys(this.taskFieldsIndex).find(taskId => + Object.keys(this.taskFieldsIndex[taskId].fields).includes(changedField)); + } + return undefined; + } } diff --git a/projects/netgrif-components-core/src/lib/task/services/assign-policy.service.ts b/projects/netgrif-components-core/src/lib/task/services/assign-policy.service.ts index 7f586f4c0c..7b5bb75574 100644 --- a/projects/netgrif-components-core/src/lib/task/services/assign-policy.service.ts +++ b/projects/netgrif-components-core/src/lib/task/services/assign-policy.service.ts @@ -122,7 +122,7 @@ export class AssignPolicyService extends TaskHandlingService { afterAction.next(false); afterAction.complete(); return; - } + } this._cancelTaskService.cancel( this._callchain.create((requestSuccess) => { this._taskOperations.close(); diff --git a/projects/netgrif-components-core/src/lib/task/services/finish-policy.service.ts b/projects/netgrif-components-core/src/lib/task/services/finish-policy.service.ts index 26fdd5f452..118455049c 100644 --- a/projects/netgrif-components-core/src/lib/task/services/finish-policy.service.ts +++ b/projects/netgrif-components-core/src/lib/task/services/finish-policy.service.ts @@ -45,7 +45,6 @@ export class FinishPolicyService extends TaskHandlingService { protected autoNoDataFinishPolicy(afterAction: AfterAction): void { if (this._safeTask.dataSize <= 0) { this._finishTaskService.validateDataAndFinish(afterAction); - this._taskOperations.close(); } else { this._taskOperations.open(); this._dataFocusPolicyService.performDataFocusPolicy(); diff --git a/projects/netgrif-components-core/src/lib/task/services/task-data.service.ts b/projects/netgrif-components-core/src/lib/task/services/task-data.service.ts index 9dbb30237e..bbd3cc76e7 100644 --- a/projects/netgrif-components-core/src/lib/task/services/task-data.service.ts +++ b/projects/netgrif-components-core/src/lib/task/services/task-data.service.ts @@ -34,6 +34,7 @@ import {EventService} from '../../event/services/event.service'; import {EventOutcome} from '../../resources/interface/event-outcome'; import {ChangedFieldsService} from '../../changed-fields/services/changed-fields.service'; import {ChangedFieldsMap} from '../../event/services/interfaces/changed-fields-map'; +import {TaskFields} from '../../task-content/model/task-fields'; /** * Handles the loading and updating of data fields and behaviour of @@ -176,6 +177,8 @@ export class TaskDataService extends TaskHandlingService implements OnDestroy { dataGroups.forEach(group => { const dataGroupParentCaseId: string = group.parentCaseId === undefined ? this._safeTask.caseId : group.parentCaseId; const parentTaskId: string = group.parentTaskId === undefined ? this._safeTask.stringId : group.parentTaskId; + const parentTransitionId: string = group.parentTransitionId === undefined ? + this._safeTask.transitionId : group.parentTransitionId; if (dataGroupParentCaseId !== this._safeTask.caseId) { if (!this._taskContentService.referencedTaskAndCaseIds[dataGroupParentCaseId]) { this._taskContentService.referencedTaskAndCaseIds[dataGroupParentCaseId] = [group.parentTaskId]; @@ -188,10 +191,14 @@ export class TaskDataService extends TaskHandlingService implements OnDestroy { this._taskContentService.referencedTaskAndCaseIds[dataGroupParentCaseId].push(group.parentTaskId); } if (group.fields.length > 0 && !this._taskContentService.taskFieldsIndex[parentTaskId]) { - this._taskContentService.taskFieldsIndex[parentTaskId] = {}; + this._taskContentService.taskFieldsIndex[parentTaskId] = {} as TaskFields; + } + if (group.fields.length > 0 && !this._taskContentService.taskFieldsIndex[parentTaskId].fields) { + this._taskContentService.taskFieldsIndex[parentTaskId].fields = {}; } group.fields.forEach(field => { - this._taskContentService.taskFieldsIndex[parentTaskId][field.stringId] = field; + this._taskContentService.taskFieldsIndex[parentTaskId].transitionId = parentTransitionId; + this._taskContentService.taskFieldsIndex[parentTaskId].fields[field.stringId] = field; field.valueChanges().subscribe(() => { if (this.wasFieldUpdated(field)) { if (field instanceof DynamicEnumerationField) { @@ -368,7 +375,7 @@ export class TaskDataService extends TaskHandlingService implements OnDestroy { } const fieldIdsOfRequest = Object.keys(request[taskId]); for (const fieldId of fieldIdsOfRequest) { - const field = this._taskContentService.taskFieldsIndex[taskId][fieldId]; + const field = this._taskContentService.taskFieldsIndex[taskId].fields[fieldId]; if (field === undefined) { this._log.error(`Unexpected state. Datafield ${fieldId} of task ${taskId } in setData request is not present in the task.`); @@ -573,7 +580,7 @@ export class TaskDataService extends TaskHandlingService implements OnDestroy { private clearWaitingForResponseFlag(body: TaskSetDataRequestBody) { Object.keys(body).forEach(taskId => { Object.keys(body[taskId]).forEach(fieldId => { - this._taskContentService.taskFieldsIndex[taskId][fieldId].waitingForResponse = false; + this._taskContentService.taskFieldsIndex[taskId].fields[fieldId].waitingForResponse = false; }); }); } diff --git a/projects/netgrif-components/package.json b/projects/netgrif-components/package.json index 66b68ce31d..32a94f25ea 100644 --- a/projects/netgrif-components/package.json +++ b/projects/netgrif-components/package.json @@ -1,6 +1,6 @@ { "name": "@netgrif/components", - "version": "6.0.1", + "version": "6.0.2", "description": "Netgrif Application Engine frontend Angular components", "homepage": "https://components.netgrif.com", "license": "SEE LICENSE IN LICENSE", @@ -28,7 +28,7 @@ "nae frontend" ], "peerDependencies": { - "@netgrif/components-core": "6.0.1", + "@netgrif/components-core": "6.0.2", "@angular-material-components/datetime-picker": "^2.0.2", "@angular-material-components/moment-adapter": "^2.0.1", "@angular/animations": "^9.1.12", diff --git a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-dynamic-field/enumeration-autocomplete-dynamic-field.component.html b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-dynamic-field/enumeration-autocomplete-dynamic-field.component.html index 363ecdbfc4..d2b2f7c71b 100644 --- a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-dynamic-field/enumeration-autocomplete-dynamic-field.component.html +++ b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-dynamic-field/enumeration-autocomplete-dynamic-field.component.html @@ -16,6 +16,7 @@ + --- {{option.value}} diff --git a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-select-field/enumeration-autocomplete-select-field.component.html b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-select-field/enumeration-autocomplete-select-field.component.html index d41dc1346f..6c5b472114 100644 --- a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-select-field/enumeration-autocomplete-select-field.component.html +++ b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-autocomplete-select-field/enumeration-autocomplete-select-field.component.html @@ -9,6 +9,7 @@ [matAutocomplete]="auto" (keyup)="change()"> + --- {{option.value}} diff --git a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-list-field/enumeration-list-field.component.html b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-list-field/enumeration-list-field.component.html index 5385e058d1..ef7b57d35e 100644 --- a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-list-field/enumeration-list-field.component.html +++ b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-list-field/enumeration-list-field.component.html @@ -6,6 +6,7 @@ [formControl]="formControlRef"> {{enumerationField.title}} +
{{option.value}} diff --git a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-select-field/enumeration-select-field.component.html b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-select-field/enumeration-select-field.component.html index 0dee27dd44..ae46244e75 100644 --- a/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-select-field/enumeration-select-field.component.html +++ b/projects/netgrif-components/src/lib/data-fields/enumeration-field/enumeration-select-field/enumeration-select-field.component.html @@ -2,6 +2,7 @@ {{enumerationField.title}} + --- {{option.value}} diff --git a/projects/netgrif-components/src/lib/forms/email-submission/email-submission-form.component.html b/projects/netgrif-components/src/lib/forms/email-submission/email-submission-form.component.html index 560ee04746..21dcbed897 100644 --- a/projects/netgrif-components/src/lib/forms/email-submission/email-submission-form.component.html +++ b/projects/netgrif-components/src/lib/forms/email-submission/email-submission-form.component.html @@ -3,7 +3,8 @@
email - + {{ 'dataField.validations.email' | translate}} @@ -15,7 +16,14 @@ arrow_back
- +
diff --git a/projects/netgrif-components/src/lib/forms/forgotten-password/forgotten-password-form.component.html b/projects/netgrif-components/src/lib/forms/forgotten-password/forgotten-password-form.component.html index 921f437307..209629946a 100644 --- a/projects/netgrif-components/src/lib/forms/forgotten-password/forgotten-password-form.component.html +++ b/projects/netgrif-components/src/lib/forms/forgotten-password/forgotten-password-form.component.html @@ -3,7 +3,8 @@
email - +
@@ -42,7 +43,13 @@
diff --git a/projects/netgrif-components/src/lib/forms/registration/registration-form.component.html b/projects/netgrif-components/src/lib/forms/registration/registration-form.component.html index 151f68d322..722613445d 100644 --- a/projects/netgrif-components/src/lib/forms/registration/registration-form.component.html +++ b/projects/netgrif-components/src/lib/forms/registration/registration-form.component.html @@ -3,20 +3,23 @@
email - +
account_circle - + {{getErrorMessage('name')}}
account_circle_outline - + {{getErrorMessage('surname')}}
@@ -57,7 +60,13 @@
diff --git a/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.html b/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.html index 6b8d163040..122b28e7fe 100644 --- a/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.html +++ b/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.html @@ -6,18 +6,40 @@ [resizeCursorPrecision]="10" [resizeEdges]="{ right: true }" (resizing)="onResizeEvent($event)"> -
- - - - - - - +
+ +
+ + + + + +
- +
+ +
+ +
+
diff --git a/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.scss b/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.scss index 3ceaa1dbdb..82f32a314e 100644 --- a/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.scss +++ b/projects/netgrif-components/src/lib/navigation/navigation-drawer/navigation-drawer.component.scss @@ -14,3 +14,17 @@ mat-divider.drawer-divider { width: 90%; } + +.sidenav-wrapper { + overflow-x: hidden !important; +} + +.sidenav-close-button { + position: absolute; + right: 0; + z-index: 100; +} + +.content-wrapper { + height: 100%; +}