UNPKG

kwikid-forms

Version:

KwikID's JSON Configuration based Forms Renderer and Builder

908 lines 626 kB
import { __awaiter, __decorate } from "tslib"; /* eslint-disable no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Component, EventEmitter, Inject, Input, Output, ViewChild, ViewChildren } from "@angular/core"; import { FormGroup } from "@angular/forms"; import { TuiPreviewDialogService } from "@taiga-ui/addon-preview"; import { TuiAlertService, TuiDialogService, TuiNotification } from "@taiga-ui/core"; import { TuiPushService } from "@taiga-ui/kit"; import { Action, Condition, ESourceKey, Rule, RuleEngine, Source, checkObjectKeyExists, checkObjectPathExists, getObjectDeepCopy, getObjectValueFromPath, isEmptyString, isEmptyValue, isNotEmptyString, isNotEmptyValue, isNull, isUndefined, logMethod, mergeObjects, mergeObjectsDeep, removeKeyFromObjectPath, replaceString, setValueToObjectPath } from "kwikid-toolkit"; import { pairwise } from "rxjs/operators"; import { v4 as uuidv4 } from "uuid"; import { Converter } from "../config-converter/config-converter"; import { FIELD_PROPERTIES } from "../config-converter/config-converter.constants"; import { getLanguage, updateLanguage } from "../config-converter/config-converter.helper"; import { EFormsListStatus } from "../forms-list/forms-list.definitions"; import { EActionKey } from "./definitions/form-view.actions.definition"; import { EApiRequestUrlType, EApiStatusType } from "./definitions/form-view.apis.definition"; import { EMessageType } from "./definitions/form-view.commons.definition"; import { EFieldType } from "./definitions/form-view.fields.definition"; import { ELogEventType } from "./definitions/form-view.logs.definition"; import { KwikIDFormViewApiService } from "./form-view.api.service"; import { FORM_VIEW_TIMERS } from "./form-view.constants"; import { KwikIDFormViewService } from "./form-view.service"; import { Apis } from "./helpers/form-view.apis.helper"; import { CameraHelper } from "./helpers/form-view.camera.helper"; import { appendFormFieldMessage, appendHtmlMessage, convertFormFieldEmptyValueToKwikUIFormat, convertFormFieldValueToKwikUIFormat, convertFormFieldValueToStandardFormat, filterDuplicatesFiles, filterDuplicatesMediaFiles, getFormFieldByKey, getFormFieldIndexByKey, highlightFormFieldError, removeFormFieldMessage, setApiTimerMessage, showFormFieldError } from "./helpers/form-view.fields.helper"; import { FormValidation } from "./helpers/form-view.form-validations.helper"; import { formatEventLogs } from "./helpers/form-view.logs.helper"; import { Tasks } from "./helpers/form-view.tasks.helper"; import * as i0 from "@angular/core"; import * as i1 from "./form-view.service"; import * as i2 from "./form-view.api.service"; import * as i3 from "kwikui"; import * as i4 from "kwikid-camera"; import * as i5 from "@taiga-ui/core"; import * as i6 from "@taiga-ui/kit"; import * as i7 from "@taiga-ui/addon-preview"; import * as i8 from "@angular/common"; import * as i9 from "@angular/forms"; import * as i10 from "./helpers/styles-sanitizer.pipe"; import * as i11 from "./pipes/filter-image-url-or-base64-from-object.pipe"; import * as i12 from "./pipes/filter-video-url-or-base64-from-object.pipe"; import * as i13 from "../../common/pipes/timer-formatter.pipe"; export class KwikIDFormViewComponent { constructor(cdRef, formViewService, formViewApiService, pushService, alertService, previewDialogService, dialogService, loaderService, cameraRecordService, ref, renderer) { this.cdRef = cdRef; this.formViewService = formViewService; this.formViewApiService = formViewApiService; this.pushService = pushService; this.alertService = alertService; this.previewDialogService = previewDialogService; this.dialogService = dialogService; this.loaderService = loaderService; this.cameraRecordService = cameraRecordService; this.ref = ref; this.renderer = renderer; this.isMobileView = false; this.popupFormCallback = undefined; this.getLogs = new EventEmitter(); this.getUnsavedDataState = new EventEmitter(); this.onActionShowPopupForm = new EventEmitter(); this.onClickApiCall = new EventEmitter(); this.onClickViewFile = new EventEmitter(); this.onClickFormFieldButton = new EventEmitter(); this.onClickGoBack = new EventEmitter(); this.onClickSaveForm = new EventEmitter(); this.onClickViewForms = new EventEmitter(); this.fieldGroups = {}; this.formFields = []; this.previousFormData = {}; this.cameraData = {}; this.isShowCamera = false; this.isShowCameraFullscreen = false; this.activeCameraFieldKey = ""; this.activeCameraData = {}; this.activeCameraType = undefined; this.activeCameraImage = ""; this.activeCameraVideo = ""; this.activeCameraConfig = undefined; this.activeCameraRecordingTime = 0; this.activeCameraRecordingTimerSubcription = undefined; this.activeCameraRecordingState = "NONE"; this.activeCameraRecordingStateSubcription = undefined; this.previewProperties = { html: { before: "", beforeStyles: "", after: "", afterStyles: "" }, iframe: { src: "", title: "" }, type: "dialog", size: "auto", popupFormKey: "", title: "", unavailable: false }; this.loading = true; this.apiLoading = false; this.backButton = { disabled: false, showLoader: false }; this.viewFormsButton = { disabled: false, showLoader: false }; this.saveFormButton = { disabled: false, showLoader: false }; this.files = {}; this.mediaFiles = {}; this.stopTaskExecution = false; this.waitingForChanges = false; this.popupFormConfig = undefined; this.popupFormData = {}; this.taskData = {}; this.formGroup = new FormGroup({}); this.showErrorNotification = false; this.showPermissionErrorNotification = false; this.dialogRef = undefined; } resetCamera() { this.isShowCamera = false; this.isShowCameraFullscreen = false; this.activeCameraFieldKey = ""; this.activeCameraData = undefined; this.activeCameraType = undefined; this.activeCameraImage = ""; this.activeCameraVideo = ""; this.activeCameraConfig = undefined; this.activeCameraRecordingTime = 0; this.activeCameraRecordingState = "NONE"; } ngOnInit() { (() => __awaiter(this, void 0, void 0, function* () { const res = yield this.initFormConfig(this.formConfig); if (res) { this.loading = false; this.activeCameraRecordingTimerSubcription = this.cameraRecordService .getTimerUpdate() .subscribe((time) => { this.activeCameraRecordingTime = time; this.ref.detectChanges(); }); this.activeCameraRecordingStateSubcription = this.cameraRecordService .getRecordingState() .subscribe((state) => { this.activeCameraRecordingState = state; this.ref.detectChanges(); }); } }))(); } ngOnChanges(changes) { var _a, _b, _c, _d; const verifyChange = (key) => { return checkObjectKeyExists(changes, key) && !changes[key].firstChange; }; if (verifyChange("extraData")) { this.extraData = changes.extraData.currentValue; } if (verifyChange("userConfig")) { this.userConfig = changes.userConfig.currentValue; } if (verifyChange("stepConfig")) { this.stepConfig = changes.stepConfig.currentValue; } if (verifyChange("formData")) { if (checkObjectKeyExists(changes.formData.currentValue, "data") && checkObjectKeyExists(changes.formData.currentValue, "extendedData")) { this.formData = Object.assign(Object.assign({}, this.formData), changes.formData.currentValue.data); } else { this.formData = Object.assign(Object.assign({}, this.formData), changes.formData.currentValue); } } if (verifyChange("popupFormCallback")) { if (isNotEmptyValue(changes.popupFormCallback.currentValue)) { const popupFormData = checkObjectKeyExists(changes.popupFormCallback.currentValue.popupFormData, "data") && checkObjectKeyExists(changes.popupFormCallback.currentValue.popupFormData, "extendedData") ? changes.popupFormCallback.currentValue.popupFormData.data : changes.popupFormCallback.currentValue.popupFormData; const { popupFormConfig } = changes.popupFormCallback.currentValue; this.popupFormData = mergeObjects(this.popupFormData, { [popupFormConfig.key]: popupFormData }); this.formData = mergeObjects(this.formData, this.popupFormData); if (checkObjectKeyExists(changes.popupFormCallback.currentValue, "stopTaskExecution")) { this.stopTaskExecution = changes.popupFormCallback.currentValue.stopTaskExecution; } else { this.stopTaskExecution = false; } } this.waitingForChanges = false; } if (verifyChange("isMobileView")) { this.isMobileView = changes.isMobileView.currentValue; } if (verifyChange("apiCallResponse")) { this.apiCallResponse = changes.apiCallResponse.currentValue; const field = getFormFieldByKey(this.formFields, this.apiCallResponse.key); const response = (_a = this.apiCallResponse) === null || _a === void 0 ? void 0 : _a.response; switch (field.type) { case EFieldType.FILE: if (response) { const updatedFile = getObjectDeepCopy(Object.assign({ id: uuidv4() }, response)); this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_FILE, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "FILE_UPLOAD_API_SUCCESS", response }); this.updateFiles(updatedFile, "NORMAL", this.apiCallResponse.key); } else { const updatedFile = getObjectDeepCopy(Object.assign({ id: uuidv4() }, (_c = (_b = this.apiCallResponse) === null || _b === void 0 ? void 0 : _b.payload) === null || _c === void 0 ? void 0 : _c.metadata)); this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_FILE, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "FILE_UPLOAD_API_ERROR" }); this.updateFiles(updatedFile, "ERROR", this.apiCallResponse.key); } this.hideApiLoader(); break; case EFieldType.CAPTURE: if (response) { this.resetCamera(); const image = response === null || response === void 0 ? void 0 : response.image_url; const imageOcr = response === null || response === void 0 ? void 0 : response.image_ocr; const imageFacematch = response === null || response === void 0 ? void 0 : response.image_facematch; const imageLiveliness = response === null || response === void 0 ? void 0 : response.image_liveliness; const imageWatermark = response === null || response === void 0 ? void 0 : response.image_watermark; const isCheckCameraFeatures = () => { return (imageOcr || imageLiveliness || imageFacematch || imageWatermark); }; const imageData = isCheckCameraFeatures() ? Object.assign(Object.assign(Object.assign(Object.assign({ image }, (imageOcr && { ocr: imageOcr })), (imageFacematch && { facematch: imageFacematch })), (imageLiveliness && { liveliness: imageLiveliness })), (imageWatermark && { watermark: imageWatermark })) : image; this.formData[field.key] = getObjectDeepCopy([imageData]); this.cameraData[field.key] = getObjectDeepCopy(imageData); this.mediaFiles[field.key] = getObjectDeepCopy([imageData]); this.formGroup.controls[field.key].patchValue(getObjectDeepCopy([imageData]), { emitEvent: false, onlySelf: false }); this.formGroup.patchValue({ [field.key]: getObjectDeepCopy([imageData]) }, { emitEvent: false }); this.formGroup.controls[field.key].updateValueAndValidity({ emitEvent: false }); this.formGroup.updateValueAndValidity({ emitEvent: false }); this.getUnsavedDataState.emit(true); if (field.isFormElement && checkObjectKeyExists(field, "validation") && field.validation.triggers.includes("ON_CHANGE")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { yield ruleEngine.run(field.validation); }))(); } if (field.isFormElement && checkObjectKeyExists(field, "connectedElements")) { this.handleConnectedElements({ key: field.key, value: this.formGroup.controls[field.key].value }, "ON_CHANGE"); } this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_IMAGE, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "IMAGE_UPLOAD_API_SUCCESS", response }); } else { this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_IMAGE, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "IMAGE_UPLOAD_API_ERROR" }); console.error("File Upload for Image Failed"); } this.hideApiLoader(); break; case EFieldType.RECORD: if (response) { this.resetCamera(); const video = response === null || response === void 0 ? void 0 : response.video_url; this.formData[field.key] = getObjectDeepCopy([video]); this.cameraData[field.key] = getObjectDeepCopy(video); this.mediaFiles[field.key] = getObjectDeepCopy([video]); this.formGroup.controls[field.key].patchValue(getObjectDeepCopy([video]), { emitEvent: false, onlySelf: false }); this.formGroup.patchValue({ [field.key]: getObjectDeepCopy([video]) }, { emitEvent: false }); this.formGroup.controls[field.key].updateValueAndValidity({ emitEvent: false }); this.formGroup.updateValueAndValidity({ emitEvent: false }); this.getUnsavedDataState.emit(true); if (field.isFormElement && checkObjectKeyExists(field, "validation") && field.validation.triggers.includes("ON_CHANGE")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { yield ruleEngine.run(field.validation); }))(); } if (field.isFormElement && checkObjectKeyExists(field, "connectedElements")) { this.handleConnectedElements({ key: field.key, value: this.formGroup.controls[field.key].value }, "ON_CHANGE"); } this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_VIDEO, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "VIDEO_UPLOAD_API_SUCCESS", response }); } else { this.triggerLogs(ELogEventType.FORM__API_RESPONSE_UPLOAD_VIDEO, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "VIDEO_UPLOAD_API_ERROR" }); console.error("File Upload for Video Failed"); } this.hideApiLoader(); break; case EFieldType.LIVE_LOCATION: if (response) { this.formData[field.key] = getObjectDeepCopy(response); this.formGroup.controls[field.key].patchValue(getObjectDeepCopy(response), { emitEvent: false, onlySelf: false }); this.formGroup.patchValue({ [field.key]: getObjectDeepCopy(response) }, { emitEvent: false }); this.formGroup.controls[field.key].updateValueAndValidity({ emitEvent: false }); this.formGroup.updateValueAndValidity({ emitEvent: false }); this.getUnsavedDataState.emit(true); const apis = new Apis({ FIELD_CONFIG: field, API_CONFIG: field.api, API_RESPONSE: response, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { const api = yield apis.validateResponse(); field.api = api; }))(); if (field.isFormElement && checkObjectKeyExists(field, "validation") && field.validation.triggers.includes("ON_CHANGE")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { yield ruleEngine.run(field.validation); }))(); } if (field.isFormElement && checkObjectKeyExists(field, "connectedElements")) { this.handleConnectedElements({ key: field.key, value: this.formGroup.controls[field.key].value }, "ON_CHANGE"); } this.hideApiLoader(); this.triggerLogs(ELogEventType.FORM__API_RESPONSE_REVERSE_LAT_LONG, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "REVERSE_LAT_LONG_API_SUCCESS", response }); } else { this.triggerLogs(ELogEventType.FORM__API_RESPONSE_REVERSE_LAT_LONG, { api_key: this.apiCallResponse.key, field_key: this.apiCallResponse.key, response_type: "REVERSE_LAT_LONG_API_ERROR" }); const apis = new Apis({ FIELD_CONFIG: field, API_CONFIG: field.api, API_RESPONSE: {}, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { const api = yield apis.validateResponse(); field.api = api; }))(); console.error("Reverse Location for LatLong Failed"); } this.hideApiLoader(); break; default: break; } } if (verifyChange("buttonClickResponse")) { this.buttonClickResponse = changes.buttonClickResponse.currentValue; if (checkObjectKeyExists(this.buttonClickResponse, "key")) { let field = getFormFieldByKey(this.formFields, (_d = this.buttonClickResponse) === null || _d === void 0 ? void 0 : _d.key); if (checkObjectKeyExists(this.buttonClickResponse, "default")) { field.default = getObjectDeepCopy(this.buttonClickResponse.default); delete this.buttonClickResponse.default; } if (checkObjectKeyExists(this.buttonClickResponse, "messages")) { field.messages = getObjectDeepCopy(this.buttonClickResponse.messages); delete this.buttonClickResponse.messages; } if (checkObjectKeyExists(this.buttonClickResponse, "validation")) { field.validation = getObjectDeepCopy(this.buttonClickResponse.validation); delete this.buttonClickResponse.validation; } field = getObjectDeepCopy(mergeObjects(field, this.buttonClickResponse)); if (checkObjectKeyExists(field, "validation")) { if (checkObjectKeyExists(field.validation, "triggers") && field.validation.triggers.includes("ON_RESPONSE")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { yield ruleEngine.run(field.validation); }))(); } } } } if (verifyChange("allFormsData")) { this.allFormsData = changes.allFormsData.currentValue; } if (verifyChange("formConfig")) { this.formConfig = changes.formConfig.currentValue; (() => __awaiter(this, void 0, void 0, function* () { yield this.initFormConfig(this.formConfig); }))(); } } ngOnDestroy() { if (this.activeCameraRecordingTimerSubcription) { this.activeCameraRecordingTimerSubcription.unsubscribe(); } if (this.activeCameraRecordingStateSubcription) { this.activeCameraRecordingStateSubcription.unsubscribe(); } } triggerLogs(eventType, logs) { this.getLogs.emit(formatEventLogs(eventType, this.stepConfig, this.formConfig, getObjectDeepCopy(logs))); } initFormConfig(formConfig) { return __awaiter(this, void 0, void 0, function* () { formConfig = new Converter().convertFormConfig(formConfig); formConfig = new Converter().updateFormConfigProperties(formConfig); this.setFormFieldsFromFormConfig(formConfig); this.setFormFieldGroupsFromFormConfig(formConfig); this.setFormDataFromAllFormsData(); this.formConfig = formConfig; this.triggerLogs(ELogEventType.FORM__CONFIG_LOAD_SUCCESS, Object.assign(Object.assign({}, (formConfig.sequenceNo && { form_sequence_no: formConfig.sequenceNo })), (formConfig.status && { form_status: formConfig.status }))); /** * PRE Form Tasks * 1. API Calls. * 2. Alter Data Structure. * 3. Alter Form Config. */ if (checkObjectKeyExists(this.formConfig, "tasks") && checkObjectKeyExists(this.formConfig.tasks, "pre")) { this.triggerLogs(ELogEventType.FORM__TASK_PRE, {}); for (const preTask of this.formConfig.tasks.pre) { const task = new Tasks(preTask, { FORM_CONFIG: this.formConfig, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); this.stopTaskExecution = false; if (checkObjectKeyExists(preTask, "wait")) { this.waitingForChanges = preTask.wait; } else { this.waitingForChanges = false; } yield task.execute(); // Wait for ngOnChanges to be called before continuing to the next task yield new Promise((resolve) => { const intervalId = setInterval(() => { if (!this.waitingForChanges) { clearInterval(intervalId); resolve(); } }, FORM_VIEW_TIMERS.WAIT_FOR_CHANGES_BEFORE_MOVING_TO_NEXT_TASK); }); if (this.stopTaskExecution) { break; } } this.formData = mergeObjects(this.formData, this.popupFormData); } if (this.stopTaskExecution) { return false; } this.formGroup = yield this.formViewService.createFormGroup(this.formFields, { FORM_CONFIG: this.formConfig, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); /** * For some reason if their a field of type 'IMAGE' then * formData is adding a 'undefined' key with last image's value from the array. * Below piece of code is to remove that redundent value from formData. */ if (checkObjectKeyExists(this.formData, "undefined")) { delete this.formData.undefined; } for (const field of this.formFields) { if (field.isFormElement) { this.previousFormData = Object.assign(Object.assign({}, this.previousFormData), { [field.key]: convertFormFieldValueToStandardFormat(field, this.formGroup.controls[field.key].value) }); this.formData = Object.assign(Object.assign({}, this.formData), { [field.key]: convertFormFieldValueToStandardFormat(field, this.formGroup.controls[field.key].value) }); if (field.type === EFieldType.FILE) { this.files[field.key] = this.formGroup.controls[field.key].value; } if (field.type === EFieldType.CAPTURE) { this.resetCamera(); this.cameraData = Object.assign(Object.assign({}, this.cameraData), { [field.key]: convertFormFieldValueToStandardFormat(field, this.formGroup.controls[field.key].value) }); this.mediaFiles[field.key] = this.formGroup.controls[field.key].value; } if (field.type === EFieldType.RECORD) { this.resetCamera(); this.cameraData = Object.assign(Object.assign({}, this.cameraData), { [field.key]: convertFormFieldValueToStandardFormat(field, this.formGroup.controls[field.key].value) }); this.mediaFiles[field.key] = this.formGroup.controls[field.key].value; } this.formGroup.controls[field.key].valueChanges .pipe(pairwise()) .subscribe(([previousValue, currentValue]) => { this.previousFormData = Object.assign(Object.assign({}, this.previousFormData), { [field.key]: convertFormFieldValueToStandardFormat(field, previousValue) }); this.formData = Object.assign(Object.assign({}, this.formData), { [field.key]: convertFormFieldValueToStandardFormat(field, currentValue) }); if (field.type === EFieldType.FILE) { this.files[field.key] = currentValue; } if (field.type === EFieldType.CAPTURE) { this.resetCamera(); this.cameraData = Object.assign(Object.assign({}, this.cameraData), { [field.key]: convertFormFieldValueToStandardFormat(field, currentValue) }); this.mediaFiles[field.key] = currentValue; } if (field.type === EFieldType.RECORD) { this.resetCamera(); this.cameraData = Object.assign(Object.assign({}, this.cameraData), { [field.key]: convertFormFieldValueToStandardFormat(field, currentValue) }); this.mediaFiles[field.key] = currentValue; } }); } } for (const field of this.formFields) { if (field.isFormElement) { if (checkObjectKeyExists(field, "validation")) { if (field.validation.triggers.includes("ON_INIT")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); yield ruleEngine.run(field.validation); } } if (checkObjectKeyExists(field, "connectedElements")) { this.handleConnectedElements({ key: field.key, value: this.formGroup.controls[field.key].value }, "ON_INIT"); } } } return true; }); } setFormFieldsFromFormConfig(formConfig) { if (checkObjectKeyExists(formConfig, "fields")) { this.formFields = formConfig.fields; } else if (checkObjectKeyExists(formConfig, "multiForm") && checkObjectKeyExists(formConfig.multiForm, "fields")) { this.formFields = formConfig.multiForm.fields; } } setFormFieldGroupsFromFormConfig(formConfig) { this.fieldGroups = formConfig.fieldGroups; } setFormDataFromAllFormsData() { if (checkObjectKeyExists(this.allFormsData, this.formConfig.key)) { const formData = this.allFormsData[this.formConfig.key]; if (checkObjectKeyExists(formData, "data") && checkObjectKeyExists(formData, "extendedData")) { this.formData = Object.assign(Object.assign({}, this.formData), formData.data); } else { this.formData = Object.assign(Object.assign({}, this.formData), formData); } } else { this.formData = {}; } } handleConnectedElementFieldGroupActions(childFieldGroupConfig, parentField) { return __awaiter(this, void 0, void 0, function* () { if (checkObjectKeyExists(childFieldGroupConfig, "rules")) { const rulesMapping = new Rule(childFieldGroupConfig.rules, { FIELD_CONFIG: parentField, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }).mapping(); for (const action of childFieldGroupConfig.actions) { const conditionSuccess = new Condition(action.condition, rulesMapping).evaluate(); if (conditionSuccess) { const actions = new Action(action, rulesMapping, { FIELD_CONFIG: parentField, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeActionOnFieldGroup.bind(this)); yield actions.execute(); } } } }); } handleConnectedElementFieldGroup(currentField, connectedFieldGroupConfig, eventType) { return __awaiter(this, void 0, void 0, function* () { if (checkObjectKeyExists(connectedFieldGroupConfig, "triggers")) { if (connectedFieldGroupConfig.triggers.includes(eventType)) { yield this.handleConnectedElementFieldGroupActions(connectedFieldGroupConfig, currentField); } } }); } handleConnectedElementFieldActions(connectedFieldConfig, connectedField) { return __awaiter(this, void 0, void 0, function* () { if (checkObjectKeyExists(connectedFieldConfig, "rules")) { const rulesMapping = new Rule(connectedFieldConfig.rules, { FIELD_CONFIG: connectedField, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }).mapping(); for (const action of connectedFieldConfig.actions) { const conditionSuccess = new Condition(action.condition, rulesMapping).evaluate(); if (conditionSuccess) { const actions = new Action(action, rulesMapping, { FORM_FIELDS: this.formFields, FIELD_CONFIG: connectedField, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); yield actions.execute(); } } } return connectedField; }); } handleConnectedElementFields(currentField, connectedFieldConfig, eventType, nested) { return __awaiter(this, void 0, void 0, function* () { let connectedField = getFormFieldByKey(this.formFields, connectedFieldConfig.key); if (checkObjectKeyExists(connectedFieldConfig, "triggers")) { if (connectedFieldConfig.triggers.includes(eventType)) { connectedField = yield this.handleConnectedElementFieldActions(connectedFieldConfig, connectedField); } } if (checkObjectKeyExists(connectedFieldConfig, "handleNestedFields")) { if (connectedFieldConfig.handleNestedFields) { this.handleConnectedElements({ key: connectedFieldConfig.key }, eventType); } } return currentField; }); } handleConnectedElements(e, eventType) { return __awaiter(this, void 0, void 0, function* () { let currentField = getFormFieldByKey(this.formFields, e.key); if (currentField !== undefined) { if (checkObjectKeyExists(currentField, "connectedElements")) { if (checkObjectKeyExists(currentField.connectedElements, "connectedFieldGroups")) { const { connectedFieldGroups } = currentField.connectedElements; for (const connectedFieldGroupConfig of connectedFieldGroups) { yield this.handleConnectedElementFieldGroup(currentField, connectedFieldGroupConfig, eventType); } } if (checkObjectKeyExists(currentField.connectedElements, "connectedFields")) { const { connectedFields } = currentField.connectedElements; for (const connectedFieldConfig of connectedFields) { currentField = yield this.handleConnectedElementFields(currentField, connectedFieldConfig, eventType, eventType); } } } } else { throw new Error(`Field for the given key ['${e.key}'] is not found with eventType: '${eventType}'.`); } }); } handleRemovedFile(e) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; this.showApiLoader(); if (this.formGroup.controls[e.key].enabled) { this.files[e.key] = e.files; this.formData[e.key] = filterDuplicatesFiles(this.files[e.key]); this.formGroup.patchValue({ [e.key]: this.formData[e.key] }, { emitEvent: false }); } this.triggerLogs(ELogEventType.FORM__FIELD_FILE_REMOVE, Object.assign(Object.assign(Object.assign({ field_key: e.key }, ((_b = (_a = e.file) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : { file_name: (_c = e.file) === null || _c === void 0 ? void 0 : _c.name })), ((_e = (_d = e.file) === null || _d === void 0 ? void 0 : _d.size) !== null && _e !== void 0 ? _e : { file_size: (_f = e.file) === null || _f === void 0 ? void 0 : _f.size })), ((_h = (_g = e.file) === null || _g === void 0 ? void 0 : _g.type) !== null && _h !== void 0 ? _h : { file_type: (_j = e.file) === null || _j === void 0 ? void 0 : _j.type }))); this.hideApiLoader(); } handleViewButtonClick(e, field) { this.onClickViewFile.emit({ key: field === null || field === void 0 ? void 0 : field.key, type: field === null || field === void 0 ? void 0 : field.type, payload: { field, event: e } }); } handleGetKeyValueFile(e) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; return __awaiter(this, void 0, void 0, function* () { this.showApiLoader(); const field = getFormFieldByKey(this.formFields, e.key); const values = Array.isArray(e.value) ? e.value : [e.value]; if (checkObjectKeyExists(field, "properties") && checkObjectKeyExists(field.properties, "uploadFileToServer") && field.properties.uploadFileToServer) { for (const value of values) { yield this.uploadFile(field, value); } } else { for (const value of values) { this.updateFiles(value, "LOADING", e.key); this.triggerLogs(ELogEventType.FORM__FIELD_FILE_ADD, Object.assign(Object.assign(Object.assign({ field_key: e.key }, ((_b = (_a = e.file) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : { file_name: (_c = e.file) === null || _c === void 0 ? void 0 : _c.name })), ((_e = (_d = e.file) === null || _d === void 0 ? void 0 : _d.size) !== null && _e !== void 0 ? _e : { file_size: (_f = e.file) === null || _f === void 0 ? void 0 : _f.size })), ((_h = (_g = e.file) === null || _g === void 0 ? void 0 : _g.type) !== null && _h !== void 0 ? _h : { file_type: (_j = e.file) === null || _j === void 0 ? void 0 : _j.type }))); const updatedFile = getObjectDeepCopy(yield new Promise((resolve) => { setTimeout(() => { resolve({ id: uuidv4(), name: value.name, type: value.type, size: value.size, lastModified: value.lastModified, webkitRelativePath: value.webkitRelativePath }); }, FORM_VIEW_TIMERS.WAIT_FOR_FILE_METADATA_DEEPCOPY); // 1000 ms = 1 sec })); this.updateFiles(updatedFile, "NORMAL", e.key); } this.hideApiLoader(); } }); } /** Methods for Camera related fields like 'CAPTURE' or 'RECORD' */ handleOnClickGetRemovedMediaFile(e) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (this.formGroup.controls[e.key].enabled) { this.showApiLoader(); const field = getFormFieldByKey(this.formFields, e.key); this.resetCamera(); this.mediaFiles[e.key] = e.mediaFiles; this.formData[e.key] = filterDuplicatesMediaFiles(this.mediaFiles[e.key]); this.cameraData[e.key] = convertFormFieldValueToStandardFormat(field, this.formData[e.key]); this.formGroup.patchValue({ [e.key]: this.formData[e.key] }, { emitEvent: false }); this.triggerLogs(ELogEventType.FORM__FIELD_MEDIA_FILE_REMOVE, Object.assign(Object.assign(Object.assign({ field_key: e.key }, ((_b = (_a = e.file) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : { file_name: (_c = e.file) === null || _c === void 0 ? void 0 : _c.name })), ((_e = (_d = e.file) === null || _d === void 0 ? void 0 : _d.size) !== null && _e !== void 0 ? _e : { file_size: (_f = e.file) === null || _f === void 0 ? void 0 : _f.size })), ((_h = (_g = e.file) === null || _g === void 0 ? void 0 : _g.type) !== null && _h !== void 0 ? _h : { file_type: (_j = e.file) === null || _j === void 0 ? void 0 : _j.type }))); this.getUnsavedDataState.emit(true); if (field.isFormElement && checkObjectKeyExists(field, "validation") && field.validation.triggers.includes("ON_CHANGE")) { const ruleEngine = new RuleEngine({ FIELD_CONFIG: field, FORM_FIELDS: this.formFields, FORM_DATA: this.formData, CAMERA_DATA: this.cameraData, TASK_DATA: this.taskData, PREVIOUS_FORM_DATA: this.previousFormData, ALL_FORMS_DATA: this.allFormsData, EXTRA_DATA: this.extraData }, this.takeAction.bind(this)); (() => __awaiter(this, void 0, void 0, function* () { yield ruleEngine.run(field.validation); }))(); } if (field.isFormElement && checkObjectKeyExists(field, "connectedElements")) { this.handleConnectedElements({ key: field.key, value: this.formGroup.controls[field.key].value }, "ON_CHANGE"); } setTimeout(() => { this.hideApiLoader(); }, 500); } } handleOnClickInputCamera(e, field) { var _a, _b, _c, _d, _e, _f; return __awaiter(this, void 0, void 0, function* () { this.loaderService.show({ loaderText: "Loading Camera...", fullscreen: true }); const fieldKey = field.key; const fie