nm-dynamic-form-tabs-dialog
src/app/shared/widgets/dynamic-form/dynamic-form-tabs-dialog/dynamic-form-tabs-dialog.component.ts
changeDetection | ChangeDetectionStrategy.OnPush |
selector | nm-dynamic-form-tabs-dialog |
styleUrls | dynamic-form-tabs-dialog.component.scss |
templateUrl | ./dynamic-form-tabs-dialog.component.html |
constructor(data: any, dialogRef: MatDialogRef
|
||||||||||||||||||
Parameters :
|
document:keydown.escape |
Arguments : '$event'
|
document:keydown.escape(event: )
|
Public getLocaleFields |
getLocaleFields()
|
Returns :
{}
|
Private handleAttribute | ||||||
handleAttribute(attribute: any)
|
||||||
Parameters :
Returns :
void
|
Private initLocalesFields |
initLocalesFields()
|
Returns :
void
|
isBackButtonNeeded |
isBackButtonNeeded()
|
Returns :
boolean
|
Private loadTabData | ||||||
loadTabData(tab: string)
|
||||||
Parameters :
Returns :
void
|
Private loadUserRights |
loadUserRights()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onCancel |
onCancel()
|
Returns :
void
|
onClick | ||||||
onClick(field: DynamicFormTabsField)
|
||||||
Parameters :
Returns :
void
|
onInit | ||||
onInit(value: )
|
||||
Parameters :
Returns :
void
|
onListFolderSelect |
onListFolderSelect(tab: any, data: any)
|
Returns :
void
|
onLocaleInit | ||||
onLocaleInit(value: )
|
||||
Parameters :
Returns :
void
|
onLocaleValueChange |
onLocaleValueChange(tab: any, data: any)
|
Returns :
void
|
onSave |
onSave()
|
Returns :
void
|
onUserRightsSelect |
onUserRightsSelect(tab: any, rights: any)
|
Returns :
void
|
onValidChange | ||||||
onValidChange(data: any)
|
||||||
Parameters :
Returns :
void
|
onValueChange | ||||||
onValueChange(data: any)
|
||||||
Parameters :
Returns :
void
|
Private populateAttributeValues | ||||
populateAttributeValues(data: )
|
||||
Parameters :
Returns :
void
|
Private setDefaultValues |
setDefaultValues()
|
Returns :
void
|
Private setTabData | ||||||
setTabData(tab: string)
|
||||||
Parameters :
Returns :
void
|
Private setUpdateValues |
setUpdateValues()
|
Returns :
void
|
Private subscribeToContextInputs |
subscribeToContextInputs()
|
Returns :
void
|
switchTab | ||||||
switchTab(field: DynamicFormTabsField)
|
||||||
Parameters :
Returns :
void
|
toListFolderForm | ||||||
toListFolderForm(field: DynamicFormTabsField)
|
||||||
Parameters :
Returns :
void
|
toLocalizationForm | ||||||
toLocalizationForm(field: DynamicFormTabsField)
|
||||||
Parameters :
Returns :
void
|
toMainForm | ||||||
toMainForm(tab: string)
|
||||||
Parameters :
Returns :
void
|
toUserRightsForm | ||||||
toUserRightsForm(field: DynamicFormTabsField)
|
||||||
Parameters :
Returns :
void
|
Private updateLocalizationFormValues |
updateLocalizationFormValues()
|
Returns :
void
|
Public _widgetframeService |
_widgetframeService:
|
Type : WidgetframeService
|
Public addFields |
addFields:
|
Default value : new Subject<any>()
|
Public attributeFields |
attributeFields:
|
Type : AttributeField[]
|
Default value : []
|
Public context |
context:
|
Type : string
|
Default value : ""
|
Public data |
data:
|
Type : any
|
Decorators : Inject
|
Public dialogRef |
dialogRef:
|
Type : MatDialogRef<DynamicFormTabsDialog>
|
Public editAttributeService |
editAttributeService:
|
Type : EditAttributeService
|
Private editedAttributeValues |
editedAttributeValues:
|
Default value : new Map<string, any>()
|
Private firstLocalesLoad |
firstLocalesLoad:
|
Type : boolean
|
Default value : true
|
Public isValid |
isValid:
|
Type : boolean
|
Default value : false
|
Public listFolderDataType |
listFolderDataType:
|
Type : string
|
Public listFolderLocalStorageSearch |
listFolderLocalStorageSearch:
|
Type : string
|
Public listFolderLocalStorageState |
listFolderLocalStorageState:
|
Type : string
|
Private listFolderSelection |
listFolderSelection:
|
Type : []
|
Default value : []
|
Public listFolderType |
listFolderType:
|
Type : string
|
Public localeFields |
localeFields:
|
Type : any[]
|
Default value : []
|
Public localeTabInitialized |
localeTabInitialized:
|
Default value : new Subject<{ init: boolean; value: any }>()
|
Private localeValues |
localeValues:
|
Type : any
|
Default value : {}
|
Public localeValueSetter |
localeValueSetter:
|
Default value : new Subject<{ field: string; value: any }>()
|
Public lookupOptions |
lookupOptions:
|
Default value : new Subject<any>()
|
Public removeFields |
removeFields:
|
Default value : new Subject<any>()
|
Public resetLookup |
resetLookup:
|
Default value : new Subject<any>()
|
Private restoreLocaleValues |
restoreLocaleValues:
|
Type : any
|
Default value : {}
|
Private restoreValues |
restoreValues:
|
Type : any
|
Default value : {}
|
Public selectedIndex |
selectedIndex:
|
Type : number
|
Default value : 0
|
Public selectedTab |
selectedTab:
|
Type : string
|
Public setDisabled |
setDisabled:
|
Default value : new Subject<any>()
|
Private tabContext |
tabContext:
|
Type : literal type
|
Public tabInitialized |
tabInitialized:
|
Default value : new Subject<{ init: boolean; value: any }>()
|
Public triggerValidation |
triggerValidation:
|
Default value : new Subject()
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public userRights |
userRights:
|
Type : any
|
Private userRightsSelection |
userRightsSelection:
|
Type : any
|
Default value : {}
|
Private values |
values:
|
Type : any
|
Default value : {}
|
Public valueSetter |
valueSetter:
|
Default value : new Subject<{ field: string; value: any }>()
|
import {
OnDestroy,
Component,
OnInit,
Inject,
ChangeDetectionStrategy,
ChangeDetectorRef,
HostListener,
} from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
import { WidgetframeService } from "../../widgetframe/widgetframe.service";
import { mapToLocalesFields } from "../../../components/util/";
import { DynamicFormField } from "../dynamic-form-component/dynamic-form-fields.component";
import { Subject } from "rxjs";
import { NgUnsubscribe } from "../../../ng-unsubscribe";
import { takeUntil } from "rxjs/operators";
import { EditAttributeService } from "../../../components/edit-attribute";
import { Attribute } from "../../../components/edit-attribute/attribute";
import { deepCopy } from "../../../components/util/util.service";
const TAB = {
localizedtext: "localizedtext",
listFolder: "listFolder",
userRights: "userRights",
};
const TAB_INDEX = new Map([
[TAB.localizedtext, 1],
[TAB.listFolder, 2],
[TAB.userRights, 3],
]);
export let DynamicFormTabsContext = {
saveClicked: new Subject<any>(),
saveSuccessful: new Subject<any>(),
enableSave: new Subject<any>(),
valueChanged: new Subject<any>(),
resetLookup: new Subject<any>(),
lookupOptions: new Subject<any>(),
addFields: new Subject<any>(),
removeFields: new Subject<any>(),
triggerValidation: new Subject(),
setDisabled: new Subject<any>(),
valueSetter: new Subject<any>(),
onClick: new Subject<any>(),
unsubscribe: null,
};
export interface DynamicFormTabsField extends DynamicFormField {
tab?: string;
}
interface AttributeField {
header: string;
attribute: Attribute;
}
@Component({
selector: "nm-dynamic-form-tabs-dialog",
templateUrl: "./dynamic-form-tabs-dialog.component.html",
styleUrls: ["./dynamic-form-tabs-dialog.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DynamicFormTabsDialog implements OnDestroy, OnInit {
private unsubscribe = NgUnsubscribe.create();
public selectedIndex = 0;
public selectedTab: string;
public isValid: boolean = false;
public valueSetter = new Subject<{ field: string; value: any }>();
public lookupOptions = new Subject<any>();
public addFields = new Subject<any>();
public removeFields = new Subject<any>();
public setDisabled = new Subject<any>();
public resetLookup = new Subject<any>();
public triggerValidation = new Subject();
public tabInitialized = new Subject<{ init: boolean; value: any }>();
private values: any = {};
private restoreValues: any = {};
public attributeFields: AttributeField[] = [];
private editedAttributeValues = new Map<string, any>();
public localeFields: any[] = [];
public localeValueSetter = new Subject<{ field: string; value: any }>();
public localeTabInitialized = new Subject<{ init: boolean; value: any }>();
private localeValues: any = {};
private restoreLocaleValues: any = {};
private firstLocalesLoad: boolean = true;
public listFolderType: string;
public listFolderDataType: string;
public listFolderLocalStorageState: string;
public listFolderLocalStorageSearch: string;
private listFolderSelection = [];
public userRights: any;
private userRightsSelection: any = {};
public context: string = "";
private tabContext: { field: any; value?: any };
constructor(
@Inject(MAT_DIALOG_DATA) public data: any,
public dialogRef: MatDialogRef<DynamicFormTabsDialog>,
public _widgetframeService: WidgetframeService,
public editAttributeService: EditAttributeService,
protected cdr: ChangeDetectorRef
) {
DynamicFormTabsContext.unsubscribe = NgUnsubscribe.create();
}
ngOnInit() {
if (!this.data) {
console.log("[nm-dynamic-form-tabs-dialog] no data");
}
this.setDefaultValues();
this.subscribeToContextInputs();
this.initLocalesFields();
this.loadUserRights();
this.tabInitialized
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => {
if (data && data.init && !data.value && this.restoreValues) {
Object.keys(this.restoreValues).forEach((key) =>
this.valueSetter.next({
field: key,
value: this.restoreValues[key],
})
);
this.loadTabData(this.selectedTab);
} else if (data && !data.init && data.value) {
this.restoreValues = data.value;
}
data["context"] = this.data.id;
this.context = this.data.id;
});
this.setUpdateValues();
if (this.data.attributeValues) {
this.populateAttributeValues(this.data.attributeValues);
this.editAttributeService
.getAttributeChangedEvent()
.pipe(takeUntil(this.unsubscribe))
.subscribe((attribute) => {
this.editedAttributeValues.set(attribute.identifier, attribute);
});
}
}
private setDefaultValues() {
if (!this.data.localesUrl) {
this.data.localesUrl = "/api/public/locales?type=ipim";
}
if (!this.data.saveButtonText) {
this.data.saveButtonText = "button.save";
}
if (!this.data.closeOnSave) {
this.data.closeOnSave = true;
}
}
private initLocalesFields() {
if (!this.data.localesUrl) {
return;
}
let localizationTabs = this.data.dialogConfig.tabs.filter(
(tab) => tab.type === "localizedtext"
);
if (localizationTabs && localizationTabs.length > 0) {
this._widgetframeService
.getData(this.data.localesUrl)
.subscribe((response) => {
localizationTabs.forEach((tab) => {
this.localeFields = mapToLocalesFields(
response._embedded.locales,
"plain",
tab.floatingLabel
);
});
});
}
}
public getLocaleFields() {
if (this.localeFields && this.localeFields.length > 0) {
this.localeFields[0].autofocus = true;
}
return this.localeFields;
}
private loadUserRights() {
if (!this.data.userRightsUrl) {
return;
}
this._widgetframeService
.getData(this.data.userRightsUrl)
.subscribe((response) => {
this.userRights = response._embedded[response.type];
});
}
private subscribeToContextInputs() {
DynamicFormTabsContext.saveSuccessful
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => this.dialogRef.close(data));
DynamicFormTabsContext.resetLookup
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => this.resetLookup.next(data));
DynamicFormTabsContext.lookupOptions
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => this.lookupOptions.next(data));
DynamicFormTabsContext.addFields
.pipe(takeUntil(this.unsubscribe))
.subscribe((fields) => this.addFields.next(fields));
DynamicFormTabsContext.removeFields
.pipe(takeUntil(this.unsubscribe))
.subscribe((fields) => this.removeFields.next(fields));
DynamicFormTabsContext.triggerValidation
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => this.triggerValidation.next());
DynamicFormTabsContext.setDisabled
.pipe(takeUntil(this.unsubscribe))
.subscribe((field) => this.setDisabled.next(field));
DynamicFormTabsContext.valueSetter
.pipe(takeUntil(this.unsubscribe))
.subscribe((field) => this.valueSetter.next(field));
DynamicFormTabsContext.enableSave
.pipe(takeUntil(this.unsubscribe))
.subscribe((isValid) => {
this.onValidChange(isValid);
});
}
private populateAttributeValues(data) {
let attributeValues = data ? data : [];
attributeValues.forEach((av) => {
this.handleAttribute(av);
});
}
private handleAttribute(attribute: any) {
if (attribute["read-only"]) {
return;
}
const field = {
header: attribute.description,
attribute: deepCopy(attribute),
};
this.attributeFields.push(field);
}
private setUpdateValues() {
if (!this.data.update) {
return;
}
if (this.data.localeValues) {
let restoredValues: any = {};
Object.keys(this.data.localeValues).forEach((key) => {
let values: any = {};
this.data.localeValues[key].forEach((value) => {
values[value.field] = value.value;
});
restoredValues[key] = values;
});
this.restoreLocaleValues = restoredValues;
}
if (this.data.userRights) {
this.userRightsSelection = this.data.userRights;
}
}
private setTabData(tab: string) {
switch (tab) {
case TAB.localizedtext:
this.tabContext.value = this.localeValues;
break;
case TAB.listFolder:
this.tabContext.value = this.listFolderSelection
? this.listFolderSelection
: null;
break;
case TAB.userRights:
if (
!this.userRightsSelection[this.tabContext.field] ||
this.userRightsSelection[this.tabContext.field].length === 0
) {
this.tabContext.value = this.values[this.tabContext.field];
return;
}
this.tabContext.value = this.userRightsSelection[this.tabContext.field];
break;
default:
return;
}
}
private loadTabData(tab: string) {
if (!tab) {
return;
}
switch (tab) {
case TAB.listFolder:
if (this.tabContext.value && this.tabContext.value.length !== 0) {
this.valueSetter.next({
field: this.tabContext.field,
value: [this.tabContext.value],
});
}
break;
default:
this.valueSetter.next({
field: this.tabContext.field,
value: this.tabContext.value,
});
return;
}
this.cdr.markForCheck();
}
toMainForm(tab: string) {
this.setTabData(tab);
this.selectedIndex = 0;
}
toLocalizationForm(field: DynamicFormTabsField) {
this.tabContext = { field: field.field };
this.localeTabInitialized
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => {
if (
data &&
data.init &&
!data.value &&
this.restoreLocaleValues &&
this.restoreLocaleValues[this.tabContext.field]
) {
Object.keys(this.restoreLocaleValues[this.tabContext.field]).forEach(
(key) =>
this.localeValueSetter.next({
field: key,
value: this.restoreLocaleValues[this.tabContext.field][key],
})
);
} else if (data && !data.init && data.value) {
this.restoreLocaleValues[this.tabContext.field] = data.value;
}
this.updateLocalizationFormValues();
});
}
private updateLocalizationFormValues() {
if (
!this.firstLocalesLoad ||
!this.data.update ||
!this.data.localeValues ||
!this.data.localeValues[this.tabContext.field]
) {
return;
}
this.data.localeValues[this.tabContext.field].forEach((value) =>
this.localeValueSetter.next(value)
);
this.firstLocalesLoad = false;
}
toListFolderForm(field: DynamicFormTabsField) {
this.tabContext = { field: field.field };
this.listFolderType = field.listfolderType;
this.listFolderDataType = field.dataType;
this.listFolderLocalStorageState = field.field + "LocalStorageState";
this.listFolderLocalStorageSearch = field.field + "LocalStorageSearch";
}
toUserRightsForm(field: DynamicFormTabsField) {
this.tabContext = { field: field.field };
}
onInit(value) {
this.tabInitialized.next(value);
}
onLocaleInit(value) {
this.localeTabInitialized.next(value);
}
onClick(field: DynamicFormTabsField) {
if (field.type === "password") {
DynamicFormTabsContext.onClick.next(true);
return;
}
if (!field.tab) {
return;
}
this.switchTab(field);
}
switchTab(field: DynamicFormTabsField) {
this.selectedTab = field.tab;
const index = TAB_INDEX.get(TAB[field.tab]);
switch (index) {
case 1: {
this.toLocalizationForm(field);
break;
}
case 2: {
this.toListFolderForm(field);
break;
}
case 3: {
this.toUserRightsForm(field);
break;
}
default: {
this.tabContext = { field: field.field };
}
}
this.selectedIndex = index;
}
onValueChange(data: any) {
this.values = data.value;
DynamicFormTabsContext.valueChanged.next(data);
}
onValidChange(data: any) {
this.isValid = data;
}
onLocaleValueChange(tab: any, data: any) {
this.localeValues = data.value;
}
onListFolderSelect(tab: any, data: any) {
if (!data || !data.isNode) {
return;
}
this.listFolderSelection = data;
this.toMainForm(tab.type);
}
onUserRightsSelect(tab: any, rights: any) {
if (!rights || rights.length === 0) {
return;
}
this.userRightsSelection[this.tabContext.field] = rights;
if (tab.multiSelection) {
return;
}
this.toMainForm(tab.type);
}
onSave() {
const data = {
id: this.data.id,
values: this.values,
attributeValues: this.editedAttributeValues,
localeValues: this.restoreLocaleValues,
listFolders: this.listFolderSelection,
userRights: this.userRightsSelection,
};
if (this.data.closeOnSave) {
this.dialogRef.close(data);
} else {
DynamicFormTabsContext.saveClicked.next(data);
}
}
isBackButtonNeeded() {
return this.selectedIndex > 0;
}
onCancel() {
this.dialogRef.close();
}
@HostListener("document:keydown.escape", ["$event"]) onKeydownHandler(event) {
// cant focus lastFocused element (not known)
this.onCancel();
}
ngOnDestroy() {
DynamicFormTabsContext.unsubscribe.destroy();
this.unsubscribe.destroy();
}
}
<nm-dialog
[dialogRef]="dialogRef"
class="nm-dynamicFormTabsDialog"
[id]="data.identifier"
[infoTitle]="data.infoTitle"
[infoText]="data.infoText"
>
<ng-container slot="title">
{{ data.title | translate }}
</ng-container>
<ng-container slot="content">
<mat-tab-group
[selectedIndex]="selectedIndex"
class="nm-dynamicFormTabsDialog__tabGroup --headerless"
>
<mat-tab *ngFor="let tab of data.dialogConfig.tabs; let i = index">
<ng-template matTabContent>
<div [ngSwitch]="tab.type">
<div *ngSwitchCase="'form'">
<nm-dynamic-form-fields-component
[fields]="tab.fields"
[valueSetter]="valueSetter"
[lookupOptions]="lookupOptions"
[resetLookup]="resetLookup"
[addFields]="addFields"
[removeFields]="removeFields"
[setDisabled]="setDisabled"
[triggerValidation]="triggerValidation"
(init)="onInit($event)"
(onClick)="onClick($event)"
(value)="onValueChange($event)"
(valid)="onValidChange($event)"
>
</nm-dynamic-form-fields-component>
<div *ngFor="let field of attributeFields">
<div class="nm-dynamicFormTabsDialog__attributeValue">
<nm-edit-attribute
[attribute]="field.attribute"
[copyContentButton]="false"
[onlyInputsForTexts]="true"
[readOnly]="field.attribute.readOnly"
[editAttributeService]="editAttributeService"
[floatingLabel]="field.header"
>
</nm-edit-attribute>
</div>
</div>
</div>
<div *ngSwitchCase="'localizedtext'">
<nm-dynamic-form-fields-component
[fields]="getLocaleFields()"
[valueSetter]="localeValueSetter"
(init)="onLocaleInit($event)"
(value)="onLocaleValueChange(tab, $event)"
>
</nm-dynamic-form-fields-component>
</div>
<div *ngSwitchCase="'listFolder'">
<nm-worklist-tree-selector
(onSelection)="onListFolderSelect(tab, $event)"
[local-storage-grid]="listFolderLocalStorageState"
[local-storage-filter]="listFolderLocalStorageSearch"
[folder-type]="listFolderType"
[elements-type]="listFolderDataType"
[recover-from-local-storage]="false"
[show-static-folders]="listFolderType === 'WORKLIST'"
height="400px"
>
</nm-worklist-tree-selector>
</div>
<div *ngSwitchCase="'userRights'">
<nm-user-rights-tree
[userRights]="userRights"
[hiddenPimRef]="tab.hiddenPimRef"
[hiddenType]="tab.hiddenType"
[multiSelection]="tab.multiSelection"
[hasChildrenKey]="tab.hasChildrenKey"
(selectedRights)="onUserRightsSelect(tab, $event)"
[context]="context"
[autoFocus]="true"
>
</nm-user-rights-tree>
</div>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</ng-container>
<ng-container slot="actions">
<button
id="tab.type"
*ngIf="isBackButtonNeeded()"
mat-button
type="button"
(click)="toMainForm(selectedTab)"
>
<mat-icon>keyboard_backspace</mat-icon>
{{ "button.back" | translate }}
</button>
<div style="flex-grow: 1"></div>
<button type="button" mat-button (click)="onCancel()">
{{ "button.cancel" | translate }}
</button>
<button
type="button"
mat-raised-button
color="primary"
(click)="onSave()"
[disabled]="!isValid"
>
{{ data.saveButtonText | translate }}
</button>
</ng-container>
</nm-dialog>