UNPKG

ontimize-web-ngx

Version:
1,339 lines (1,338 loc) 213 kB
import { __decorate, __metadata } from "tslib"; import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Injector, NgZone, ViewChild, ViewEncapsulation } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { BooleanInputConverter } from '../../decorators/input-converter'; import { DialogService } from '../../services/dialog.service'; import { OntimizeServiceProvider } from '../../services/factories'; import { NavigationService } from '../../services/navigation.service'; import { OntimizeService } from '../../services/ontimize/ontimize.service'; import { PermissionsService } from '../../services/permissions/permissions.service'; import { SnackBarService } from '../../services/snackbar.service'; import { Codes } from '../../util/codes'; import { SQLTypes } from '../../util/sqltypes'; import { Util } from '../../util/util'; import { OFormContainerComponent } from '../form-container/o-form-container.component'; import { OFormControl } from '../input/o-form-control.class'; import { OFormCacheClass } from './cache/o-form.cache.class'; import { CanDeactivateFormGuard } from './guards/o-form-can-deactivate.guard'; import { OFormNavigationClass } from './navigation/o-form.navigation.class'; import { OFormBase } from './o-form-base.class'; import { O_FORM_GLOBAL_CONFIG } from './o-form-tokens'; import { OFormValue } from './o-form-value'; import { OFormMessageService } from './services/o-form-message.service'; import { FactoryUtil } from '../../util/factory.util'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/common"; import * as i3 from "./toolbar/o-form-toolbar.component"; import * as i4 from "@angular/flex-layout/flex"; import * as i5 from "@angular/forms"; import * as i6 from "../../directives/keyboard-listener.directive"; import * as i7 from "@angular/material/progress-bar"; export const DEFAULT_INPUTS_O_FORM = [ 'showHeader: show-header', 'headerMode: header-mode', 'headerPosition: header-position', 'labelheader: label-header', 'labelHeaderAlign: label-header-align', 'headeractions: header-actions', 'showHeaderActionsText: show-header-actions-text', 'entity', 'keys', 'columns', 'service', 'stayInRecordAfterEdit: stay-in-record-after-edit', 'afterInsertMode: after-insert-mode', 'serviceType : service-type', 'queryOnInit : query-on-init', 'parentKeys: parent-keys', 'queryMethod: query-method', 'insertMethod: insert-method', 'updateMethod: update-method', 'deleteMethod: delete-method', 'layoutDirection: layout-direction', 'layoutAlign: layout-align', 'editableDetail: editable-detail', 'keysSqlTypes: keys-sql-types', 'undoButton: undo-button', 'showHeaderNavigation: show-header-navigation', 'oattr:attr', 'includeBreadcrumb: include-breadcrumb', 'detectChangesOnBlur: detect-changes-on-blur', 'confirmExit: confirm-exit', 'ignoreOnExit: ignore-on-exit', 'queryFallbackFunction: query-fallback-function', 'ignoreDefaultNavigation: ignore-default-navigation', 'messageServiceType : message-service-type', 'configureServiceArgs: configure-service-args', 'setValueOrder: set-value-order', 'formDataValidationFunction: form-data-validation-function' ]; export const DEFAULT_OUTPUTS_O_FORM = [ 'onDataLoaded', 'beforeCloseDetail', 'beforeGoEditMode', 'onFormModeChange', 'onBeforeInsert', 'onBeforeUpdate', 'onBeforeDelete', 'onInsert', 'onUpdate', 'onDelete', 'beforeInsertMode', 'beforeUpdateMode', 'beforeInitialMode', 'onInsertMode', 'onUpdateMode', 'onInitialMode', 'onCancel' ]; export class OFormComponent { set ignoreOnExit(val) { if (typeof val === 'string') { val = Util.parseArray(val, true); } this._ignoreOnExit = val; } get ignoreOnExit() { return this._ignoreOnExit; } static Mode() { let m; (function (m) { m[m["QUERY"] = 0] = "QUERY"; m[m["INSERT"] = 1] = "INSERT"; m[m["UPDATE"] = 2] = "UPDATE"; m[m["INITIAL"] = 3] = "INITIAL"; })(m || (m = {})); return m; } constructor(router, actRoute, zone, cd, injector, elRef) { this.router = router; this.actRoute = actRoute; this.zone = zone; this.cd = cd; this.injector = injector; this.elRef = elRef; this.showHeader = true; this.headerMode = 'floating'; this.headerPosition = 'top'; this.labelheader = ''; this.labelHeaderAlign = 'center'; this.headeractions = 'all'; this.showHeaderActionsText = 'yes'; this.keys = ''; this.columns = ''; this.setValueOrder = ''; this.stayInRecordAfterEdit = false; this.afterInsertMode = 'close'; this.queryOnInit = true; this.getMethod = ""; this.queryMethod = Codes.QUERYBYID_METHOD; this.insertMethod = Codes.INSERT_METHOD; this.updateMethod = Codes.UPDATE_METHOD; this.deleteMethod = Codes.DELETE_METHOD; this._layoutDirection = OFormComponent.DEFAULT_LAYOUT_DIRECTION; this._layoutAlign = 'start stretch'; this.editableDetail = true; this.undoButton = true; this.showHeaderNavigation = false; this.oattr = ''; this.includeBreadcrumb = false; this.detectChangesOnBlur = true; this.confirmExit = true; this.ignoreDefaultNavigation = false; this.isDetailForm = false; this.keysArray = []; this.colsArray = []; this._pKeysEquiv = {}; this.keysSqlTypesArray = []; this.onDataLoaded = new EventEmitter(); this.beforeCloseDetail = new EventEmitter(); this.beforeGoEditMode = new EventEmitter(); this.beforeInsertMode = new EventEmitter(); this.beforeUpdateMode = new EventEmitter(); this.beforeInitialMode = new EventEmitter(); this.onInsertMode = new EventEmitter(); this.onUpdateMode = new EventEmitter(); this.onInitialMode = new EventEmitter(); this.onFormModeChange = new EventEmitter(); this.onBeforeInsert = new EventEmitter(); this.onBeforeUpdate = new EventEmitter(); this.onBeforeDelete = new EventEmitter(); this.onInsert = new EventEmitter(); this.onUpdate = new EventEmitter(); this.onDelete = new EventEmitter(); this.onCancel = new EventEmitter(); this.loadingSubject = new BehaviorSubject(false); this.loading = this.loadingSubject.asObservable(); this.formData = {}; this.navigationData = []; this.currentIndex = 0; this.mode = OFormComponent.Mode().INITIAL; this._components = {}; this._compSQLTypes = {}; this.onFormInitStream = new EventEmitter(); this.ignoreFormCacheKeys = []; this.formCache = new OFormCacheClass(this); this.formNavigation = new OFormNavigationClass(this.injector, this, this.router, this.actRoute); this.dialogService = injector.get(DialogService); this.navigationService = injector.get(NavigationService); this.snackBarService = injector.get(SnackBarService); this.permissionsService = this.injector.get(PermissionsService); const self = this; this.reloadStream = combineLatest([ self.onFormInitStream.asObservable(), self.formNavigation.navigationStream.asObservable() ]); this.reloadStreamSubscription = this.reloadStream.subscribe(valArr => { if (Util.isArray(valArr) && valArr.length === 2 && !self.isInInsertMode()) { const valArrValues = valArr[0] === true && valArr[1] === true; if (self.queryOnInit && valArrValues) { self.reload(true); } else { self.initializeFields(); } } }); try { this.formContainer = injector.get(OFormContainerComponent); this.formContainer.setForm(this); } catch (e) { } this.getGlobalConfig(); } getGlobalConfig() { try { const oFormGlobalConfig = this.injector.get(O_FORM_GLOBAL_CONFIG); if (Util.isDefined(oFormGlobalConfig.headerActions)) { this.headeractions = oFormGlobalConfig.headerActions; } ; } catch (error) { } } registerFormComponent(comp) { if (comp) { const attr = comp.getAttribute(); if (attr && attr.length > 0) { if (!comp.isAutomaticRegistering()) { return; } if (this._components.hasOwnProperty(attr)) { comp.repeatedAttr = true; console.error('There is already a component registered in the form with the attr: ' + attr); return; } this._components[attr] = comp; if (this.formParentKeysValues && this.formParentKeysValues[attr] !== undefined) { const val = this.formParentKeysValues[attr]; this._components[attr].setValue(val, { emitModelToViewChange: false, emitEvent: false }); } const cachedValue = this.formCache.getCachedValue(attr); if (Util.isDefined(cachedValue) && this.getDataValues() && this._components.hasOwnProperty(attr)) { this._components[attr].setValue(cachedValue, { emitModelToViewChange: false, emitEvent: false }); } } } } registerSQLTypeFormComponent(comp) { if (comp.repeatedAttr) { return; } if (comp) { const type = comp.getSQLType(); const attr = comp.getAttribute(); if (type !== SQLTypes.OTHER && attr && attr.length > 0 && this.ignoreFormCacheKeys.indexOf(attr) === -1) { this._compSQLTypes[attr] = type; } } } registerFormControlComponent(comp) { if (comp.repeatedAttr) { return; } if (comp) { const attr = comp.getAttribute(); if (attr && attr.length > 0) { const control = comp.getControl(); if (control) { this.formGroup.registerControl(attr, control); if (!comp.isAutomaticRegistering()) { this.ignoreFormCacheKeys.push(comp.getAttribute()); } } } } } unregisterFormComponent(comp) { if (comp) { const attr = comp.getAttribute(); if (attr && attr.length > 0 && this._components.hasOwnProperty(attr)) { delete this._components[attr]; } } } getAttribute() { if (this.oattr) { return this.oattr; } return undefined; } unregisterFormControlComponent(comp) { if (comp && comp.isAutomaticRegistering()) { const control = comp.getControl(); const attr = comp.getAttribute(); if (control && attr && attr.length > 0) { this.formGroup.removeControl(attr); } } } unregisterSQLTypeFormComponent(comp) { if (comp) { const attr = comp.getAttribute(); if (attr && attr.length > 0) { delete this._compSQLTypes[attr]; } } } registerToolbar(fToolbar) { if (fToolbar) { this._formToolbar = fToolbar; this._formToolbar.isDetail = this.isDetailForm; } } getComponents() { return this._components; } getComponentByAttr(attr) { return this._components[attr]; } load() { const self = this; const zone = this.injector.get(NgZone); const loadObservable = new Observable(observer => { const timer = window.setTimeout(() => { observer.next(true); }, 250); return () => { window.clearTimeout(timer); zone.run(() => { self.loadingSubject.next(false); }); }; }); const subscription = loadObservable.subscribe(val => { zone.run(() => { self.loadingSubject.next(val); }); }); return subscription; } getDataValue(attr) { if (this.isInInsertMode()) { const urlParams = this.formNavigation.getFilterFromUrlParams(); const val = this.formGroup.value[attr] || urlParams[attr]; return new OFormValue(val); } else if (this.isInInitialMode() && !this.isEditableDetail()) { const data = this.formData; if (data && data.hasOwnProperty(attr)) { return data[attr]; } } else if (this.isInUpdateMode() || this.isEditableDetail()) { if (this.formData && Object.keys(this.formData).length > 0) { const val = this.formCache.getCachedValue(attr); if (this.formGroup.dirty && val) { if (val instanceof OFormValue) { return val; } return new OFormValue(val); } else { const data = this.formData; if (data && data.hasOwnProperty(attr)) { return data[attr]; } } } } return new OFormValue(); } getDataValues() { return this.formData; } clearData() { const filter = this.formNavigation.getFilterFromUrlParams(); this.formGroup.reset({}, { emitEvent: false }); this.setData(filter); } canDeactivate() { const readOnly = this.isInInitialMode() && !this.isEditableDetail(); const cancelledEdition = this.isInUpdateMode() && this._formToolbar && !this._formToolbar.editMode; if (readOnly || cancelledEdition) { return true; } if (!this.confirmExit) { return true; } const canDiscardChanges = !!this.canDiscardChanges; this.canDiscardChanges = false; return canDiscardChanges || this.showConfirmDiscardChanges(); } showConfirmDiscardChanges() { return this.formNavigation.showConfirmDiscardChanges(this.ignoreOnExit); } executeToolbarAction(action, options) { switch (action) { case Codes.BACK_ACTION: this.back(options); break; case Codes.CLOSE_DETAIL_ACTION: this.closeDetail(options); break; case Codes.RELOAD_ACTION: this.reload(true); break; case Codes.GO_INSERT_ACTION: this.goInsertMode(options); break; case Codes.INSERT_ACTION: this.insert(); break; case Codes.GO_EDIT_ACTION: this.goEditMode(); break; case Codes.EDIT_ACTION: this.update(); break; case Codes.UNDO_LAST_CHANGE_ACTION: this.undo(); break; case Codes.DELETE_ACTION: return this.delete(); default: break; } return undefined; } ngOnInit() { this.addDeactivateGuard(); this.formGroup = new UntypedFormGroup({}); this.formNavigation.initialize(); this.initialize(); } addDeactivateGuard() { if (!this.actRoute || !this.actRoute.routeConfig) { return; } this.deactivateGuard = this.injector.get(CanDeactivateFormGuard); this.deactivateGuard.addForm(this); const canDeactivateArray = (this.actRoute.routeConfig.canDeactivate || []); let previouslyAdded = false; for (let i = 0, len = canDeactivateArray.length; i < len; i++) { previouslyAdded = ((canDeactivateArray[i].hasOwnProperty('CLASSNAME') && canDeactivateArray[i].CLASSNAME) === OFormComponent.guardClassName); if (previouslyAdded) { break; } } if (!previouslyAdded) { canDeactivateArray.push(this.deactivateGuard.constructor); this.actRoute.routeConfig.canDeactivate = canDeactivateArray; } } destroyDeactivateGuard() { try { if (this.hasDeactivateGuard()) { this.deactivateGuard.removeForm(this); if (!this.deactivateGuard.isFormsCacheEmpty()) { return; } } if (!this.actRoute || !this.actRoute.routeConfig || !this.actRoute.routeConfig.canDeactivate) { return; } const guardIndex = this.actRoute.routeConfig.canDeactivate.findIndex((canDeactivate) => canDeactivate.name === OFormComponent.guardClassName); if (guardIndex >= 0) { this.actRoute.routeConfig.canDeactivate.splice(guardIndex, 1); } if (this.actRoute.routeConfig.canDeactivate.length === 0) { delete this.actRoute.routeConfig.canDeactivate; } } catch (e) { } } hasDeactivateGuard() { return Util.isDefined(this.deactivateGuard); } initialize() { const self = this; if (this.headeractions === 'all') { this.headeractions = 'R;I;U;D'; } this.keysArray = Util.parseArray(this.keys, true); this.colsArray = Util.parseArray(this.columns, true); const pkArray = Util.parseArray(this.parentKeys); this._pKeysEquiv = Util.parseParentKeysEquivalences(pkArray); this.keysSqlTypesArray = Util.parseArray(this.keysSqlTypes); this.setValueOrderArray = Util.parseArray(this.setValueOrder); this.configureService(); this.formNavigation.subscribeToQueryParams(); this.formNavigation.subscribeToUrlParams(); this.formNavigation.subscribeToUrl(); this.formNavigation.subscribeToCacheChanges(); if (this.navigationService) { this.navigationService.onVisibleChange(visible => { self.showHeader = visible; }); } this.mode = OFormComponent.Mode().INITIAL; this.permissions = this.permissionsService.getFormPermissions(this.oattr, this.actRoute); if (typeof this.queryFallbackFunction !== 'function') { this.queryFallbackFunction = undefined; } } reinitialize(options) { if (options && Object.keys(options).length) { const clonedOpts = Object.assign({}, options); for (const prop in clonedOpts) { if (clonedOpts.hasOwnProperty(prop)) { this[prop] = clonedOpts[prop]; } } this.destroy(); this.initialize(); } } configureService() { const msgConfigureServiceArgs = { injector: this.injector, baseService: OFormMessageService, serviceType: this.messageServiceType }; this._messageService = Util.configureMessageService(msgConfigureServiceArgs); let configureServiceArgs = { injector: this.injector, baseService: OntimizeService, entity: this.entity, service: this.service, serviceType: this.serviceType }; if (Util.isDefined(this.configureServiceArgs)) { configureServiceArgs = { ...configureServiceArgs, ...this.configureServiceArgs }; } this.dataService = FactoryUtil.configureService(configureServiceArgs); } get messageService() { return this._messageService; } ngOnDestroy() { this.destroy(); } destroy() { if (this.reloadStreamSubscription) { this.reloadStreamSubscription.unsubscribe(); } if (this.querySubscription) { this.querySubscription.unsubscribe(); } if (this.loaderSubscription) { this.loaderSubscription.unsubscribe(); } this.formCache.destroy(); this.formNavigation.destroy(); this.destroyDeactivateGuard(); } ngAfterViewInit() { setTimeout(() => { this.determinateFormMode(); this.onFormInitStream.emit(true); }, 0); } _setComponentsEditable(state) { const components = this.getComponents(); Object.keys(components).forEach(compKey => { const component = components[compKey]; component.isReadOnly = !state; }); } setFormMode(mode) { switch (mode) { case OFormComponent.Mode().INITIAL: this.beforeInitialMode.emit(); this.mode = mode; if (this._formToolbar) { this._formToolbar.setInitialMode(); } this._setComponentsEditable(this.isEditableDetail()); this.onFormModeChange.emit(this.mode); this.onInitialMode.emit(); break; case OFormComponent.Mode().INSERT: this.beforeInsertMode.emit(); this.mode = mode; if (this._formToolbar) { this._formToolbar.setInsertMode(); } this.clearData(); this._setComponentsEditable(true); this.onFormModeChange.emit(this.mode); this.onInsertMode.emit(); break; case OFormComponent.Mode().UPDATE: this.beforeUpdateMode.emit(); this.mode = mode; if (this._formToolbar) { this._formToolbar.setEditMode(); } this._setComponentsEditable(true); this.onFormModeChange.emit(this.mode); this.onUpdateMode.emit(); break; case OFormComponent.Mode().QUERY: console.error('Form QUERY mode is not implemented'); break; default: break; } } setData(data) { if (Util.isArray(data)) { if (data.length > 1) { console.warn('[OFormComponent] Form data has more than a single record. Storing empty data'); } const currentData = data.length === 1 ? data[0] : {}; this._updateFormData(this.toFormValueData(currentData)); this._emitData(currentData); } else if (Util.isObject(data)) { this._updateFormData(this.toFormValueData(data)); this._emitData(data); } else { console.warn('Form has received not supported service data. Supported data are Array or Object'); this._updateFormData({}); } } _setData(data) { console.warn('Method `OFormComponent._setData` is deprecated and will be removed in the furute. Use `setData` instead'); this.setData(data); } _emitData(data) { this.onDataLoaded.emit(data); } _backAction() { console.warn('Method `OFormComponent._backAction` is deprecated and will be removed in the furute. Use `back` instead'); this.back(); } back(options) { const allOptions = Object.assign(options || {}, { ignoreNavigation: this.ignoreDefaultNavigation }); this.formNavigation.navigateBack(allOptions); } _closeDetailAction(options) { console.warn('Method `OFormComponent._closeDetailAction` is deprecated and will be removed in the furute. Use `closeDetail` instead'); this.closeDetail(options); } closeDetail(options) { options = Util.isDefined(options) ? options : {}; options.ignoreNavigation = this.ignoreDefaultNavigation; this.formNavigation.closeDetailAction(options); } _stayInRecordAfterInsert(insertedKeys) { this.formNavigation.stayInRecordAfterInsert(insertedKeys); } _reloadAction(useFilter = false) { console.warn('Method `OFormComponent._reloadAction` is deprecated and will be removed in the furute. Use `reload` instead'); this.reload(useFilter); } reload(useFilter = false) { let queryArguments = this.getQueryArguments(useFilter); this.queryData(queryArguments.filter); } getQueryArguments(useFilter, filter = {}) { const av = this.getAttributesToQuery(); const sqlTypes = this.getAttributesSQLTypes(); if (useFilter) { filter = this.getCurrentKeysValues(); } return { filter: filter, columns: av, entity: this.entity, sqlTypes: sqlTypes }; } _goInsertMode(options) { console.warn('Method `OFormComponent._goInsertMode` is deprecated and will be removed in the furute. Use `goInsertMode` instead'); this.goInsertMode(options); } goInsertMode(options) { this.formNavigation.goInsertMode(options); } _clearFormAfterInsert() { this.clearData(); this._setComponentsEditable(true); } _clearAndCloseFormAfterInsert() { const closeOpts = { exitWithoutConfirmation: true }; this.closeDetail(closeOpts); } _insertAction() { console.warn('Method `OFormComponent._insertAction` is deprecated and will be removed in the furute. Use `insert` instead'); this.insert(); } insert() { Object.keys(this.formGroup.controls).forEach((control) => { this.formGroup.controls[control].markAsTouched(); }); if (!this.formGroup.valid) { this.dialogService.alert(this._messageService.getValidationErrorDialogTitle(), this._messageService.getValidationError()); return; } const self = this; const values = this.getAttributesValuesToInsert(); const sqlTypes = this.getAttributesSQLTypes(); if (!(this.validateBeforeAction(values))) { return; } this.onBeforeInsert.emit(values); this.insertData(values, sqlTypes).subscribe(resp => { self.postCorrectInsert(resp); self.formCache.setCacheSnapshot(); self.markFormLayoutManagerToUpdate(); if (self.afterInsertMode === 'detail') { self._stayInRecordAfterInsert(resp); } else if (self.afterInsertMode === 'new') { this._clearFormAfterInsert(); } else if (self.afterInsertMode === 'close') { this._clearAndCloseFormAfterInsert(); } else { self.closeDetail(); } }, error => { self.postIncorrectInsert(error); }); } validateBeforeAction(values) { if (this.formDataValidationFunction) { const result = this.formDataValidationFunction(values); if (!result.valid) { this.dialogService.alert(result.title ?? this._messageService.getValidationErrorDialogTitle(), result.messages ? result.messages.join('</br>') : this._messageService.getValidationError()); return false; } } return true; } _goEditMode() { console.warn('Method `OFormComponent._goEditMode` is deprecated and will be removed in the furute. Use `goEditMode` instead'); this.goEditMode(); } goEditMode() { this.formNavigation.goEditMode(); } _editAction() { console.warn('Method `OFormComponent._editAction` is deprecated and will be removed in the furute. Use `update` instead'); this.update(); } update() { Object.keys(this.formGroup.controls).forEach((control) => { this.formGroup.controls[control].markAsTouched(); }); if (!this.formGroup.valid) { this.dialogService.alert('ERROR', this._messageService.getValidationError()); return; } const self = this; const filter = this.getKeysValues(); const values = this.getAttributesValuesToUpdate(); const sqlTypes = this.getAttributesSQLTypes(); if (Object.keys(values).length === 0) { this.dialogService.alert('INFO', this._messageService.getNothingToUpdateMessage()); return; } if (!(this.validateBeforeAction(values))) { return; } this.onBeforeUpdate.emit(values); this.updateData(filter, values, sqlTypes).subscribe(resp => { self.postCorrectUpdate(resp); self.formCache.setCacheSnapshot(); self.markFormLayoutManagerToUpdate(); if (self.stayInRecordAfterEdit) { self.reload(true); } else { self.closeDetail(); } }, error => { self.postIncorrectUpdate(error); }); } _deleteAction() { console.warn('Method `OFormComponent._deleteAction` is deprecated and will be removed in the furute. Use `delete` instead'); return this.delete(); } delete() { const filter = this.getKeysValues(); this.onBeforeDelete.emit(filter); return this.deleteData(filter); } queryData(filter) { if (!Util.isDefined(this.dataService)) { console.warn('OFormComponent: no service configured! aborting query'); return; } if (!Util.isDefined(filter) || Object.keys(filter).length === 0) { console.warn('OFormComponent: no filter configured! aborting query'); return; } this.formCache.restartCache(); this.clearComponentsOldValue(); if (this.querySubscription) { this.querySubscription.unsubscribe(); } if (this.loaderSubscription) { this.loaderSubscription.unsubscribe(); } this.loaderSubscription = this.load(); const queryParameter = this.getQueryArguments(false, filter); this.querySubscription = this.dataService[this.queryMethod](...this.dataService.requestArgumentAdapter.parseQueryParameters(queryParameter)) .subscribe((resp) => { if (resp.isSuccessful()) { this.setData(resp.data); } else { this._updateFormData({}); this.dialogService.alert('ERROR', this._messageService.getQueryErrorMessage()); console.error('ERROR: ' + resp.message); } this.loaderSubscription.unsubscribe(); }, err => { console.error(err); this._updateFormData({}); if (Util.isDefined(this.queryFallbackFunction)) { this.queryFallbackFunction(err); } else if (err && err.statusText) { this.dialogService.alert('ERROR', err.statusText); } else { this.dialogService.alert('ERROR', this._messageService.getQueryErrorMessage()); } this.loaderSubscription.unsubscribe(); }); } getAttributesToQuery() { let attributes = []; if (this.keysArray && this.keysArray.length > 0) { attributes.push(...this.keysArray); } const components = this.getComponents(); Object.keys(components).forEach(item => { if (attributes.indexOf(item) < 0 && components[item].isAutomaticRegistering() && components[item].isAutomaticBinding()) { attributes.push(item); } }); const dataCache = this.formCache.getDataCache(); if (dataCache) { Object.keys(dataCache).forEach(item => { if (item !== undefined && attributes.indexOf(item) === -1) { attributes.push(item); } }); } attributes = attributes.concat(this.colsArray.filter(col => attributes.indexOf(col) < 0)); return attributes; } insertData(values, sqlTypes) { if (this.loaderSubscription) { this.loaderSubscription.unsubscribe(); } this.loaderSubscription = this.load(); const self = this; const observable = new Observable(observer => { this.dataService[this.insertMethod](values, this.entity, sqlTypes).subscribe(resp => { if (resp.isSuccessful()) { observer.next(resp.data); observer.complete(); } else { observer.error(resp.message); } self.loaderSubscription.unsubscribe(); }, err => { observer.error(err); self.loaderSubscription.unsubscribe(); }); }); return observable; } getAttributesValuesToInsert() { const attrValues = {}; if (this.formParentKeysValues) { Object.assign(attrValues, this.formParentKeysValues); } return Object.assign(attrValues, this.getRegisteredFieldsValues()); } getAttributesSQLTypes() { const types = {}; this.keysSqlTypesArray.forEach((kst, i) => types[this.keysArray[i]] = SQLTypes.getSQLTypeValue(kst)); if (this._compSQLTypes && Object.keys(this._compSQLTypes).length > 0) { Object.assign(types, this._compSQLTypes); } return types; } updateData(filter, values, sqlTypes) { if (this.loaderSubscription) { this.loaderSubscription.unsubscribe(); } this.loaderSubscription = this.load(); const self = this; const observable = new Observable(observer => { this.dataService[this.updateMethod](filter, values, this.entity, sqlTypes).subscribe(resp => { if (resp.isSuccessful()) { observer.next(resp.data); observer.complete(); } else { observer.error(resp.message); } self.loaderSubscription.unsubscribe(); }, err => { observer.error(err); self.loaderSubscription.unsubscribe(); }); }); return observable; } getAttributesValuesToUpdate() { const values = {}; const self = this; const changedAttrs = this.formCache.getChangedFormControlsAttr(); Object.keys(this.formGroup.controls).filter(controlName => self.ignoreFormCacheKeys.indexOf(controlName) === -1 && changedAttrs.indexOf(controlName) !== -1).forEach((item) => { const control = self.formGroup.controls[item]; if (control instanceof OFormControl) { const comp = this.getComponentByAttr(item); values[item] = SQLTypes.parseUsingSQLType(control.getValue(), SQLTypes.getSQLTypeKey(comp.getSQLType())); ; } else { values[item] = control.value; } if (values[item] === undefined) { values[item] = null; } }); return values; } deleteData(filter) { if (this.loaderSubscription) { this.loaderSubscription.unsubscribe(); } this.loaderSubscription = this.load(); const self = this; const sqlTypes = this.getAttributesSQLTypes(); const observable = new Observable(observer => { this.canDiscardChanges = true; this.dataService[this.deleteMethod](filter, this.entity, sqlTypes).subscribe(resp => { if (resp.isSuccessful()) { self.formCache.setCacheSnapshot(); self.markFormLayoutManagerToUpdate(); self.postCorrectDelete(resp); observer.next(resp.data); observer.complete(); } else { self.postIncorrectDelete(resp); observer.error(resp.message); } self.loaderSubscription.unsubscribe(); }, err => { self.postIncorrectDelete(err); observer.error(err); self.loaderSubscription.unsubscribe(); }); }); return observable; } toJSONData(data) { if (!data) { data = {}; } const valueData = {}; Object.keys(data).forEach((item) => { valueData[item] = data[item].value; }); return valueData; } toFormValueData(data) { if (data && Util.isArray(data)) { const valueData = []; const self = this; data.forEach(item => { valueData.push(self.objectToFormValueData(item)); }); return valueData; } else if (data && Util.isObject(data)) { return this.objectToFormValueData(data); } return undefined; } getKeysValues() { const filter = {}; const currentRecord = this.formData; if (!this.keysArray) { return filter; } this.keysArray.forEach(key => { if (currentRecord[key] !== undefined) { let currentData = currentRecord[key]; if (currentData instanceof OFormValue) { currentData = currentData.value; } filter[key] = currentData; } }); return filter; } isInQueryMode() { return this.mode === OFormComponent.Mode().QUERY; } isInInsertMode() { return this.mode === OFormComponent.Mode().INSERT; } isInUpdateMode() { return this.mode === OFormComponent.Mode().UPDATE; } isInInitialMode() { return this.mode === OFormComponent.Mode().INITIAL; } setQueryMode() { this.setFormMode(OFormComponent.Mode().QUERY); } setInsertMode() { this.setFormMode(OFormComponent.Mode().INSERT); } setUpdateMode() { this.setFormMode(OFormComponent.Mode().UPDATE); } setInitialMode() { this.setFormMode(OFormComponent.Mode().INITIAL); } registerDynamicFormComponent(dynamicForm) { if (!Util.isDefined(dynamicForm)) { return; } const self = this; this.dynamicFormSubscription = dynamicForm.render.subscribe(res => { if (res) { self.refreshComponentsEditableState(); if (!self.isInInsertMode() && self.queryOnInit) { self.reload(true); } if (self.formParentKeysValues) { Object.keys(self.formParentKeysValues).forEach(parentKey => { const value = self.formParentKeysValues[parentKey]; const comp = self.getFieldReference(parentKey); if (Util.isFormDataComponent(comp) && comp.isAutomaticBinding()) { comp.setValue(value, { emitModelToViewChange: false, emitEvent: false }); } }); } } }); } unregisterDynamicFormComponent(dynamicForm) { if (dynamicForm && this.dynamicFormSubscription) { this.dynamicFormSubscription.unsubscribe(); } } getRequiredComponents() { const requiredCompontents = {}; const components = this.getComponents(); if (components) { Object.keys(components).forEach(key => { const comp = components[key]; const attr = comp.getAttribute(); if (comp.isRequired && attr && attr.length > 0) { requiredCompontents[attr] = comp; } }); } return requiredCompontents; } get layoutDirection() { return this._layoutDirection; } set layoutDirection(val) { const parsedVal = (val || '').toLowerCase(); this._layoutDirection = ['row', 'column', 'row-reverse', 'column-reverse'].indexOf(parsedVal) !== -1 ? parsedVal : OFormComponent.DEFAULT_LAYOUT_DIRECTION; } get layoutAlign() { return this._layoutAlign; } set layoutAlign(val) { this._layoutAlign = val; } get showFloatingToolbar() { return this.showHeader && this.headerMode === 'floating'; } get showNotFloatingToolbar() { return this.showHeader && this.headerMode !== 'floating'; } isEditableDetail() { return this.editableDetail; } isInitialStateChanged(ignoreAttrs = []) { return this.formCache.isInitialStateChanged(ignoreAttrs); } _undoLastChangeAction() { console.warn('Method `OFormComponent._undoLastChangeAction` is deprecated and will be removed in the furute. Use `undo` instead'); this.undo(); } undo() { this.formCache.undoLastChange(); } get isCacheStackEmpty() { return this.formCache.isCacheStackEmpty; } undoKeyboardPressed() { this.formCache.undoLastChange(); } getFormToolbar() { return this._formToolbar; } getFormManager() { return this.formNavigation.formLayoutManager; } getFormNavigation() { return this.formNavigation; } getFormCache() { return this.formCache; } getUrlParam(arg) { return this.getFormNavigation().getUrlParams()[arg]; } getUrlParams() { return this.getFormNavigation().getUrlParams(); } setUrlParamsAndReload(val) { this.formNavigation.setUrlParams(val); this.reload(true); } getRegisteredFieldsValues() { const values = {}; const components = this.getComponents(); const self = this; const componentsKeys = Object.keys(components).filter(key => self.ignoreFormCacheKeys.indexOf(key) === -1); componentsKeys.forEach(compKey => { const comp = components[compKey]; values[compKey] = SQLTypes.parseUsingSQLType(comp.getValue(), SQLTypes.getSQLTypeKey(comp.getSQLType())); }); return values; } getFieldValue(attr) { let value = null; const comp = this.getFieldReference(attr); if (comp) { value = comp.getValue(); } return value; } getFieldValues(attrs) { const arr = {}; attrs.forEach(key => arr[key] = this.getFieldValue(key)); return arr; } setFieldValue(attr, value, options) { const comp = this.getFieldReference(attr); if (comp) { comp.setValue(value, options); } } setFieldValues(values, options) { for (const key in values) { if (values.hasOwnProperty(key)) { this.setFieldValue(key, values[key], options); } } } clearFieldValue(attr, options) { const comp = this.getFieldReference(attr); if (comp) { comp.clearValue(options); } } clearFieldValues(attrs, options) { const self = this; attrs.forEach((key) => { self.clearFieldValue(key, options); }); } getFieldReference(attr) { return this._components[attr]; } getFieldReferences(attrs) { const arr = {}; const self = this; attrs.forEach((key) => { arr[key] = self.getFieldReference(key); }); return arr; } getFormComponentPermissions(attr) { let permissions; if (Util.isDefined(this.permissions)) { permissions = (this.permissions.components || []).find(comp => comp.attr === attr); } return permissions; } getActionsPermissions() { let permissions; if (Util.isDefined(this.permissions)) { permissions = (this.permissions.actions || []); } return permissions; } determinateFormMode() { const urlSegments = this.formNavigation.getUrlSegments(); if (urlSegments.length > 0) { const segment = urlSegments[urlSegments.length - 1]; this.determinateModeFromUrlSegment(segment); } else if (this.actRoute.parent) { this.actRoute.parent.url.subscribe(segments => { const segment = segments[segments.length - 1]; this.determinateModeFromUrlSegment(segment); }); } else { this.setFormMode(OFormComponent.Mode().INITIAL); } this.stayInRecordAfterEdit = this.stayInRecordAfterEdit || this.isEditableDetail(); } determinateModeFromUrlSegment(segment) { const _path = segment ? segment.path : ''; if (this.isInsertModePath(_path)) { this.setInsertMode(); return; } else if (this.isUpdateModePath(_path)) { this.setUpdateMode(); } else { this.setInitialMode(); } } _updateFormData(newFormData) { const self = this; this.zone.run(() => { this.formData = newFormData; const components = this.getComponents(); const keyComponents = [...Object.keys(components)]; if (!Util.isArrayEmpty(this.setValueOrderArray)) { keyComponents.sort((a, b) => { const indexA = this.setValueOrderArray.indexOf(a) === -1 ? 1 : 0; const indexB = this.setValueOrderArray.indexOf(b) === -1 ? 1 : 0; return indexA - indexB; }); } if (!Util.isArrayEmpty(keyComponents)) { keyComponents.forEach(key => { const comp = components[key]; this.setDataInFormDataComponent(comp, key); }); self.initializeFields(); } }); } setDataInFormDataComponent(comp, attr) { if (Util.isFormDataComponent(comp)) { try { if (comp.isAutomaticBinding()) { comp.data = this.getDataValue(attr); } } catch (error) { console.error(error); } } } initializeFields() { Object.keys(this.formGroup.controls).forEach(control => { this.formGroup.controls[control].markAsPristine(); }); this.formCache.registerCache(); this.formNavigation.updateNavigation(); } clearComponentsOldValue() { const components = this.getComponents(); const self = this; const componentsKeys = Object.keys(components).filter(key => self.ignoreFormCacheKeys.indexOf(key) === -1); componentsKeys.forEach(compKey => { const comp = components[compKey]; comp.oldValue = undefined; comp.getFormControl().setValue(undefined); }); } postCorrectInsert(result) { this.snackBarService.open(this._messageService.getInsertSuccessMessage(), { icon: 'check_circle' }); this.onInsert.emit(result); } postIncorrectInsert(result) { this.showError('insert', result); } postIncorrectDelete(result) { this.showError('delete', result); } postIncorrectUpdate(result) { this.showError('update', result); } postCorrectUpdate(result) { this.snackBarService.open(this._messageService.getUpdateSuccessMessage(), { icon: 'check_circle' }); this.onUpdate.emit(result); } postCorrectDelete(result) { this.snackBarService.open(this._messageService.getDeleteSuccessMessage(), { icon: 'check_circle' }); this.onDelete.emit(result); } markFormLayoutManagerToUpdate() { const formLayoutManager = this.getFormManager(); if (Util.isDefined(formLayoutManager)) { formLayoutManager.markForUpdate = true; } } objectToFormValueData(data = {}) { const valueData = {}; Object.keys(data).forEach((item) => { valueData[item] = new OFormValue(data[item]); }); return valueData; } getCurrentKeysValues() { return this.formNavigation.getCurrentKeysValues(); } refreshComponentsEditableState() { switch (this.mode) { case OFormComponent.Mode().INITIAL: this._setComponentsEditable(this.isEditableDetail()); break; case OFormComponent.Mode().INSERT: case OFormComponent.Mode().UPDATE: this._setComponentsEditable(true); break; default: break; } } isInsertModePath(path) { const navData = this.navigationService.getLastItem(); return Util.isDefined(navData) ? path === navData.getInsertFormRoute() : Codes.DEFAULT_INSERT_ROUTE === path;