src/app/shared/widgets/dynamic-form/dynamic-form-tabs-dialog/dynamic-form-tabs-dialog.component.ts
Properties |
|
tab |
tab:
|
Type : string
|
Optional |
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();
}
}