ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
1,339 lines (1,338 loc) • 213 kB
JavaScript
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;