@rangertechnologies/ngnxt
Version:
This library was used for creating dymanic UI based on the input JSON/data
698 lines • 126 kB
JavaScript
import { Component, Input, Output, EventEmitter, ViewChild, } from "@angular/core";
import { QuestionbookComponent } from "../questionbook/questionbook.component";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";
import * as i0 from "@angular/core";
import * as i1 from "../../services/salesforce.service";
import * as i2 from "../../services/data.service";
import * as i3 from "../../services/storage.service";
import * as i4 from "@angular/router";
import * as i5 from "@angular/platform-browser";
import * as i6 from "../../services/change.service";
import * as i7 from "../../i18n.service";
import * as i8 from "@angular/common/http";
import * as i9 from "@angular/common";
export class BookletComponent {
sfService;
dataService;
storageService;
route;
sanitizer;
changeService;
i18nService;
http;
bookletId;
serv;
tkn;
bookletJSON;
dropdownDependentData;
labelValue;
token;
languageCode; // VD 11Jun24 - translation changes
fieldRestrictions; // VD 12Jun24 - field permission change
from; // Form Builder dependent change
apiUrl; // AP-16APR25 Input property to receive the API URL from the parent component
isEdit; // AP-19MAY25 - Added isEdit input
handleBookletActionEvent = new EventEmitter();
handlePage = new EventEmitter();
hadleDropDownDependent = new EventEmitter();
// VD 06Sep24 calendar changes
handleCalendarDate = new EventEmitter();
handleCalendarEvent = new EventEmitter();
nxtBooklet;
booklet = [];
abItem = {};
actions = [];
bookQuestionsMap = new Map();
translateMap = new Map(); // VD 11Jun24 - translation changes
sqOptions = new Map();
isAnswerFlag = false;
spinnerName;
spinnerType;
// HA 19DEC23 langDirection variable is created to assign the direction as class
langDirection = 'ltr'; // HA 28DEC23 making ltr as default direction
answerList = []; // HA 11-JAN-24 Answerlist to store the minimal value
dataBind; // HA 18-JAN-24 To insert the endpoint value to the question
allEvents = []; // VD 06Sep24 calendar changes
//AP-19MAY25 - Accessing the QuestionbookComponent instance using ViewChild reference
questionbookComponent;
constructor(sfService, dataService, storageService, route, sanitizer, changeService, el, i18nService, http) {
this.sfService = sfService;
this.dataService = dataService;
this.storageService = storageService;
this.route = route;
this.sanitizer = sanitizer;
this.changeService = changeService;
this.i18nService = i18nService;
this.http = http;
this.spinnerName = "sp1";
this.spinnerType = "ball-spin-clockwise";
}
ngOnInit() {
// VD 12Jan24 fieldRestrictions formate
// {
// "fields" : {
// "transQb-01" : "readOnly",
// "TransFir02" : "",
// "TransLast03" : "readOnly",
// "bk2-q2" : "hide"
// }
// }
// HA 18-JAN-24 Dummy Static data for testing
// this.dataBind = {
// "_id": "659ed002ed51bb8061544255",
// "companyId": "5ullh1BWpYqnvzKh9L",
// "name": "Al Yasmine",
// "code": "check",
// "status": "In-Progress",
// "createdAt": "2024-01-10T17:12:34.686Z",
// "updatedAt": "2024-01-10T19:53:08.135Z",
// "__v": 0,
// "owner": "check",
// "customer": "check",
// "dati": "2024-01-23T18:30:00.000Z",
// "timi": "2024-01-23T18:30:00.000Z",
// "fName": "Haider",
// "lName": "Ali",
// "defaultApp": "NXT",
// "email": "haider@gmail.com",
// "location": {address: "107, Ashok Nagar, Kadugondanahalli, Bengaluru, Karnataka 560045, India",
// latitude: 13.0200575,
// longitude: 77.6129816},
// "location": "107, Ashok Nagar, Kadugondanahalli, Bengaluru, Karnataka 560045, India",
// "textArea": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
// };
this.processBooklet();
//AP-16APR25 // Get the dynamic API URL and pass it to the service method
let apidata = this.apiUrl;
this.dataService.apikey(apidata);
}
// VD NOV23 - update the json data when bookletId and bookletJSON changes
ngOnChanges(simplechanges) {
// HA 23JAN24 To avoid undefined error
if (simplechanges['bookletId'] || (simplechanges['bookletJSON'] && simplechanges['bookletJSON'].currentValue != null) || (simplechanges['dataBind'] && simplechanges['dataBind'].currentValue != null)) {
this.allEvents = [];
this.processBooklet();
}
//AP-19MAY25 - If bookletJSON input changes, trigger processData on QuestionbookComponent
if (simplechanges['bookletJSON']) {
const currentValue = simplechanges['bookletJSON'].currentValue;
//AP-28MAY25 - If the action is a string, upgrade it to the new action model (array of objects)
if (currentValue?.questionbook?.action && typeof currentValue.questionbook.action === 'string') {
currentValue.questionbook.action = this.upgradeActions(currentValue.questionbook.action);
}
if (this.questionbookComponent) {
this.questionbookComponent.processData();
}
}
}
// AP-28MAY25 - Converts old action string (JSON) into a new model (array of action objects)
upgradeActions(actionString) {
try {
// Try to parse the action string to JSON
const parsed = JSON.parse(actionString);
// AP-28MAY25 If parsed result is an array, apply default styles and adjust position
if (Array.isArray(parsed)) {
return parsed.map((item, index) => ({
...item,
positionPercent: item.name === 'Cancel' ? 3 : 14, // Set position based on action name
width: 100,
textColor: '#ffffff',
borderRadius: 6,
id: index
}));
}
}
catch (e) {
console.error("Invalid JSON action format", e);
}
return [];
}
processBooklet() {
if (this.bookletId) {
if (this.bookletId.length == 18) {
this.readBooklet(this.bookletId);
}
}
else if (this.bookletJSON) {
// Try to pass a value from Backend to differentiate the QuestionBook Read and AnswerBook Read
this.isAnswerFlag = true;
if (this.bookletJSON != null && this.bookletJSON != undefined && this.bookletJSON?.bookQuestionsMap) {
// SKS28MAR25 get the nested reference qb
let tempbook = this.bookletJSON?.bookQuestionsMap[Object.keys(this.bookletJSON?.bookQuestionsMap)[0]].subQuestions;
tempbook.forEach((element) => {
if (element.type === "book" && element?.qbReference) {
this.getRefQbData(element?.qbReference).subscribe((response) => {
element['qbReferenceQuestions'] = response; // Assign response to qbReferenceQuestions
}, (error) => {
console.error("API Error:", error);
});
}
});
this.bookletJSON['bookQuestionsMap'][Object.keys(this.bookletJSON?.bookQuestionsMap)[0]].subQuestions = tempbook;
// Storing the API response for future use
this.storageService.save(this.bookletJSON);
}
this.booklet = this.bookletJSON?.records;
this.abItem = this.bookletJSON?.answerbook;
// Process the Sub Question Options - This should be merged with bookQuestionsMap in future
for (var sq in this.bookletJSON?.sqOptions) {
this.sqOptions.set(sq, this.bookletJSON?.sqOptions[sq]);
}
// Process the Questions
// HA 28DEC23 this applies for booklet
// HA 17JAN24 Added ternary operator to avoid undefined scenario
// HA 09FEB24 Adding condition to avoid undefined error
if (this.bookletJSON?.bookQuestionsMap && Object.keys(this.bookletJSON?.bookQuestionsMap).length > 0) {
for (var value in this.bookletJSON?.bookQuestionsMap) {
this.bookQuestionsMap.set(value, this.bookletJSON?.bookQuestionsMap[value]);
}
}
// HA 28DEC23 this applies for book or questions
else if (this.bookletJSON?.records) {
var value = '';
// HA 09FEB24 Added ternary
// RS 09DEC24 Changed keys
value = this.bookletJSON?.records[0]?.id;
this.bookQuestionsMap.set(value, this.bookletJSON?.questionbook);
}
// VD 20Jun24 - translation changes
for (var value in this.bookletJSON?.translationMap) {
this.translateMap.set(value, this.bookletJSON?.translationMap[value]);
}
// AP 23MAY25 - supports both stringified and object formats
if (this.bookletJSON?.questionbook?.action != undefined && this.bookletJSON?.questionbook?.action != '') {
this.actions = typeof this.bookletJSON?.questionbook.action === 'string'
? JSON.parse(this.bookletJSON?.questionbook.action)
: this.bookletJSON?.questionbook.action;
}
}
// HA 19DEC23 langDirection variable value assigning
// RS 09DEC24 Changed keys
if (this.bookletJSON?.questionbook?.style) {
var style = typeof this.bookletJSON?.questionbook?.style === 'object' ? this.bookletJSON?.questionbook?.style : JSON.parse(this.bookletJSON?.questionbook?.style);
this.langDirection = style?.direction;
}
else if (this.bookletJSON?.records && this.bookletJSON?.records[0]?.style) {
var style = typeof this.bookletJSON?.records[0]?.style === 'object' ? this.bookletJSON?.records[0]?.style : JSON.parse(this.bookletJSON?.records[0]?.style);
this.langDirection = style?.direction;
}
// HA 18-JAN-24 The condition is used for Bind-In Logic
this.handleCompleteBooklet(this.bookletJSON);
}
// VD 12Jun24 - translation changes
readBooklet = (uuid) => {
if (this.serv == "api") {
this.dataService.getAPIData(this.tkn, ["Booklet", "read", uuid, this.languageCode], this.successReadBooklet, this.failureReadBooklet);
}
else {
// VD 31NOV24 param changes with new method
let paramMap = { createAnswerBookFlag: false };
paramMap['c__qb_id'] = '';
paramMap["c__record_id"] = '';
let para = {
dataType: "Booklet",
operation: "read",
param1: uuid,
paramJSON: JSON.stringify(paramMap),
languageCode: this.languageCode
};
this.sfService.remoteAction("NxtController.processData", [JSON.stringify(para)], this.successReadBooklet, this.failureReadBooklet);
}
};
successReadBooklet = (response) => {
console.log('Inside the successReadBooklet');
if (response != null || response != undefined) {
// Storing the API response for future use
this.storageService.save(response);
// Try to pass a value from Backend to differentiate the QuestionBook Read and AnswerBook Read
// this.isAnswerFlag = true;
this.booklet = response.records;
this.abItem = response.answerbook;
// Process the Sub Question Options - This should be merged with bookQuestionsMap in future
for (var sq in response.sqOptions) {
this.sqOptions.set(sq, response.sqOptions[sq]);
}
// Process the Questions
for (var value in response.bookQuestionsMap) {
this.bookQuestionsMap.set(value, response.bookQuestionsMap[value]);
}
// VD 11Jun24 - translation changes
for (var value in response.translationMap) {
this.translateMap.set(value, response.translationMap[value]);
}
// VD 31NOV24 wrapper changes
if (response.questionbook?.action != undefined) {
this.actions = typeof response.questionbook?.action === 'string'
? JSON.parse(response.questionbook?.action)
: response.questionbook?.action;
}
}
// HA 19DEC23 langDirection variable value assigning
if (response?.questionbook?.style) {
var style = typeof response?.questionbook?.style === 'object' ? response?.questionbook?.style : JSON.parse(response?.questionbook?.style);
this.langDirection = style?.direction;
}
else if (response?.records[0]?.style) {
var style = typeof response?.records[0]?.style === 'object' ? response?.records[0]?.style : JSON.parse(response?.records[0]?.style);
this.langDirection = style?.direction;
}
};
failureReadBooklet = (response) => {
};
//SKS28MAR25 Function to fetch refqb data
getRefQbData(refqbid) {
return this.http.get(`https://dev-api.valarhr.com/nxt?name=${refqbid}`);
}
singleFieldChange(event) {
console.log("single FieldChange", event);
let actionButton;
this.actions.forEach(action => {
if (action.eventtoemit === 'submit') {
actionButton = action;
}
});
this.handleBookletActionClick(actionButton, event);
}
handleBookletActionClick(action, ques) {
// HA 19JAN24 Action changes
// RS 09DEC24 Changed keys
this.answerList = [];
this.dataBind = []; // HA 12FEB24 Clearing dataBind upon button action so that dataBind value will not override the changed value
let dataToParent = {};
let validForm = true; // VD 01Aug24 - validation change
let isPrimaryKey = false;
let primaryKeyElement;
let dependentElementArray = [];
// HA 22JAN24 this change to make close event work
dataToParent['action'] = action.eventtoemit;
if (!(action.eventtoemit === 'close' || action.eventtoemit === 'print')) {
// HA 18-JAN-24 Sending the complete json data also
dataToParent['jsonBook'] = this.storageService.get();
// HA 17JAN24 nxtId to dataParent object
if (this.bookletJSON) {
dataToParent['nxtId'] = Object.keys(this.bookletJSON?.bookQuestionsMap)[0];
}
// HA 11-JAN-24 Minimizing the value which has to be passed to the server
this.handleCompleteBooklet(dataToParent['jsonBook']);
dataToParent['data'] = this.answerList ? this.answerList : dataToParent['data'];
// when clicking the submit button validating the required fields
for (let key in dataToParent['jsonBook'].bookQuestionsMap) {
const currentBook = dataToParent['jsonBook'].bookQuestionsMap[key];
currentBook.subQuestions.forEach(element => {
if (!isPrimaryKey) {
if (element?.primaryKey === true && element?.input !== undefined && element?.input !== '' && element?.input !== null) {
isPrimaryKey = true;
primaryKeyElement = element;
if (ques?.subText?.sourceQuestionId !== undefined && ques?.subText?.sourceQuestionId !== null && ques?.subText?.sourceQuestionId !== '' && !ques?.subText?.isDependentField) {
}
else if (ques?.subText?.sourceQuestionId !== undefined && ques?.subText?.sourceQuestionId !== null && ques?.subText?.sourceQuestionId !== '' && ques?.subText?.isDependentField) {
}
else {
currentBook.subQuestions.forEach(ele => {
if (ques?.id && ques?.id === ele?.subText?.sourceQuestionId) {
dependentElementArray.push(ele.id);
}
});
}
}
}
// VD 01Aug24 - validation change
if (element.isOptional && dataToParent['action'] == 'submit' && (!element.input || (Array.isArray(element.input) && element.input.length === 0)) && !element.isHidden && element.type != 'Label' && element.type != 'Image') { //SKS5NOV25
element.error = true;
validForm = false;
this.changeService.submitChange(element.id);
}
// VD 02Aug24 - clear action changes
if (dataToParent['action'] == 'clear') {
if (element.type == 'Dropdown' || element.type == 'Location' || element.type == 'Radio') {
element.selectedValue = undefined;
}
else if (element.type == 'File') {
element.input = [];
}
else {
element.input = '';
}
}
});
}
}
// VD 13MAY24 - print QR button changes
if (action.eventtoemit === 'print') {
dataToParent['actionData'] = action['data'];
}
// MSM 17JUN25 - Close button event changes
if (action.eventtoemit === 'close' && this.isEdit) {
this.isEdit = false;
}
// HA 23JAN24 To call the action on any event
// VD 01Aug24 - validation change
if (validForm) {
// SKS13JUN25 single field change emit
if (ques && ques.singleFieldChange) {
dataToParent.data = dataToParent.data.filter((inputData) => inputData.id === ques.id || inputData.id === primaryKeyElement?.id || dependentElementArray.includes(inputData.id));
}
if (isPrimaryKey) {
dataToParent.action = 'save';
}
this.handleBookletActionEvent.emit(dataToParent);
}
else {
dataToParent['action'] = 'error';
this.handleBookletActionEvent.emit(dataToParent);
}
}
// HA 18-JAN-24 handleCompleteBooklet is to simplify the logic
handleCompleteBooklet(completeBooklet) {
if (Object.keys(completeBooklet?.bookQuestionsMap ?? {}).length === 0) { // HA 11-JAN-24 If condition to load booklet
this.handleBook(completeBooklet?.questionbook?.subQuestions);
}
else { // HA 11-JAN-24 To load book questions
for (const key in completeBooklet.bookQuestionsMap) {
const val = completeBooklet.bookQuestionsMap[key];
if (val.type === 'Book') {
this.handleBook(val.subQuestions);
}
else {
this.handleQues(val);
}
}
}
}
// HA 11-JAN-24 handleBook loads the Book
// RS 09DEC24 Changed keys
handleBook(quesList) {
quesList?.forEach(element => {
if (element.type === 'Book' && element.qbReferenceQuestions) {
// HA 24JAN24 Fetching from QB reference
var book = typeof element.qbReferenceQuestions === 'object' ? element.qbReferenceQuestions : JSON.parse(element.qbReferenceQuestions);
const firstKey = Object.keys(book?.bookQuestionsMap || {})[0];
book?.bookQuestionsMap[firstKey]?.subQuestions?.forEach(ques => {
this.handleQues(ques);
});
}
else {
this.handleQues(element);
}
});
// VD 13Sep24 - databind changes
// VD 23 Oct24 - file type changes
if (this.dataBind && Object.keys(this.dataBind).length > 0) {
this.changeService.dataChanges('dataBind');
}
}
// SKS20MAR25 flattening nested objects, mapping values using referenceField
flattenObject(obj, parentKey = '', includeObjects = true) {
let result = [];
for (let [key, val] of Object.entries(obj)) {
let newKey = parentKey ? `${parentKey}.${key}` : key;
if (Array.isArray(val)) {
result.push([newKey, val]); // Include full array
val.forEach((item, index) => {
if (typeof item === 'object' && item !== null) {
result.push(...this.flattenObject(item, `${newKey}[${index}]`, false)); // Flatten objects in arrays
}
else {
result.push([`${newKey}[${index}]`, item]); // Store primitive values in arrays
}
});
}
else if (typeof val === 'object' && val !== null) {
if (includeObjects) {
result.push([newKey, val]); // Include full object
}
result.push(...this.flattenObject(val, newKey, false)); // Flatten nested objects
}
else {
result.push([newKey, val]); // Store key-value pairs
}
}
return result;
}
// SKS20MAR25 referenceField set like this
// name --> normal
// items[0].name --> value in a array set like this
// addresses.line2 ---> if value in a json set like this
// addresses.line4.dd ---> if value in a nested json set like this
// HA 11-JAN-24 handleQues to load question
// VD 06Sep24 calendar changes
handleQues(ques) {
// HA 19-JAN-24 If condition is for bind-in, correction
// HA 09FEB24 Adding condition to avoid undefined error
if (this.dataBind && Object.keys(this.dataBind).length > 0) {
let result = this.flattenObject(this.dataBind);
let found = false;
for (let [key, val] of result) {
let value = val;
if (ques.referenceField === key) {
found = true;
if (ques.type === 'Dropdown' || ques.type === 'Radio') {
this.sqOptions.forEach(element => {
if (element['referenceField'] === key) {
element['input'] = ques.input = value || ques.defaultValue;
element['selectedValue'] = ques.selectedValue = value || ques.defaultValue;
}
});
}
// HA 24JAN24 To bind-in Date and DateTime
else if (ques.type === 'Date' || ques.type == 'DateTime') {
ques.input = new Date(value?.toString()) || ques.defaultValue;
}
// HA 12FEB24 To bind-in Location Type
else if (ques.type === 'Location') {
ques.input = value || ques.defaultValue;
ques.selectedValue = value['address'] ? value['address'] : value || ques.defaultValue;
}
// VD 06Sep24 calendar changes for data bindIn
else if (ques.type === 'Calendar') {
let entries = typeof ques['fieldsMeta'] === 'object' ? ques['fieldsMeta'] : JSON.parse(ques['fieldsMeta']);
if (entries) {
let referenceQuestions = [];
if (entries.length > 0) {
entries.forEach(element => {
if (element.questionReference) {
let qReference = JSON.parse(element.questionReference);
referenceQuestions.push(qReference?.question);
}
});
}
if (referenceQuestions.length > 0) {
value?.forEach(calendarArray => {
let date = new Date(calendarArray.date);
calendarArray.entries.forEach(inputEntry => {
for (let [k, v] of Object.entries(inputEntry)) {
referenceQuestions.forEach(field => {
if (field.referenceField == k) {
if (field.type === 'Date' || field.type == 'DateTime' || field.type == 'Time') {
field.input = new Date(v?.toString()) || ques.defaultValue;
}
if (field.type === 'Dropdown' || field.type === 'Radio') {
field.selectedValue = v;
field.input = v || ques.defaultValue;
}
else {
field.input = v || ques.defaultValue;
}
}
});
}
this.addEvent(date, referenceQuestions); //SKS 27SEP24 each event added to allEvents array
});
// this.addEvent(date,referenceQuestions); //this is only last event added to allEvents array
});
}
}
ques.input = this.allEvents.length > 0 ? this.allEvents : '';
}
// VD 23 Oct24 - file type changes
else if (ques.type === 'File') {
ques.input = [];
ques.input = value;
}
else {
ques.input = value || ques.defaultValue;
}
this.answerList.push(ques); // HA 12FEB24 To give the value for data
break; // AP-03JUN25 - Match found and value bound; no need to continue the loop
}
}
if (!found) {
ques.input = '';
}
}
else {
const question = {};
question['id'] = ques.id;
question['input'] = ques.input || ques.defaultValue || '';
// HA 12FEB24 To bind-out Location Type
if (ques.type === 'Location') {
question['input'] = ques.input ? ques.input : ques.selectedValue || '';
}
else if (ques.type == 'File') {
// VD 23 Oct24 - file type changes
question['input'] = ques.input ? ques.input : ques.defaultValue || [];
}
question['type'] = ques.type;
question['questionNumber'] = ques.questionNumber;
question['referenceField'] = ques?.referenceField;
question['selectedValue'] = ques?.selectedValue; // MR 31JAN24 Need to pass the selected value too
this.answerList.push(question);
}
}
// VD 06Sep24 calendar changes for data bindIn
addEvent(day, entryQues) {
// Transform new entries into the desired format
const newEntries = entryQues.reduce((acc, q) => {
acc[q.id] = { ...q };
return acc;
}, {});
// Find if an event already exists for the given date
const existingEvent = this.allEvents.find(event => event.date.toDateString() === day.toDateString());
if (existingEvent) {
// If the event exists, push the new entries to the existing entries
const existingEntries = existingEvent.entries.map(entry => ({ ...entry }));
existingEntries.push(newEntries);
existingEvent.entries = existingEntries;
}
else {
// Create a new event if it doesn't exist for the given date
const newEvent = {
id: '_' + Math.random().toString(36).substr(2, 9),
date: day,
entries: [newEntries] // Wrap the new entries in an array
};
this.allEvents.push(newEvent);
}
}
readQuestions(qbId) {
let questions = [];
// HA 31-JAN-24 Added ternary to avoid undefined
for (var sq in this.bookQuestionsMap?.get(qbId)?.subQuestions) {
// AP-14MAY25 Extracted question from subQuestions into variable 'q'
let q = this.bookQuestionsMap?.get(qbId).subQuestions[sq];
// HA 09FEB24 if question is there process
if (q) {
if ((q.type == 'Dropdown' || q.type == 'Radio') && this.sqOptions.get(q.id)) {
questions.push(this.sqOptions.get(q.id));
}
else {
questions.push(q);
}
}
}
// VD 12Jun24 field permisision changes
if (this.fieldRestrictions) {
const fieldRestrictions = new Map(Object.entries(this.fieldRestrictions.fields));
questions.forEach(ques => {
const restriction = fieldRestrictions.get(ques.uniqueIdentifier);
if (restriction) {
ques.isReadOnly = restriction === 'readOnly';
ques.isHidden = restriction === 'hide';
}
});
}
return questions;
}
// VD 11Jun24 - translation changes
readTransQuestions(qbId) {
let record = [];
let translateRecord = this.translateMap.get(qbId);
if (translateRecord && translateRecord.length > 0) {
translateRecord.forEach(lanRec => {
if (lanRec.languageCode == this.languageCode) {
record = lanRec.fields;
}
});
}
return record;
}
getText(value) {
var doc = new DOMParser().parseFromString(value, "text/html");
return this.sanitizer.bypassSecurityTrustHtml(doc.documentElement.textContent);
}
getDropDown(event) {
this.hadleDropDownDependent.emit(event);
}
// VD 06Sep24 calendar changes
getCalendarDate(event) {
this.handleCalendarDate.emit(event);
}
getCalendarEvent(event) {
event["nxtId"] = Object.keys(this.bookletJSON?.bookQuestionsMap)[0];
this.handleCalendarEvent.emit(event);
}
editChangeClick(action) {
this.isEdit = true;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookletComponent, deps: [{ token: i1.SalesforceService }, { token: i2.DataService }, { token: i3.StorageService }, { token: i4.ActivatedRoute }, { token: i5.DomSanitizer }, { token: i6.ChangeService }, { token: i0.ElementRef }, { token: i7.I18nService }, { token: i8.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: BookletComponent, isStandalone: true, selector: "lib-booklet", inputs: { bookletId: "bookletId", serv: "serv", tkn: "tkn", bookletJSON: "bookletJSON", dropdownDependentData: "dropdownDependentData", labelValue: "labelValue", token: "token", languageCode: "languageCode", fieldRestrictions: "fieldRestrictions", from: "from", apiUrl: "apiUrl", isEdit: "isEdit", dataBind: "dataBind" }, outputs: { handleBookletActionEvent: "handleBookletActionEvent", handlePage: "handlePage", hadleDropDownDependent: "hadleDropDownDependent", handleCalendarDate: "handleCalendarDate", handleCalendarEvent: "handleCalendarEvent" }, viewQueries: [{ propertyName: "questionbookComponent", first: true, predicate: ["questionbook"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Booklet Handling-->\n<!-- HA 19DEC23 For Direction -->\n<div *ngFor=\"let qb of booklet\" [ngClass]=\"langDirection\">\n <!-- MR Commented below code to ensure single JSON for UNCONDITIONAL Booklets -->\n <!-- RS 09DEC24 Changed keys-->\n <!-- <lib-questionnaire [serv]=\"serv\" [qbId]=\"qb.id\" [tkn]=\"tkn\"></lib-questionnaire> -->\n <!-- HA 28DEC23 Below If logic is to load from booklet -->\n <div *ngIf=\"qb.subQuestions; else elseBlock\">\n <div *ngFor=\"let ques of qb.subQuestions\" class=\"questiondiv1\">\n <div>\n <!-- HA 17JAN24 - Is title is enabled so that based on the boolean div will be visible -->\n <div *ngIf=\"ques.isTitle\" [class]=\"qb.isShengel ? 'header-style' : 'question-f-size additional'\">\n <!-- VD 08NOV23 - showing label when its available-->\n <div [innerHTML]=\"getText(ques?.questionText)\" *ngIf=\"ques?.questionText && ques?.style?.showLabel !== false\" >\n {{ ques?.questionText }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!--VD 11Jun24 - translation changes-->\n <!--VD 06Sep24 calendar changes-->\n <!-- AP-14MAY25 - Added [dataBind] input binding -->\n <!-- AP-19MAY25 - Added [isEdit] binding --> \n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\"\n [labelValue]=\"labelValue\"\n [questionItem]=\"ques\"\n [translatedQuestions]=\"readTransQuestions(qb.id)\"\n [questions]=\"readQuestions(qb.id)\"\n (handleDropDown)=\"getDropDown($event)\"\n (handleCalendarDate)=\"getCalendarDate($event)\"\n (handleCalendarEvent)=\"getCalendarEvent($event)\"\n (singleFieldChangeEmit) ='singleFieldChange($event)'\n [dataBind]=\"dataBind\"\n [isEdit]=\"isEdit\" \n ></lib-questionbook>\n </div>\n </div>\n </div>\n <!-- HA 28DEC23 Below else logic is to load from books or questions -->\n <ng-template #elseBlock>\n <div class=\"questiondiv1\">\n <div>\n <div *ngIf=\"!qb.isTitle\" [class]=\"qb.isShengel ? 'header-style' : 'question-f-size additional'\">\n <!-- VD 08NOV23 - showing label when its available-->\n <div [innerHTML]=\"getText(qb?.questionText)\" *ngIf=\"qb?.questionText && qb?.style?.showLabel !== false\" >\n {{ qb?.questionText }}\n {{ qb?.title }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!-- // VD 11Jun24 - translation changes-->\n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\" [labelValue]=\"labelValue\" [questionItem]=\"qb\" [translatedQuestions]=\"readTransQuestions(qb.id)\" [questions]=\"readQuestions(qb.id)\" (handleDropDown)=\"getDropDown($event)\"></lib-questionbook>\n </div>\n </div>\n </ng-template>\n\n <!-- RS 09DEC24 Changed keys-->\n <!-- Group Actions -->\n <!-- HA 19DEC23 For Direction -->\n <!-- AP 23MAY25 - Action Buttons: Dynamically positioned buttons with JSON-configured styles -->\n <div class=\"align-submit-row\" *ngIf=\"abItem?.status != 'Completed'\" [ngClass]=\"langDirection\"> <!-- position-relative removed in this tag-->\n <ng-container *ngFor=\"let action of actions; let i = index\">\n <div class=\"action-wrapper\"\n [style.width.px]=\"action.width || 100\"\n style=\"margin-right: 10px;\"> <!-- style=\"position: absolute; [style.left.%]=\"action.positionPercent || 0\" removed in this tag -->\n @if(!isEdit && action.eventtoemit === 'submit'){\n <button \n (click)=\"editChangeClick(action)\" \n class=\"btn btn-primary fc-button nxtButton action-btn\"\n [style.--btn-bg]=\"action.bgColor\"\n [style.background-color]=\"action.bgColor || ''\"\n [style.color]=\"action.textColor || ''\"\n [style.border-radius.px]=\"action.borderRadius || 4\"\n style=\"width: 100%;\">\n Edit All\n </button>\n }\n @else {\n <button \n (click)=\"handleBookletActionClick(action)\" \n class=\"btn btn-primary fc-button nxtButton action-btn\"\n [style.--btn-bg]=\"action.bgColor\"\n [style.background-color]=\"action.bgColor || ''\"\n [style.color]=\"action.textColor || ''\"\n [style.border-radius.px]=\"action.borderRadius || 4\"\n style=\"width: 100%;\">\n {{ action.name }}\n </button>\n }\n </div>\n </ng-container>\n </div>\n</div>", styles: [".align-submit-row{display:flex}.header-style{padding:15px;background:#f8f8f8;color:#898989;border:1px solid #e8e8e8;border-top-left-radius:5px;border-top-right-radius:5px;margin-left:0;justify-content:left;font-size:15px}.rtl{flex-direction:row-reverse}.action-btn{width:100%;height:40px;transition:all .3s ease}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: QuestionbookComponent, selector: "lib-questionbook", inputs: ["qbItem", "questionItem", "translatedQuestions", "questions", "errorFieldId", "labelValue", "token", "isEdit", "dropDownData", "dataBind"], outputs: ["handleDropDown", "handleQuestion", "singleFieldChangeEmit", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookletComponent, decorators: [{
type: Component,
args: [{ selector: 'lib-booklet', standalone: true, imports: [
CommonModule,
FormsModule,
QuestionbookComponent
], template: "<!-- Booklet Handling-->\n<!-- HA 19DEC23 For Direction -->\n<div *ngFor=\"let qb of booklet\" [ngClass]=\"langDirection\">\n <!-- MR Commented below code to ensure single JSON for UNCONDITIONAL Booklets -->\n <!-- RS 09DEC24 Changed keys-->\n <!-- <lib-questionnaire [serv]=\"serv\" [qbId]=\"qb.id\" [tkn]=\"tkn\"></lib-questionnaire> -->\n <!-- HA 28DEC23 Below If logic is to load from booklet -->\n <div *ngIf=\"qb.subQuestions; else elseBlock\">\n <div *ngFor=\"let ques of qb.subQuestions\" class=\"questiondiv1\">\n <div>\n <!-- HA 17JAN24 - Is title is enabled so that based on the boolean div will be visible -->\n <div *ngIf=\"ques.isTitle\" [class]=\"qb.isShengel ? 'header-style' : 'question-f-size additional'\">\n <!-- VD 08NOV23 - showing label when its available-->\n <div [innerHTML]=\"getText(ques?.questionText)\" *ngIf=\"ques?.questionText && ques?.style?.showLabel !== false\" >\n {{ ques?.questionText }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!--VD 11Jun24 - translation changes-->\n <!--VD 06Sep24 calendar changes-->\n <!-- AP-14MAY25 - Added [dataBind] input binding -->\n <!-- AP-19MAY25 - Added [isEdit] binding --> \n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\"\n [labelValue]=\"labelValue\"\n [questionItem]=\"ques\"\n [translatedQuestions]=\"readTransQuestions(qb.id)\"\n [questions]=\"readQuestions(qb.id)\"\n (handleDropDown)=\"getDropDown($event)\"\n (handleCalendarDate)=\"getCalendarDate($event)\"\n (handleCalendarEvent)=\"getCalendarEvent($event)\"\n (singleFieldChangeEmit) ='singleFieldChange($event)'\n [dataBind]=\"dataBind\"\n [isEdit]=\"isEdit\" \n ></lib-questionbook>\n </div>\n </div>\n </div>\n <!-- HA 28DEC23 Below else logic is to load from books or questions -->\n <ng-template #elseBlock>\n <div class=\"questiondiv1\">\n <div>\n <div *ngIf=\"!qb.isTitle\" [class]=\"qb.isShengel ? 'header-style' : 'question-f-size additional'\">\n <!-- VD 08NOV23 - showing label when its available-->\n <div [innerHTML]=\"getText(qb?.questionText)\" *ngIf=\"qb?.questionText && qb?.style?.showLabel !== false\" >\n {{ qb?.questionText }}\n {{ qb?.title }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!-- // VD 11Jun24 - translation changes-->\n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\" [labelValue]=\"labelValue\" [questionItem]=\"qb\" [translatedQuestions]=\"readTransQuestions(qb.id)\" [questions]=\"readQuestions(qb.id)\" (handleDropDown)=\"getDropDown($event)\"></lib-questionbook>\n </div>\n </div>\n </ng-template>\n\n <!-- RS 09DEC24 Changed keys-->\n <!-- Group Actions -->\n <!-- HA 19DEC23 For Direction -->\n <!-- AP 23MAY25 - Action Buttons: Dynamically positioned buttons with JSON-configured styles -->\n <div class=\"align-submit-row\" *ngIf=\"abItem?.status != 'Completed'\" [ngClass]=\"langDirection\"> <!-- position-relative removed in this tag-->\n <ng-container *ngFor=\"let action of actions; let i = index\">\n <div class=\"action-wrapper\"\n [style.width.px]=\"action.width || 100\"\n style=\"margin-right: 10px;\"> <!-- style=\"position: absolute; [style.left.%]=\"action.positionPercent || 0\" removed in this tag -->\n @if(!isEdit && action.eventtoemit === 'submit'){\n <button \n (click)=\"editChangeClick(action)\" \n class=\"btn btn-primary fc-button nxtButton action-btn\"\n [style.--btn-bg]=\"action.bgColor\"\n [style.background-color]=\"action.bgColor || ''\"\n [style.color]=\"action.textColor || ''\"\n [style.border-radius.px]=\"action.borderRadius || 4\"\n style=\"width: 100%;\">\n Edit All\n </button>\n }\n @else {\n <button \n (click)=\"handleBookletActionClick(action)\" \n class=\"btn btn-primary fc-button nxtButton action-btn\"\n [style.--btn-bg]=\"action.bgColor\"\n [style.background-color]=\"action.bgColor || ''\"\n [style.color]=\"action.textColor || ''\"\n [style.border-radius.px]=\"action.borderRadius || 4\"\n style=\"width: 100%;\">\n {{ action.name }}\n </button>\n }\n </div>\n </ng-container>\n </div>\n</div>", styles: [".align-submit-row{display:flex}.header-style{padding:15px;background:#f8f8f8;color:#898989;border:1px solid #e8e8e8;border-top-left-radius:5px;border-top-right-radius:5px;margin-left:0;justify-content:left;font-size:15px}.rtl{flex-direction:row-reverse}.action-btn{width:100%;height:40px;transition:all .3s ease}\n"] }]
}], ctorParameters: () => [{ type: i1.SalesforceService }, { type: i2.DataService }, { type: i3.StorageService }, { type: i4.ActivatedRoute }, { type: i5.DomSanitizer }, { type: i6.ChangeService }, { type: i0.ElementRef }, { type: i7.I18nService }, { type: i8.HttpClient }], propDecorators: { bookletId: [{
type: Input
}], serv: [{
type: Input
}], tkn: [{
type: Input
}], bookletJSON: [{
type: Input
}], dropdownDependentData: [{
type: Input
}], labelValue: [{
type: Input
}], token: [{
type: Input
}], languageCode: [{
type: Input
}], fieldRestrictions: [{
type: Input
}], from: [{
type: Input
}], apiUrl: [{
type: Input
}], isEdit: [{
type: Input
}], handleBookletActionEvent: [{
type: Output
}], handlePage: [{
type: Output
}], hadleDropDownDependent: [{
type: Output
}], handleCalendarDate: [{
type: Output
}], handleCalendarEvent: [{
type: Output
}], dataBind: [{
type: Input
}], questionbookComponent: [{
type: ViewChild,
args: ['questionbook']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9va2xldC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvcGFnZXMvYm9va2xldC9ib29rbGV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL254dC1hcHAvc3JjL2xpYi9wYWdlcy9ib29rbGV0L2Jvb2tsZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFJVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFJWixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFjdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7QUFhN0MsTUFBTSxPQUFPLGdCQUFnQjtJQXlDakI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBRUQ7SUFDQztJQWhERCxTQUFTLENBQVM7SUFDbEIsSUFBSSxDQUFTO0lBQ2IsR0FBRyxDQUFTO0lBQ1osV0FBVyxDQUFNO0lBQ2pCLHFCQUFxQixDQUFNO0lBQzNCLFVBQVUsQ0FBUztJQUNuQixLQUFLLENBQVM7SUFDZCxZQUFZLENBQVMsQ0FBRSxtQ0FBbUM7SUFDMUQsaUJBQWlCLENBQU0sQ0FBQyx1Q0FBdUM7SUFDL0QsSUFBSSxDQUFNLENBQUMsZ0NBQWdDO0lBQzNDLE1BQU0sQ0FBTSxDQUFDLDZFQUE2RTtJQUMxRixNQUFNLENBQVcsQ0FBQyxrQ0FBa0M7SUFFbkQsd0JBQXdCLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7SUFDakUsVUFBVSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ25ELHNCQUFzQixHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ3pFLDhCQUE4QjtJQUNwQixrQkFBa0IsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUMzRCxtQkFBbUIsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUUvRCxVQUFVLENBQWlCO0lBRTNCLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFDcEIsTUFBTSxHQUFRLEVBQUUsQ0FBQztJQUNqQixPQUFPLEdBQWlCLEVBQUUsQ0FBQztJQUMzQixnQkFBZ0IsR0FBUSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2xDLFlBQVksR0FBUSxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUUsbUNBQW1DO0lBQ2xFLFNBQVMsR0FBUSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQzVCLFlBQVksR0FBWSxLQUFLLENBQUM7SUFDOUIsV0FBVyxDQUFTO0lBQ3BCLFdBQVcsQ0FBUztJQUMzQixnRkFBZ0Y7SUFDaEYsYUFBYSxHQUFHLEtBQUssQ0FBQyxDQUFDLDZDQUE2QztJQUNwRSxVQUFVLEdBQUcsRUFBRSxDQUFDLENBQUMscURBQXFEO0lBQzdELFFBQVEsQ0FBTSxDQUFBLDREQUE0RDtJQUNuRixTQUFTLEdBQVUsRUFBRSxDQUFDLENBQUUsOEJBQThCO0lBQ3RELHFGQUFxRjtJQUMxRCxxQkFBcUIsQ0FBeUI7SUFFekUsWUFDVSxTQUE0QixFQUM1QixXQUF3QixFQUN4QixjQUE4QixFQUM5QixLQUFxQixFQUNyQixTQUF1QixFQUN2QixhQUE0QixFQUNwQyxFQUFjLEVBQ1AsV0FBd0IsRUFDdkIsSUFBZ0I7UUFSaEIsY0FBUyxHQUFULFNBQVMsQ0FBbUI7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLGNBQVMsR0FBVCxTQUFTLENBQWM7UUFDdkIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFFN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDdkIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUV4QixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLHFCQUFxQixDQUFDO0lBQzNDLENBQUM7SUFFRCxRQUFRO1FBQ04seUNBQXlDO1FBQ3pDLE1BQU07UUFDTixtQkFBbUI7UUFDbkIscUNBQXFDO1FBQ3JDLDZCQUE2QjtRQUM3QixzQ0FBc0M7UUFDdEMsNEJBQTRCO1FBQzVCLFFBQVE7UUFDUixLQUFLO1FBRUwsNkNBQTZDO1FBQzdDLG9CQUFvQjtRQUNwQix1Q0FBdUM7UUFDdkMsdUNBQXVDO1FBQ3ZDLDBCQUEwQjtRQUMxQixxQkFBcUI7UUFDckIsNkJBQTZCO1FBQzdCLDZDQUE2QztRQUM3Qyw2Q0FBNkM7UUFDN0MsY0FBYztRQUNkLHNCQUFzQjtRQUN0Qix5QkFBeUI7UUFDekIsd0NBQXdDO1FBQ3hDLHdDQUF3QztRQUN4QyxxQkFBcUI7UUFDckIsa0JBQWtCO1FBQ2xCLHVCQUF1QjtRQUN2QiwrQkFBK0I7UUFDL0Isa0dBQWtHO1FBQ2xHLDBCQUEwQjtRQUMxQiw0Qk