kwikid-forms
Version:
KwikID's JSON Configuration based Forms Renderer and Builder
908 lines • 626 kB
JavaScript
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