UNPKG

@rangertechnologies/ngnxt

Version:

This library was used for creating dymanic UI based on the input JSON/data

698 lines 126 kB
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