@rangertechnologies/ngnxt 2.1.324 → 2.1.325
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/rangertechnologies-ngnxt.mjs +10 -50
- package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
- package/lib/pages/booklet/booklet.component.d.ts +1 -3
- package/lib/pages/questionbook/questionbook.component.d.ts +1 -3
- package/lib/services/storage/storage.service.d.ts +0 -6
- package/package.json +1 -1
- package/rangertechnologies-ngnxt-2.1.325.tgz +0 -0
- package/rangertechnologies-ngnxt-2.1.324.tgz +0 -0
|
@@ -44537,39 +44537,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
44537
44537
|
}], ctorParameters: () => [] });
|
|
44538
44538
|
|
|
44539
44539
|
class StorageService {
|
|
44540
|
-
nxtBookletAnswer;
|
|
44541
|
-
selectedData;
|
|
44542
44540
|
queryValueMap = new Map();
|
|
44543
44541
|
apiResponseData = {};
|
|
44544
44542
|
conditionQuestionValue = {};
|
|
44545
44543
|
constructor() { }
|
|
44546
|
-
save(qbJson) {
|
|
44547
|
-
this.nxtBookletAnswer = qbJson;
|
|
44548
|
-
}
|
|
44549
|
-
update(questionWithInput) {
|
|
44550
|
-
// Store the Updated Questions (with Answer/Error) in a Map
|
|
44551
|
-
// for (var eQuestion in this.nxtBookletAnswer.bookQuestionsMap) {
|
|
44552
|
-
// if(eQuestion == questionWithInput.Id) {
|
|
44553
|
-
// this.nxtBookletAnswer.bookQuestionsMap[eQuestion] = questionWithInput;
|
|
44554
|
-
// }
|
|
44555
|
-
// }
|
|
44556
|
-
// RS 09DEC24 Changed keys
|
|
44557
|
-
for (var eQuestion in this.nxtBookletAnswer.bookQuestionsMap) {
|
|
44558
|
-
if (this.nxtBookletAnswer.bookQuestionsMap.hasOwnProperty(eQuestion)) {
|
|
44559
|
-
const questionsR = this.nxtBookletAnswer.bookQuestionsMap[eQuestion].subQuestions;
|
|
44560
|
-
// VD 31NOV24 wrapper changes
|
|
44561
|
-
for (let i = 0; i < questionsR.length; i++) {
|
|
44562
|
-
if (questionsR[i].id == questionWithInput.id) {
|
|
44563
|
-
questionsR[i] = questionWithInput;
|
|
44564
|
-
}
|
|
44565
|
-
}
|
|
44566
|
-
}
|
|
44567
|
-
}
|
|
44568
|
-
}
|
|
44569
|
-
get() {
|
|
44570
|
-
// return the stored questions
|
|
44571
|
-
return this.nxtBookletAnswer;
|
|
44572
|
-
}
|
|
44573
44544
|
queryValueStore(questionId, key, value) {
|
|
44574
44545
|
const existing = this.queryValueMap.get(questionId) || {};
|
|
44575
44546
|
existing[key] = value;
|
|
@@ -57280,7 +57251,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
57280
57251
|
class QuestionbookComponent {
|
|
57281
57252
|
dataService;
|
|
57282
57253
|
changeService;
|
|
57283
|
-
storageService;
|
|
57284
57254
|
qbItem;
|
|
57285
57255
|
questionItem;
|
|
57286
57256
|
questions;
|
|
@@ -57345,10 +57315,9 @@ class QuestionbookComponent {
|
|
|
57345
57315
|
handleCalendarDate = new EventEmitter();
|
|
57346
57316
|
handleCalendarEvent = new EventEmitter();
|
|
57347
57317
|
bookQuestionsMap = new Map();
|
|
57348
|
-
constructor(dataService, changeService
|
|
57318
|
+
constructor(dataService, changeService) {
|
|
57349
57319
|
this.dataService = dataService;
|
|
57350
57320
|
this.changeService = changeService;
|
|
57351
|
-
this.storageService = storageService;
|
|
57352
57321
|
}
|
|
57353
57322
|
ngOnInit() {
|
|
57354
57323
|
// VD 13Sep24 changes
|
|
@@ -57636,7 +57605,6 @@ class QuestionbookComponent {
|
|
|
57636
57605
|
}
|
|
57637
57606
|
}
|
|
57638
57607
|
});
|
|
57639
|
-
this.storageService.update(element);
|
|
57640
57608
|
}
|
|
57641
57609
|
// sunday comment
|
|
57642
57610
|
// if (element.type === 'Calendar') {
|
|
@@ -57661,7 +57629,6 @@ class QuestionbookComponent {
|
|
|
57661
57629
|
el.isHidden = true;
|
|
57662
57630
|
el.input = '';
|
|
57663
57631
|
el.selectedValue = undefined;
|
|
57664
|
-
this.storageService.update(el);
|
|
57665
57632
|
// Recursively hide elements dependent on this one
|
|
57666
57633
|
this.hideDependentElements(el.id);
|
|
57667
57634
|
});
|
|
@@ -57743,8 +57710,6 @@ class QuestionbookComponent {
|
|
|
57743
57710
|
else {
|
|
57744
57711
|
ques.input = event?.valueObj;
|
|
57745
57712
|
}
|
|
57746
|
-
// Once the right value is stored in ques.input store the ques (with input) in storageService
|
|
57747
|
-
this.storageService.update(ques);
|
|
57748
57713
|
// VD 19Jul01 - get updated question
|
|
57749
57714
|
this.handleQuestion.emit(ques);
|
|
57750
57715
|
}
|
|
@@ -57968,7 +57933,7 @@ class QuestionbookComponent {
|
|
|
57968
57933
|
this.destroy$.complete();
|
|
57969
57934
|
this.loadComponent$.complete();
|
|
57970
57935
|
}
|
|
57971
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: QuestionbookComponent, deps: [{ token: DataService }, { token: ChangeService }
|
|
57936
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: QuestionbookComponent, deps: [{ token: DataService }, { token: ChangeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
57972
57937
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: QuestionbookComponent, isStandalone: true, selector: "lib-questionbook", inputs: { qbItem: "qbItem", questionItem: "questionItem", questions: "questions", errorFieldId: "errorFieldId", labelValue: "labelValue", token: "token", isEdit: "isEdit", dropDownData: "dropDownData", dataBind: "dataBind", allIcons: "allIcons", themeColor: "themeColor", cdnIconURL: "cdnIconURL", direction: "direction", languageCode: "languageCode", from: "from", bgColor: "bgColor", margin: "margin", onlyView: "onlyView" }, outputs: { handleDropDown: "handleDropDown", handleQuestion: "handleQuestion", singleFieldChangeEmit: "singleFieldChangeEmit", hadleDropDownDependent: "hadleDropDownDependent", handleCalendarDate: "handleCalendarDate", handleCalendarEvent: "handleCalendarEvent" }, ngImport: i0, template: "<!-- HA 18JAN24 Added class for styling -->\n<div [style]=\"bookStyle\" class=\"content-box form-group\" [ngClass]=\"{ 'form-group': from !== 'questionbook' }\" [style.background-color]=\"from === 'questionbook' ? bgColor || '' : ''\" [style.margin]=\"from === 'questionbook' ? (margin || '0px') : '0px'\" >\n <div class=\"form-row\">\n <!-- HA 20DEC23 Directive and Question Style from salesforce -->\n <!-- RA09DEC24 Changed keys-->\n <ng-container *ngFor=\"let ques of questions;let i = index\">\n <div [style.display]=\"ques.isHidden ? 'none' : 'block'\" [class]=\"'col-lg-' + ques.size + ' paddingnone'\" \n [id]=\"ques.id\" [style]=\"ques?.style?.questionStyle\" [ngStyle]=\"ques?.style?.parrentMargin ? {'margin': ques?.style?.parrentMargin } : {'margin-top': '5px', 'margin-bottom': '5px'}\" >\n <!-- VD 09May24 is hide field change-->\n <div class=\"nxtInputContainer\">\n <!-- AP-28MAR25 Show label if enabled and not a Boolean type -->\n <div [ngClass]=\"{ down2: qbItem?.progressBar }\"\n *ngIf=\"(ques.style?.showLabel ?? true) && ![ 'Radio','Boolean','Text','List','Dropdown','RichTextArea','DateTime','month','Location','Number','Email','Date','Time','TextArea','Label','currency','File' ].includes(ques.type)\" \n [style]=\"ques.style?.labelStyle\">\n <div style=\"gap: 5px; display: flex; align-items: center;\" [style]=\"ques.style?.labelValueStyle\"\n [ngStyle]=\"{\n 'font-family': ques.font,\n 'color': ques.color || '#212529',\n 'font-size': ques.fontSize || '14px',\n 'font-weight': ques.fontWeight || 'normal'\n }\">{{ ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText):''}}\n <div *ngIf=\"ques.isOptional && !ques.isReadOnly \" style=\"color: red;\">*</div>\n </div>\n </div>\n <!-- calendar -->\n <div *ngIf=\"ques.type === 'Calendar'\" [class]=\"ques?.style?.inputClass\">\n <app-custom-calendar [question]=\"ques\" (eventSelected)=\"getCalendarEvent($event)\"\n (dateSelected)=\"getCurrentCalendar($event)\" (openModal)=\"openCalendarModal($event)\"\n (closeModal)=\"closeCalendarModal($event)\"></app-custom-calendar>\n <!-- model used in calendar component -->\n <app-custom-model *ngIf=\"isCalendarModalOpen\" [modalTitle]=\"calendarModalTitle\"\n [isModalOpen]=\"isCalendarModalOpen\" [modalSize]=\"calendarModalSize\"\n [saveButtonValue]=\"calendarSaveButtonValue\" [modalFooter]=\"modalCalendarModalFooter\"\n (saveButtonEmit)=\"onCalendarModalSave()\" (cancelButtonEmit)=\"closeCalendarModal($event)\">\n <lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\"\n [isEdit]=\"isEdit\" \n (handleQuestion)=\"handleQuestionEvent($event)\">\n </lib-questionbook>\n </app-custom-model>\n </div>\n <!-- SKS25MAR25 Image -->\n <div *ngIf=\"ques.type === 'Image'\" (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\" [class]=\"ques?.style?.inputClass\">\n <div *ngIf=\"isImageHover\" style=\"display: flex; justify-content: end;\">\n <i *ngIf=\"!ques.isReadOnly\" (click)=\"onImageEdit(ques)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg *ngIf=\"!ques.isReadOnly\" (click)=\"onImageDelete(ques)\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <img *ngIf=\"ques.isReadOnly\" [style.width.px]=\"ques.imageSize.width\"\n [style.height.px]=\"ques.imageSize.height\" [src]=\"ques.imageData\" />\n <div *ngIf=\"!ques.isReadOnly\" class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"ques.input\">\n <img [src]=\"ques.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!ques.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{i}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>Upload Image</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\"\n (change)=\"fileChangeEvent(ques, $event)\" style=\"display: none;\" />\n </div>\n </div>\n </div>\n <!-- MSM10JUL25 icon-selector -->\n <nxt-icon-selector [class]=\"ques?.style?.inputClass\" [allIcons]=\"allIcons\" *ngIf=\"ques.type === 'Icon'\" [required]=\"ques.isOptional\" [mode]=\"isEdit !== true ? 'view' : 'edit'\" [question]=\"ques\" [labelFont]=\"ques.font\"\n [label]=\" ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [labelColor]=\"ques.color\"\n [labelSize]=\"ques.fontSize\" [labelWeight]=\"ques.fontWeight\" [showLabel]=\"ques.style?.showLabel\" (iconSelected)=\"childEventCapture($event, ques);\"></nxt-icon-selector>\n\n <!-- SKS21MAR25 line -->\n <hr [class]=\"ques?.style?.inputClass\" *ngIf=\"ques.type === 'Line'\" class=\"custom-line\" style=\"display: inline-flex\" />\n <!-- SKS13MAR25 data table -->\n <nxt-datatable *ngIf=\"ques.type === 'Table'\" [onlyView]=\"onlyView\" [class]=\"ques?.style?.inputClass\" isEditRow isDeleteRow actionButton isButtons [question]=\"ques\" from=\"questionBook\"\n (valueChange)=\"childEventCapture($event, ques)\" [apiMeta]=\"ques.subText\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" [languageCode]=\"languageCode\"\n [tableConfig]=\"ques.tableConfig\" tableId=\"\" [direction]=\"direction\" tableWidth=\"auto\">\n </nxt-datatable>\n <!-- list -->\n <nxt-search-box *ngIf=\"ques.type === 'List'\" [onlyView]=\"onlyView\" [class]=\"ques?.style?.inputClass\" [question]=\"ques\" [readOnly]=\"ques.isReadOnly\" [apiMeta]=\"ques.subText\"\n [id]=\"ques.id\" [placeHolderText]=\"ques.question || ''\" [value]=\"ques.input\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n (searchValueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-search-box>\n\n <!-- Dropdown -->\n <!-- HA 09FEB24 Added condition of sqOption to the dropdown -->\n <nxt-dropdown *ngIf=\"ques?.type === 'Dropdown' && ques?.options\" \n [onlyView]=\"onlyView\" \n [class]=\"ques?.style?.inputClass\" \n [options]=\"ques.options\" \n [apiMeta]=\"ques.subText\"\n [id]=\"ques.id\" \n [from]=\"'nxtForm'\"\n [selectedValue]=\"qbItem.isShengel ? ques.input : ques.selectedValue\"\n [placeholder]=\"ques?.question ? ((ques.id+'.question') | nxtCustomTranslate : ques?.question ): ''\"\n [readOnly]=\"ques.isReadOnly\" \n [question]=\"ques\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" \n [padding]=\"ques?.padding\"\n [labelFont]=\"ques?.font\"\n [label]=\"ques?.questionText\"\n [labelColor]=\"ques?.color\"\n [inputTextColor]=\"ques?.color\"\n [labelSize]=\"ques?.fontSize\"\n [inputValueSize]=\"ques?.fontSize\"\n [labelWeight]=\"ques?.fontWeight\"\n [inputWeight]=\"ques?.fontWeight\"\n [showLabel]=\"ques?.style?.showLabel ?? true\"\n [inputBgColor]=\"ques?.inputBgColor\"\n [inputIconLeftSrc]=\"ques?.iconLeftSrc\"\n (valueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-dropdown>\n <!-- // VD 02Aug24 custom-radio component -->\n <div *ngIf=\"ques.type === 'Radio' && ques?.options\" [class]=\"ques?.style?.inputClass\" class=\"\">\n <nxt-radio [options]=\"ques.options\" [question]=\"ques\" [apiMeta]=\"ques.subText\" [id]=\"ques.id\"\n [selectedValue]=\"ques.selectedValue\" [errorMessage]=\"ques.errorMessage\"\n [referenceField]=\"ques.referenceField\" [readOnly]=\"ques.isReadOnly\"\n [label]=\"ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" [onlyView]=\"onlyView\"\n (valueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-radio>\n </div>\n <!-- Attachment / Files -->\n <nxt-file-upload *ngIf=\"ques.type === 'File'\" \n [class]=\"ques?.style?.inputClass\" \n [config]=\"ques\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" \n [readOnly]=\"ques.isReadOnly\"\n [allFiles]=\"ques.input\" \n [onlyView]=\"onlyView\"\n [label]=\"ques.questionText\"\n [required]=\"ques.isOptional\"\n [fileConfig]=\"ques.subText\"\n (selectedFileData)=\"childEventCapture($event.value,$event.config)\"\n (deletedFileData)=\"deleteFile($event)\">\n </nxt-file-upload>\n <!-- SKS11JUN25 Button -->\n <nxt-button\n *ngIf=\"ques.type === 'Button'\" [class]=\"ques?.style?.inputClass\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n [btnHeight]=\"'50px'\" [btnWidth]=\"'150px'\" [buttonValue]=\"ques?.question\"\n (buttonClickEmit)=\"childEventCapture($event, ques)\"\n >\n </nxt-button>\n <!-- SKS11JUN25 book type -->\n <lib-questionbook *ngIf=\"ques.type === 'Book'\" [class]=\"ques?.style?.inputClass\"\n [bgColor]=\"ques?.style?.bgColor\" [margin]=\"ques?.style?.margin || '0px'\"\n [qbItem]=\"ques.qbItem\" [labelValue]=\"labelValue\" [onlyView]=\"onlyView\"\n [questions]=\"ques?.qbReferenceQuestions?.bookQuestionsMap?.[ques?.qbReference]?.subQuestions\"\n [isEdit]=\"isEdit\" [from]=\"'questionbook'\"\n (handleDropDown)=\"getDropDown($event)\">\n </lib-questionbook>\n <!-- SKS11JUN25 Text, Email, label, number, Boolean, rich text editor, DateTime, Date, Time-->\n <!-- SKS16OCT25 added custom style fields for input -->\n <nxt-input *ngIf=\"['Space','Text','Email','Number','Label','Boolean','RichTextArea','DateTime','month','Date','Time','TextArea','Location','currency'].includes(ques.type)\"\n [type]=\"ques.type === 'Text' ? 'text' : ques.type === 'Email' ? 'email' : ques.type === 'Number' ? 'number' : ques.type === 'Label' ? 'label' : ques.type === 'Boolean' ? 'checkbox' : ques.type === 'RichTextArea' ? 'richtext' : ques.type === 'DateTime' ? 'datetime' : ques.type === 'Date' ? 'date' : ques.type === 'Time' ? 'time' : ques.type === 'TextArea' ? 'textarea' : ques.type === 'month' ? 'month' : ques.type === 'Location' ? 'location' : ques.type === 'Space' ? 'space' : ques.type === 'currency' ? 'currency': 'text'\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n [value]=\"ques.input\" [class]=\"ques?.style?.inputClass\"\n [question]=\"ques\" [readOnly]=\"ques.isReadOnly\"\n [apiKey]=\"qbItem['apiKey']\"\n [labelFont]=\"ques.font\"\n [label]=\"ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [showLabel]=\"ques.style?.showLabel\"\n svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"ques?.question ? ((ques.id+'.question') | nxtCustomTranslate : ques?.question ): ''\"\n [required]=\"ques.isOptional\"\n [inputId]=\"ques.trackingId\"\n [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"ques.iconLeftSrc\" \n [minDate]=\"ques.minDate\"\n [rows]=\"2\"\n [apiMeta]=\"ques.subText\"\n [direction]=\"direction\"\n [onlyView]=\"onlyView\"\n [from]=\"'nxtForm'\"\n\n [padding]=\"ques?.style?.padding\" [margin]=\"ques?.style?.margin\" [inputValueSize]=\"ques?.style?.inputFontSize\"\n [inputBorder]=\"ques?.style?.border || '#ccc'\" [inputBgColor]=\"ques?.style?.bgColor || '#ffffff'\"\n [labelSize]=\"ques?.style?.labelFontSize\" [labelWeight]=\"ques?.style?.labelFontWeight\"\n [inputWeight]=\"ques?.style?.inputFontWeight\" [labelColor]=\"ques?.style?.labelColor\"\n [textAlign]=\"ques?.style?.textAlign\" [rows]=\"ques?.style?.rows\"\n\n [style.padding]=\"ques.type === 'Space' ? ques?.style?.padding : null\"\n [style.margin]=\"ques.type === 'Space' ? ques?.style?.margin : null\"\n\n (inputValue)=\"childEventCapture($event.value,$event.question, 'nxt-input')\"\n >\n </nxt-input>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n\n<!--SKS25MAR25 Modal Overlay -->\n<div class=\"modal-overlay\" *ngIf=\"isImageEdit\">\n <div class=\"modal-content\">\n <span class=\"close-button\" (click)=\"closeModal()\">\u00D7</span>\n\n <!-- Image Editor -->\n <div *ngIf=\"selectedImageElement?.type === 'Image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedImageElement.imageData\" [imageBase64]=\"selectedImageElement.orgImageData\"\n [disabled]=\"false\" [alignImage]=\"alignImage\" [roundCropper]=\"roundCropper\" [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\" [allowMoveImage]=\"false\" [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation\" [aspectRatio]=\"aspectRatio\" [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\" [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\" [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\" [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\" [resetCropOnAspectRatioChange]='true' [(cropper)]=\"cropper\"\n [(transform)]=\"transform\" [onlyScaleDown]=\"true\" output=\"blob\" format=\"png\"\n (imageCropped)=\"imageCropped($event)\" (cropperReady)=\"cropperReady($event)\">\n </image-cropper>\n </div>\n\n <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"Rotate Left\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [class.enabled]=\"transform.flipH\"\n title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n </div>\n </div>\n</div>", styles: [".col-lg-6{width:100%}.myt-font7{display:flex;justify-content:flex-start;align-items:center}.icon{display:inline-block;width:15px;height:15px;border-radius:50%;background-color:#08010177;color:#fff;text-align:center;line-height:16px;font-size:11px;font-family:Arial,sans-serif;font-weight:700;margin-left:5px}@media (min-width: 1200px){.col-lg-6{width:50%!important}.col-lg-6,.col-lg-4{padding-left:5px!important;padding-right:5px!important}.form-row{display:-ms-flexbox!important;display:flex!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}}.icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background-color:#f5f5f5;border:1px solid #ddd;color:#666;margin-left:4px;font-size:12px;cursor:pointer!important}::ng-deep .mat-tooltip-panel{background:#fff!important}::ng-deep .mat-tooltip{background-color:#fff!important;color:#333!important;white-space:pre-line!important;line-height:1.5!important}.mat-tooltip{padding:8px 16px!important}::ng-deep .white-tooltip{white-space:pre-line!important;line-height:1.5!important}.custom-line{width:100%;border:1px solid #d9d9d9}.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:100}.modal-content{background:#fff;padding:20px;width:500px;max-width:90%;border-radius:8px;position:relative;text-align:center}.close-button{position:absolute;top:6px;right:6px;font-size:25px;cursor:pointer;z-index:10}.controls{display:flex;gap:5px;justify-content:center;margin-top:10px}.logo-icon{cursor:pointer;padding:5px;width:35px;border-radius:5px;background:#d3d3d3}.logo-icon:hover{background:#a9a9a9}.enabled{background:#007bff;color:#fff}input[type=checkbox]{width:21px}.boolean-question{display:flex;align-items:center;gap:10px;padding-top:14px;padding-bottom:12px}.form-control[disabled]{border-radius:5px;background-color:#e9ecef!important}\n"], dependencies: [{ kind: "component", type: QuestionbookComponent, selector: "lib-questionbook", inputs: ["qbItem", "questionItem", "questions", "errorFieldId", "labelValue", "token", "isEdit", "dropDownData", "dataBind", "allIcons", "themeColor", "cdnIconURL", "direction", "languageCode", "from", "bgColor", "margin", "onlyView"], outputs: ["handleDropDown", "handleQuestion", "singleFieldChangeEmit", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }, { kind: "component", type: NxtFileUpload, selector: "nxt-file-upload", inputs: ["allFiles", "mode", "config", "from", "dragAndDrop", "readOnly", "onlyView", "required", "label", "fileConfig"], outputs: ["selectedFileData", "deletedFileData"] }, { kind: "component", type: NxtRadio, selector: "nxt-radio", inputs: ["options", "question", "apiMeta", "selectedValue", "progressBar", "id", "readOnly", "errorMessage", "fromShengel", "referenceField", "token", "label", "mode", "onlyView"], outputs: ["valueChange"] }, { kind: "component", type: nxtDropdown, selector: "nxt-dropdown", inputs: ["options", "placeholder", "apiMeta", "selectedValue", "progressBar", "readOnly", "error", "fromShengel", "question", "mode", "from", "padding", "onlyView", "labelFont", "label", "labelColor", "inputTextColor", "labelSize", "inputValueSize", "labelWeight", "inputWeight", "showLabel", "inputBorder", "inputBgColor", "inputIconLeftSrc"], outputs: ["valueChange"] }, { kind: "component", type: NxtButtonComponent, selector: "nxt-button", inputs: ["buttonValue", "buttonType", "type", "buttonDisable", "btnBgColor", "btnBorder", "btnBorderRadius", "btnBorderColor", "btnTextColor", "btnHeight", "btnWidth", "btnIconLeftSrc", "btnIconRightSrc", "btnHoverBgColor", "btnHoverTextColor", "btnId", "dataDismiss", "modalToTrigger", "isImageSvg", "tabIndex", "buttonConfig", "mode", "languageCode", "padding", "isLoading", "selector", "dropdownLoadingButton"], outputs: ["buttonClickEmit"] }, { kind: "component", type: NxtSearchBox, selector: "nxt-search-box", inputs: ["placeHolderText", "question", "apiMeta", "id", "readOnly", "mode", "from", "value", "onlyView"], outputs: ["searchValueChange"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "summaryValues", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "stickyColumn", "tableWidth", "actionColumHeader", "actionButton", "title", "isButtons", "buttonArray", "tableId", "isEditRow", "isDeleteRow", "addInlineRecord", "searchConfigs", "direction", "pagination", "actionButtonArray", "multipleFilter", "isPagination", "isListViews", "id", "isNosIndicator", "isEditable", "from", "question", "rowTextSize", "rowTextColor", "apiMeta", "summaryRows", "summaryColumns", "isLoading", "tableConfig", "tableParams", "listViews", "mode", "languageCode", "selectedColumn", "allIcons", "isButtonLoading", "isPreview", "groupFilter", "groupFilterConfig", "groupFilterColumn", "onlyView", "tableHeight", "serialNumberColumn"], outputs: ["tableRowClick", "onEditData", "onSaveData", "saveButtonData", "onDeleteData", "buttonEmit", "hyperLinkEmit", "sideNavEmit", "actionButtonEmit", "columnSelected", "removeColumn", "valueChange", "selectedValues", "fileEmit", "NxtTableFilterEmit", "hadleDropDownDependent", "NxtTableParamsEmit"] }, { kind: "component", type: CustomModelComponent, selector: "app-custom-model", inputs: ["modalTitle", "isModalOpen", "modalSize", "saveButtonValue", "modalFooter"], outputs: ["saveButtonEmit", "cancelButtonEmit"] }, { kind: "component", type: CustomCalendarComponent, selector: "app-custom-calendar", inputs: ["allEvents", "question", "nxtId"], outputs: ["eventSelected", "dateSelected", "openModal", "closeModal"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: NxtInput, selector: "nxt-input", inputs: ["label", "labelFont", "labelWeight", "inputWeight", "labelSize", "inputValueSize", "textAlign", "labelColor", "showLabel", "svgHeight", "svgWidth", "type", "inputIconRightSrc", "inputIconLeftSrc", "required", "minLength", "pattern", "errorMessages", "maxLength", "placeholder", "inputBgColor", "inputBorder", "placeholderColor", "placeholderFont", "placeholderWeight", "placeholderSize", "inputTextColor", "inputHeight", "inputWidth", "inputId", "inputBorderSize", "inputConfig", "confPassVal", "confPass", "mode", "value", "question", "showSuggestion", "ariaOwns", "ariaHasPopup", "isLoading", "options", "minDate", "maxDate", "rows", "from", "selectedOption", "apiMeta", "direction", "currency", "helpText", "apiKey", "readOnly", "padding", "margin", "onlyView", "size"], outputs: ["valueChange", "inputValue", "selectEmit", "onBlur", "onFocus", "toggleEmit", "removeValueEmit"] }, { kind: "component", type: IconSelectorComponent, selector: "nxt-icon-selector", inputs: ["allIcons", "themeColor", "height", "tooltipPosition", "selectedIcon", "cdnIconURL", "label", "labelFont", "labelWeight", "inputWeight", "labelSize", "labelColor", "showLabel", "required", "mode", "question", "options"], outputs: ["iconSelected"] }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
57973
57938
|
}
|
|
57974
57939
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: QuestionbookComponent, decorators: [{
|
|
@@ -57977,7 +57942,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
57977
57942
|
CommonModule,
|
|
57978
57943
|
FormsModule, ImageCropperComponent, NxtFileUpload, NxtRadio, nxtDropdown, NxtButtonComponent, NxtSearchBox, NxtDatatable, CustomModelComponent, CustomCalendarComponent, MatTooltipModule, NxtInput, IconSelectorComponent, NxtCustomTranslatePipe
|
|
57979
57944
|
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- HA 18JAN24 Added class for styling -->\n<div [style]=\"bookStyle\" class=\"content-box form-group\" [ngClass]=\"{ 'form-group': from !== 'questionbook' }\" [style.background-color]=\"from === 'questionbook' ? bgColor || '' : ''\" [style.margin]=\"from === 'questionbook' ? (margin || '0px') : '0px'\" >\n <div class=\"form-row\">\n <!-- HA 20DEC23 Directive and Question Style from salesforce -->\n <!-- RA09DEC24 Changed keys-->\n <ng-container *ngFor=\"let ques of questions;let i = index\">\n <div [style.display]=\"ques.isHidden ? 'none' : 'block'\" [class]=\"'col-lg-' + ques.size + ' paddingnone'\" \n [id]=\"ques.id\" [style]=\"ques?.style?.questionStyle\" [ngStyle]=\"ques?.style?.parrentMargin ? {'margin': ques?.style?.parrentMargin } : {'margin-top': '5px', 'margin-bottom': '5px'}\" >\n <!-- VD 09May24 is hide field change-->\n <div class=\"nxtInputContainer\">\n <!-- AP-28MAR25 Show label if enabled and not a Boolean type -->\n <div [ngClass]=\"{ down2: qbItem?.progressBar }\"\n *ngIf=\"(ques.style?.showLabel ?? true) && ![ 'Radio','Boolean','Text','List','Dropdown','RichTextArea','DateTime','month','Location','Number','Email','Date','Time','TextArea','Label','currency','File' ].includes(ques.type)\" \n [style]=\"ques.style?.labelStyle\">\n <div style=\"gap: 5px; display: flex; align-items: center;\" [style]=\"ques.style?.labelValueStyle\"\n [ngStyle]=\"{\n 'font-family': ques.font,\n 'color': ques.color || '#212529',\n 'font-size': ques.fontSize || '14px',\n 'font-weight': ques.fontWeight || 'normal'\n }\">{{ ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText):''}}\n <div *ngIf=\"ques.isOptional && !ques.isReadOnly \" style=\"color: red;\">*</div>\n </div>\n </div>\n <!-- calendar -->\n <div *ngIf=\"ques.type === 'Calendar'\" [class]=\"ques?.style?.inputClass\">\n <app-custom-calendar [question]=\"ques\" (eventSelected)=\"getCalendarEvent($event)\"\n (dateSelected)=\"getCurrentCalendar($event)\" (openModal)=\"openCalendarModal($event)\"\n (closeModal)=\"closeCalendarModal($event)\"></app-custom-calendar>\n <!-- model used in calendar component -->\n <app-custom-model *ngIf=\"isCalendarModalOpen\" [modalTitle]=\"calendarModalTitle\"\n [isModalOpen]=\"isCalendarModalOpen\" [modalSize]=\"calendarModalSize\"\n [saveButtonValue]=\"calendarSaveButtonValue\" [modalFooter]=\"modalCalendarModalFooter\"\n (saveButtonEmit)=\"onCalendarModalSave()\" (cancelButtonEmit)=\"closeCalendarModal($event)\">\n <lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\"\n [isEdit]=\"isEdit\" \n (handleQuestion)=\"handleQuestionEvent($event)\">\n </lib-questionbook>\n </app-custom-model>\n </div>\n <!-- SKS25MAR25 Image -->\n <div *ngIf=\"ques.type === 'Image'\" (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\" [class]=\"ques?.style?.inputClass\">\n <div *ngIf=\"isImageHover\" style=\"display: flex; justify-content: end;\">\n <i *ngIf=\"!ques.isReadOnly\" (click)=\"onImageEdit(ques)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg *ngIf=\"!ques.isReadOnly\" (click)=\"onImageDelete(ques)\" width=\"16\" height=\"16\"\n viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\"\n stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <img *ngIf=\"ques.isReadOnly\" [style.width.px]=\"ques.imageSize.width\"\n [style.height.px]=\"ques.imageSize.height\" [src]=\"ques.imageData\" />\n <div *ngIf=\"!ques.isReadOnly\" class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"ques.input\">\n <img [src]=\"ques.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!ques.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{i}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>Upload Image</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\"\n (change)=\"fileChangeEvent(ques, $event)\" style=\"display: none;\" />\n </div>\n </div>\n </div>\n <!-- MSM10JUL25 icon-selector -->\n <nxt-icon-selector [class]=\"ques?.style?.inputClass\" [allIcons]=\"allIcons\" *ngIf=\"ques.type === 'Icon'\" [required]=\"ques.isOptional\" [mode]=\"isEdit !== true ? 'view' : 'edit'\" [question]=\"ques\" [labelFont]=\"ques.font\"\n [label]=\" ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [labelColor]=\"ques.color\"\n [labelSize]=\"ques.fontSize\" [labelWeight]=\"ques.fontWeight\" [showLabel]=\"ques.style?.showLabel\" (iconSelected)=\"childEventCapture($event, ques);\"></nxt-icon-selector>\n\n <!-- SKS21MAR25 line -->\n <hr [class]=\"ques?.style?.inputClass\" *ngIf=\"ques.type === 'Line'\" class=\"custom-line\" style=\"display: inline-flex\" />\n <!-- SKS13MAR25 data table -->\n <nxt-datatable *ngIf=\"ques.type === 'Table'\" [onlyView]=\"onlyView\" [class]=\"ques?.style?.inputClass\" isEditRow isDeleteRow actionButton isButtons [question]=\"ques\" from=\"questionBook\"\n (valueChange)=\"childEventCapture($event, ques)\" [apiMeta]=\"ques.subText\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" [languageCode]=\"languageCode\"\n [tableConfig]=\"ques.tableConfig\" tableId=\"\" [direction]=\"direction\" tableWidth=\"auto\">\n </nxt-datatable>\n <!-- list -->\n <nxt-search-box *ngIf=\"ques.type === 'List'\" [onlyView]=\"onlyView\" [class]=\"ques?.style?.inputClass\" [question]=\"ques\" [readOnly]=\"ques.isReadOnly\" [apiMeta]=\"ques.subText\"\n [id]=\"ques.id\" [placeHolderText]=\"ques.question || ''\" [value]=\"ques.input\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n (searchValueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-search-box>\n\n <!-- Dropdown -->\n <!-- HA 09FEB24 Added condition of sqOption to the dropdown -->\n <nxt-dropdown *ngIf=\"ques?.type === 'Dropdown' && ques?.options\" \n [onlyView]=\"onlyView\" \n [class]=\"ques?.style?.inputClass\" \n [options]=\"ques.options\" \n [apiMeta]=\"ques.subText\"\n [id]=\"ques.id\" \n [from]=\"'nxtForm'\"\n [selectedValue]=\"qbItem.isShengel ? ques.input : ques.selectedValue\"\n [placeholder]=\"ques?.question ? ((ques.id+'.question') | nxtCustomTranslate : ques?.question ): ''\"\n [readOnly]=\"ques.isReadOnly\" \n [question]=\"ques\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" \n [padding]=\"ques?.padding\"\n [labelFont]=\"ques?.font\"\n [label]=\"ques?.questionText\"\n [labelColor]=\"ques?.color\"\n [inputTextColor]=\"ques?.color\"\n [labelSize]=\"ques?.fontSize\"\n [inputValueSize]=\"ques?.fontSize\"\n [labelWeight]=\"ques?.fontWeight\"\n [inputWeight]=\"ques?.fontWeight\"\n [showLabel]=\"ques?.style?.showLabel ?? true\"\n [inputBgColor]=\"ques?.inputBgColor\"\n [inputIconLeftSrc]=\"ques?.iconLeftSrc\"\n (valueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-dropdown>\n <!-- // VD 02Aug24 custom-radio component -->\n <div *ngIf=\"ques.type === 'Radio' && ques?.options\" [class]=\"ques?.style?.inputClass\" class=\"\">\n <nxt-radio [options]=\"ques.options\" [question]=\"ques\" [apiMeta]=\"ques.subText\" [id]=\"ques.id\"\n [selectedValue]=\"ques.selectedValue\" [errorMessage]=\"ques.errorMessage\"\n [referenceField]=\"ques.referenceField\" [readOnly]=\"ques.isReadOnly\"\n [label]=\"ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" [onlyView]=\"onlyView\"\n (valueChange)=\"childEventCapture($event.value,$event.question)\">\n </nxt-radio>\n </div>\n <!-- Attachment / Files -->\n <nxt-file-upload *ngIf=\"ques.type === 'File'\" \n [class]=\"ques?.style?.inputClass\" \n [config]=\"ques\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\" \n [readOnly]=\"ques.isReadOnly\"\n [allFiles]=\"ques.input\" \n [onlyView]=\"onlyView\"\n [label]=\"ques.questionText\"\n [required]=\"ques.isOptional\"\n [fileConfig]=\"ques.subText\"\n (selectedFileData)=\"childEventCapture($event.value,$event.config)\"\n (deletedFileData)=\"deleteFile($event)\">\n </nxt-file-upload>\n <!-- SKS11JUN25 Button -->\n <nxt-button\n *ngIf=\"ques.type === 'Button'\" [class]=\"ques?.style?.inputClass\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n [btnHeight]=\"'50px'\" [btnWidth]=\"'150px'\" [buttonValue]=\"ques?.question\"\n (buttonClickEmit)=\"childEventCapture($event, ques)\"\n >\n </nxt-button>\n <!-- SKS11JUN25 book type -->\n <lib-questionbook *ngIf=\"ques.type === 'Book'\" [class]=\"ques?.style?.inputClass\"\n [bgColor]=\"ques?.style?.bgColor\" [margin]=\"ques?.style?.margin || '0px'\"\n [qbItem]=\"ques.qbItem\" [labelValue]=\"labelValue\" [onlyView]=\"onlyView\"\n [questions]=\"ques?.qbReferenceQuestions?.bookQuestionsMap?.[ques?.qbReference]?.subQuestions\"\n [isEdit]=\"isEdit\" [from]=\"'questionbook'\"\n (handleDropDown)=\"getDropDown($event)\">\n </lib-questionbook>\n <!-- SKS11JUN25 Text, Email, label, number, Boolean, rich text editor, DateTime, Date, Time-->\n <!-- SKS16OCT25 added custom style fields for input -->\n <nxt-input *ngIf=\"['Space','Text','Email','Number','Label','Boolean','RichTextArea','DateTime','month','Date','Time','TextArea','Location','currency'].includes(ques.type)\"\n [type]=\"ques.type === 'Text' ? 'text' : ques.type === 'Email' ? 'email' : ques.type === 'Number' ? 'number' : ques.type === 'Label' ? 'label' : ques.type === 'Boolean' ? 'checkbox' : ques.type === 'RichTextArea' ? 'richtext' : ques.type === 'DateTime' ? 'datetime' : ques.type === 'Date' ? 'date' : ques.type === 'Time' ? 'time' : ques.type === 'TextArea' ? 'textarea' : ques.type === 'month' ? 'month' : ques.type === 'Location' ? 'location' : ques.type === 'Space' ? 'space' : ques.type === 'currency' ? 'currency': 'text'\"\n [mode]=\"isEdit !== true ? 'view' : 'edit'\"\n [value]=\"ques.input\" [class]=\"ques?.style?.inputClass\"\n [question]=\"ques\" [readOnly]=\"ques.isReadOnly\"\n [apiKey]=\"qbItem['apiKey']\"\n [labelFont]=\"ques.font\"\n [label]=\"ques?.questionText ? ((ques.id+'.questionText') | nxtCustomTranslate : ques?.questionText): ''\"\n [showLabel]=\"ques.style?.showLabel\"\n svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"ques?.question ? ((ques.id+'.question') | nxtCustomTranslate : ques?.question ): ''\"\n [required]=\"ques.isOptional\"\n [inputId]=\"ques.trackingId\"\n [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"ques.iconLeftSrc\" \n [minDate]=\"ques.minDate\"\n [rows]=\"2\"\n [apiMeta]=\"ques.subText\"\n [direction]=\"direction\"\n [onlyView]=\"onlyView\"\n [from]=\"'nxtForm'\"\n\n [padding]=\"ques?.style?.padding\" [margin]=\"ques?.style?.margin\" [inputValueSize]=\"ques?.style?.inputFontSize\"\n [inputBorder]=\"ques?.style?.border || '#ccc'\" [inputBgColor]=\"ques?.style?.bgColor || '#ffffff'\"\n [labelSize]=\"ques?.style?.labelFontSize\" [labelWeight]=\"ques?.style?.labelFontWeight\"\n [inputWeight]=\"ques?.style?.inputFontWeight\" [labelColor]=\"ques?.style?.labelColor\"\n [textAlign]=\"ques?.style?.textAlign\" [rows]=\"ques?.style?.rows\"\n\n [style.padding]=\"ques.type === 'Space' ? ques?.style?.padding : null\"\n [style.margin]=\"ques.type === 'Space' ? ques?.style?.margin : null\"\n\n (inputValue)=\"childEventCapture($event.value,$event.question, 'nxt-input')\"\n >\n </nxt-input>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n\n<!--SKS25MAR25 Modal Overlay -->\n<div class=\"modal-overlay\" *ngIf=\"isImageEdit\">\n <div class=\"modal-content\">\n <span class=\"close-button\" (click)=\"closeModal()\">\u00D7</span>\n\n <!-- Image Editor -->\n <div *ngIf=\"selectedImageElement?.type === 'Image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedImageElement.imageData\" [imageBase64]=\"selectedImageElement.orgImageData\"\n [disabled]=\"false\" [alignImage]=\"alignImage\" [roundCropper]=\"roundCropper\" [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\" [allowMoveImage]=\"false\" [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation\" [aspectRatio]=\"aspectRatio\" [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\" [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\" [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\" [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\" [resetCropOnAspectRatioChange]='true' [(cropper)]=\"cropper\"\n [(transform)]=\"transform\" [onlyScaleDown]=\"true\" output=\"blob\" format=\"png\"\n (imageCropped)=\"imageCropped($event)\" (cropperReady)=\"cropperReady($event)\">\n </image-cropper>\n </div>\n\n <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"Rotate Left\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [class.enabled]=\"transform.flipH\"\n title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n </div>\n </div>\n</div>", styles: [".col-lg-6{width:100%}.myt-font7{display:flex;justify-content:flex-start;align-items:center}.icon{display:inline-block;width:15px;height:15px;border-radius:50%;background-color:#08010177;color:#fff;text-align:center;line-height:16px;font-size:11px;font-family:Arial,sans-serif;font-weight:700;margin-left:5px}@media (min-width: 1200px){.col-lg-6{width:50%!important}.col-lg-6,.col-lg-4{padding-left:5px!important;padding-right:5px!important}.form-row{display:-ms-flexbox!important;display:flex!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}}.icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background-color:#f5f5f5;border:1px solid #ddd;color:#666;margin-left:4px;font-size:12px;cursor:pointer!important}::ng-deep .mat-tooltip-panel{background:#fff!important}::ng-deep .mat-tooltip{background-color:#fff!important;color:#333!important;white-space:pre-line!important;line-height:1.5!important}.mat-tooltip{padding:8px 16px!important}::ng-deep .white-tooltip{white-space:pre-line!important;line-height:1.5!important}.custom-line{width:100%;border:1px solid #d9d9d9}.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:100}.modal-content{background:#fff;padding:20px;width:500px;max-width:90%;border-radius:8px;position:relative;text-align:center}.close-button{position:absolute;top:6px;right:6px;font-size:25px;cursor:pointer;z-index:10}.controls{display:flex;gap:5px;justify-content:center;margin-top:10px}.logo-icon{cursor:pointer;padding:5px;width:35px;border-radius:5px;background:#d3d3d3}.logo-icon:hover{background:#a9a9a9}.enabled{background:#007bff;color:#fff}input[type=checkbox]{width:21px}.boolean-question{display:flex;align-items:center;gap:10px;padding-top:14px;padding-bottom:12px}.form-control[disabled]{border-radius:5px;background-color:#e9ecef!important}\n"] }]
|
|
57980
|
-
}], ctorParameters: () => [{ type: DataService }, { type: ChangeService }
|
|
57945
|
+
}], ctorParameters: () => [{ type: DataService }, { type: ChangeService }], propDecorators: { qbItem: [{
|
|
57981
57946
|
type: Input
|
|
57982
57947
|
}], questionItem: [{
|
|
57983
57948
|
type: Input
|
|
@@ -58030,7 +57995,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
58030
57995
|
class BookletComponent {
|
|
58031
57996
|
sfService;
|
|
58032
57997
|
dataService;
|
|
58033
|
-
storageService;
|
|
58034
57998
|
sanitizer;
|
|
58035
57999
|
changeService;
|
|
58036
58000
|
http;
|
|
@@ -58082,10 +58046,9 @@ class BookletComponent {
|
|
|
58082
58046
|
stickyBar;
|
|
58083
58047
|
destroy$ = new Subject();
|
|
58084
58048
|
scrollHandler = (event) => { };
|
|
58085
|
-
constructor(sfService, dataService,
|
|
58049
|
+
constructor(sfService, dataService, sanitizer, changeService, http, translationService, ngZone, cdr) {
|
|
58086
58050
|
this.sfService = sfService;
|
|
58087
58051
|
this.dataService = dataService;
|
|
58088
|
-
this.storageService = storageService;
|
|
58089
58052
|
this.sanitizer = sanitizer;
|
|
58090
58053
|
this.changeService = changeService;
|
|
58091
58054
|
this.http = http;
|
|
@@ -58182,7 +58145,6 @@ class BookletComponent {
|
|
|
58182
58145
|
});
|
|
58183
58146
|
this.bookletJSON['bookQuestionsMap'][Object.keys(this.bookletJSON?.bookQuestionsMap)[0]].subQuestions = tempbook;
|
|
58184
58147
|
// Storing the API response for future use
|
|
58185
|
-
this.storageService.save(this.bookletJSON);
|
|
58186
58148
|
}
|
|
58187
58149
|
// Process the Questions
|
|
58188
58150
|
// HA 28DEC23 this applies for booklet
|
|
@@ -58239,8 +58201,6 @@ class BookletComponent {
|
|
|
58239
58201
|
};
|
|
58240
58202
|
successReadBooklet = (response) => {
|
|
58241
58203
|
if (response != null || response != undefined) {
|
|
58242
|
-
// Storing the API response for future use
|
|
58243
|
-
this.storageService.save(response);
|
|
58244
58204
|
// Try to pass a value from Backend to differentiate the QuestionBook Read and AnswerBook Read
|
|
58245
58205
|
// this.isAnswerFlag = true;
|
|
58246
58206
|
this.booklet = response.records;
|
|
@@ -58291,7 +58251,7 @@ class BookletComponent {
|
|
|
58291
58251
|
dataToParent['actionData'] = action?.['actionData'];
|
|
58292
58252
|
if (!(action?.eventtoemit === 'close' || action?.eventtoemit === 'print')) {
|
|
58293
58253
|
// HA 18-JAN-24 Sending the complete json data also
|
|
58294
|
-
dataToParent['jsonBook'] =
|
|
58254
|
+
dataToParent['jsonBook'] = JSON.parse(JSON.stringify(this.bookletJSON));
|
|
58295
58255
|
// HA 17JAN24 nxtId to dataParent object
|
|
58296
58256
|
if (this.bookletJSON) {
|
|
58297
58257
|
dataToParent['nxtId'] = Object.keys(this.bookletJSON?.bookQuestionsMap)[0];
|
|
@@ -58702,7 +58662,7 @@ class BookletComponent {
|
|
|
58702
58662
|
this.subscription.unsubscribe();
|
|
58703
58663
|
}
|
|
58704
58664
|
}
|
|
58705
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: BookletComponent, deps: [{ token: SalesforceService }, { token: DataService }, { token:
|
|
58665
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: BookletComponent, deps: [{ token: SalesforceService }, { token: DataService }, { token: i1$2.DomSanitizer }, { token: ChangeService }, { token: i1$1.HttpClient }, { token: TranslationService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
58706
58666
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: BookletComponent, isStandalone: true, selector: "lib-booklet", inputs: { bookletId: "bookletId", serv: "serv", tkn: "tkn", bookletJSON: "bookletJSON", allIcons: "allIcons", themeColor: "themeColor", cdnIconURL: "cdnIconURL", dropdownDependentData: "dropdownDependentData", labelValue: "labelValue", token: "token", languageCode: "languageCode", fieldRestrictions: "fieldRestrictions", from: "from", apiUrl: "apiUrl", isEdit: "isEdit", direction: "direction", isLoading: "isLoading", onlyView: "onlyView", dataBind: "dataBind" }, outputs: { handleBookletActionEvent: "handleBookletActionEvent", handlePage: "handlePage", hadleDropDownDependent: "hadleDropDownDependent", handleCalendarDate: "handleCalendarDate", handleCalendarEvent: "handleCalendarEvent" }, viewQueries: [{ propertyName: "questionbookComponent", first: true, predicate: ["questionbook"], descendants: true }, { propertyName: "stickyBar", first: true, predicate: ["stickyBar"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Booklet Handling-->\n<!-- HA 19DEC23 For Direction -->\n<div *ngFor=\"let qb of booklet\" [dir]=\"direction\">\n <!-- MR Commented below code to ensure single JSON for UNCONDITIONAL Booklets -->\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.id+'.questionText') | nxtCustomTranslate : ques?.questionText }}\n </div>\n </div>\n <!--VD 06Sep24 calendar changes-->\n <!-- AP-14MAY25 - Added [dataBind] input binding -->\n <!-- AP-19MAY25 - Added [isEditVal] binding --> \n <!-- //MSM10JUL25 allIcons, themeColor, cdnIconURL added for icon-selector-->\n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\"\n [direction] = \"direction\"\n [labelValue]=\"labelValue\"\n [questionItem]=\"ques\"\n [questions]=\"bookQuestionsMap?.get(qb.id)?.subQuestions\"\n (handleDropDown)=\"getDropDown($event)\"\n (handleCalendarDate)=\"getCalendarDate($event)\"\n (handleCalendarEvent)=\"getCalendarEvent($event)\"\n (singleFieldChangeEmit) ='singleFieldChange($event)'\n [dataBind]=\"dataBind\"\n [isEdit]=\"isEditVal\" \n [allIcons]=\"allIcons\"\n [themeColor]=\"themeColor\"\n [cdnIconURL]=\"cdnIconURL\"\n [languageCode]=\"languageCode\"\n [onlyView]=\"onlyView\"\n >\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.id+'.questionText') | nxtCustomTranslate : qb?.questionText}}\n {{ qb?.title }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!-- // VD 11Jun24 - translation changes-->\n <lib-questionbook [onlyView]=\"onlyView\" [qbItem]=\"qb\" [token]=\"token\" [labelValue]=\"labelValue\" [questionItem]=\"qb\" [questions]=\"bookQuestionsMap?.get(qb.id)?.subQuestions\" (handleDropDown)=\"getDropDown($event)\" [languageCode]=\"languageCode\"></lib-questionbook>\n </div>\n </div>\n </ng-template>\n <!-- Group Actions -->\n <!-- HA 19DEC23 For Direction -->\n <!-- AP 23MAY25 - Action Buttons: Dynamically positioned buttons with JSON-configured styles -->\n <div #stickyBar class=\"align-submit-row\" [ngStyle]=\"{\n display: 'flex',\n position: 'sticky',\n bottom: '0px',\n zIndex: '1000',\n width: '100%',\n justifyContent: 'flex-end',\n background: '#ffffff',\n padding: '10px',\n gap: '10px',\n boxShadow: showStickyShadow ? 'rgba(0, 0, 0, 0.12) 0px -10px 8px -10px' : 'none'\n }\" *ngIf=\"abItem?.status != 'Completed' && from !== 'formBuilder' && !onlyView\" [dir]=\"direction\"> <!-- position-relative removed in this tag-->\n <ng-container *ngFor=\"let action of actions; let i = index\">\n <div class=\"action-wrapper\"> <!-- style=\"position: absolute; [style.left.%]=\"action.positionPercent || 0\" removed in this tag -->\n @if(!isEditVal && action.name === 'Save'){\n <nxt-button\n (buttonClickEmit)=\"editChangeClick(action)\"\n [buttonValue]=\"'EDIT' | nxtCustomTranslate : 'Edit'\"\n [btnBorder]=\"action.borderSize\"\n [btnBorderColor]=\"action.borderColor\"\n [btnBorderRadius]=\"action.borderRadius || 4\"\n [btnWidth]=\"action.width || 100\"\n [buttonType]=\"'custom-btn'\"\n [buttonConfig]=\"action?.buttonConfig\" [type]=\"action?.type\"\n [btnIconLeftSrc]=\"action?.btnIconLeftSrc\" [isImageSvg]=\"action?.isImageSvg\"\n >\n </nxt-button>\n } @else {\n <nxt-button\n (buttonClickEmit)=\"handleBookletActionClick(action)\" \n [isLoading]=\"isLoading?.includes(action.id)\"\n [buttonValue]=\"(action.id+'.name') | nxtCustomTranslate : action?.name\"\n [btnBorder]=\"action.borderSize\"\n [btnBorderRadius]=\"action.borderRadius || 4\"\n [btnWidth]=\"action.width || 100\"\n [buttonType]=\"action.name === 'Cancel' ? 'border-btn' : 'custom-btn'\"\n [buttonConfig]=\"action?.buttonConfig\" [type]=\"action?.type\"\n [btnIconLeftSrc]=\"action?.btnIconLeftSrc\" [isImageSvg]=\"action?.isImageSvg\"\n [buttonDisable]=\"action.name === 'Save' && isSaveDisabled\"\n >\n </nxt-button>\n }\n </div>\n </ng-container>\n </div>\n</div>", styles: [".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: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: QuestionbookComponent, selector: "lib-questionbook", inputs: ["qbItem", "questionItem", "questions", "errorFieldId", "labelValue", "token", "isEdit", "dropDownData", "dataBind", "allIcons", "themeColor", "cdnIconURL", "direction", "languageCode", "from", "bgColor", "margin", "onlyView"], outputs: ["handleDropDown", "handleQuestion", "singleFieldChangeEmit", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent"] }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }, { kind: "component", type: NxtButtonComponent, selector: "nxt-button", inputs: ["buttonValue", "buttonType", "type", "buttonDisable", "btnBgColor", "btnBorder", "btnBorderRadius", "btnBorderColor", "btnTextColor", "btnHeight", "btnWidth", "btnIconLeftSrc", "btnIconRightSrc", "btnHoverBgColor", "btnHoverTextColor", "btnId", "dataDismiss", "modalToTrigger", "isImageSvg", "tabIndex", "buttonConfig", "mode", "languageCode", "padding", "isLoading", "selector", "dropdownLoadingButton"], outputs: ["buttonClickEmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
58707
58667
|
}
|
|
58708
58668
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: BookletComponent, decorators: [{
|
|
@@ -58714,7 +58674,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
58714
58674
|
NxtCustomTranslatePipe,
|
|
58715
58675
|
NxtButtonComponent
|
|
58716
58676
|
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Booklet Handling-->\n<!-- HA 19DEC23 For Direction -->\n<div *ngFor=\"let qb of booklet\" [dir]=\"direction\">\n <!-- MR Commented below code to ensure single JSON for UNCONDITIONAL Booklets -->\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.id+'.questionText') | nxtCustomTranslate : ques?.questionText }}\n </div>\n </div>\n <!--VD 06Sep24 calendar changes-->\n <!-- AP-14MAY25 - Added [dataBind] input binding -->\n <!-- AP-19MAY25 - Added [isEditVal] binding --> \n <!-- //MSM10JUL25 allIcons, themeColor, cdnIconURL added for icon-selector-->\n <lib-questionbook [qbItem]=\"qb\" [token]=\"token\"\n [direction] = \"direction\"\n [labelValue]=\"labelValue\"\n [questionItem]=\"ques\"\n [questions]=\"bookQuestionsMap?.get(qb.id)?.subQuestions\"\n (handleDropDown)=\"getDropDown($event)\"\n (handleCalendarDate)=\"getCalendarDate($event)\"\n (handleCalendarEvent)=\"getCalendarEvent($event)\"\n (singleFieldChangeEmit) ='singleFieldChange($event)'\n [dataBind]=\"dataBind\"\n [isEdit]=\"isEditVal\" \n [allIcons]=\"allIcons\"\n [themeColor]=\"themeColor\"\n [cdnIconURL]=\"cdnIconURL\"\n [languageCode]=\"languageCode\"\n [onlyView]=\"onlyView\"\n >\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.id+'.questionText') | nxtCustomTranslate : qb?.questionText}}\n {{ qb?.title }}\n </div>\n </div> <!-- VD 19JAN24 - getting token as input --> <!-- // VD 11Jun24 - translation changes-->\n <lib-questionbook [onlyView]=\"onlyView\" [qbItem]=\"qb\" [token]=\"token\" [labelValue]=\"labelValue\" [questionItem]=\"qb\" [questions]=\"bookQuestionsMap?.get(qb.id)?.subQuestions\" (handleDropDown)=\"getDropDown($event)\" [languageCode]=\"languageCode\"></lib-questionbook>\n </div>\n </div>\n </ng-template>\n <!-- Group Actions -->\n <!-- HA 19DEC23 For Direction -->\n <!-- AP 23MAY25 - Action Buttons: Dynamically positioned buttons with JSON-configured styles -->\n <div #stickyBar class=\"align-submit-row\" [ngStyle]=\"{\n display: 'flex',\n position: 'sticky',\n bottom: '0px',\n zIndex: '1000',\n width: '100%',\n justifyContent: 'flex-end',\n background: '#ffffff',\n padding: '10px',\n gap: '10px',\n boxShadow: showStickyShadow ? 'rgba(0, 0, 0, 0.12) 0px -10px 8px -10px' : 'none'\n }\" *ngIf=\"abItem?.status != 'Completed' && from !== 'formBuilder' && !onlyView\" [dir]=\"direction\"> <!-- position-relative removed in this tag-->\n <ng-container *ngFor=\"let action of actions; let i = index\">\n <div class=\"action-wrapper\"> <!-- style=\"position: absolute; [style.left.%]=\"action.positionPercent || 0\" removed in this tag -->\n @if(!isEditVal && action.name === 'Save'){\n <nxt-button\n (buttonClickEmit)=\"editChangeClick(action)\"\n [buttonValue]=\"'EDIT' | nxtCustomTranslate : 'Edit'\"\n [btnBorder]=\"action.borderSize\"\n [btnBorderColor]=\"action.borderColor\"\n [btnBorderRadius]=\"action.borderRadius || 4\"\n [btnWidth]=\"action.width || 100\"\n [buttonType]=\"'custom-btn'\"\n [buttonConfig]=\"action?.buttonConfig\" [type]=\"action?.type\"\n [btnIconLeftSrc]=\"action?.btnIconLeftSrc\" [isImageSvg]=\"action?.isImageSvg\"\n >\n </nxt-button>\n } @else {\n <nxt-button\n (buttonClickEmit)=\"handleBookletActionClick(action)\" \n [isLoading]=\"isLoading?.includes(action.id)\"\n [buttonValue]=\"(action.id+'.name') | nxtCustomTranslate : action?.name\"\n [btnBorder]=\"action.borderSize\"\n [btnBorderRadius]=\"action.borderRadius || 4\"\n [btnWidth]=\"action.width || 100\"\n [buttonType]=\"action.name === 'Cancel' ? 'border-btn' : 'custom-btn'\"\n [buttonConfig]=\"action?.buttonConfig\" [type]=\"action?.type\"\n [btnIconLeftSrc]=\"action?.btnIconLeftSrc\" [isImageSvg]=\"action?.isImageSvg\"\n [buttonDisable]=\"action.name === 'Save' && isSaveDisabled\"\n >\n </nxt-button>\n }\n </div>\n </ng-container>\n </div>\n</div>", styles: [".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"] }]
|
|
58717
|
-
}], ctorParameters: () => [{ type: SalesforceService }, { type: DataService }, { type:
|
|
58677
|
+
}], ctorParameters: () => [{ type: SalesforceService }, { type: DataService }, { type: i1$2.DomSanitizer }, { type: ChangeService }, { type: i1$1.HttpClient }, { type: TranslationService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { bookletId: [{
|
|
58718
58678
|
type: Input
|
|
58719
58679
|
}], serv: [{
|
|
58720
58680
|
type: Input
|
|
@@ -58781,7 +58741,7 @@ const VERSION = {
|
|
|
58781
58741
|
"semver": null,
|
|
58782
58742
|
"suffix": "68a4eb8b-dirty",
|
|
58783
58743
|
"semverString": null,
|
|
58784
|
-
"version": "2.1.
|
|
58744
|
+
"version": "2.1.325"
|
|
58785
58745
|
};
|
|
58786
58746
|
/* tslint:enable */
|
|
58787
58747
|
|
|
@@ -63964,11 +63924,11 @@ class PropertiesComponent {
|
|
|
63964
63924
|
}
|
|
63965
63925
|
}
|
|
63966
63926
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: PropertiesComponent, deps: [{ token: FormBuilderService }, { token: TemplateService }, { token: TranslationService }, { token: i0.ChangeDetectorRef }, { token: DataService }], target: i0.ɵɵFactoryTarget.Component });
|
|
63967
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: PropertiesComponent, isStandalone: true, selector: "app-properties", inputs: { templateSelected: "templateSelected", selectedElementType: "selectedElementType" }, outputs: { formButtonHandler: "formButtonHandler", templateSaveHandler: "templateSaveHandler" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_ID' | nxtCustomTranslate : 'Button ID' }}</label>\n <input type=\"text\" [ngModel]=\"btn.id\" (ngModelChange)=\"onButtonPropertyChange(i, 'id', $event,true)\" placeholder=\"Enter button id\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <ng-container *ngIf=\"formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"(btn.id + '.name' | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n <span>{{ translated }}</span>\n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ACTION_DATA' | nxtCustomTranslate : 'Action Data' }}</label>\n <input type=\"text\" [ngModel]=\"btn.actionData\" (ngModelChange)=\"onButtonPropertyChange(i, 'actionData', $event)\" placeholder=\"Event to actionData\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_SIZE' | nxtCustomTranslate : 'Border Size' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderSize\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderSize', $event)\">\n <span>{{ btn.borderSize }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_COLOR' | nxtCustomTranslate : 'Border Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.borderColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <div class=\"form-group\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"btn.updateParentData\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'updateParentData', $event)\"\n />\n {{ 'UPDATE_PARENTDATA' | nxtCustomTranslate : 'updateParentData' }}\n </label>\n </div> \n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text' || subProp.type === 'number'\"\n [type]=\"subProp.type\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getOptimizedSubPropValue(subProp)\"\n (change)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.checked, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.checked, prop.isTranslate)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key , prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) :setValueByPath(prop.key, $event, prop.isTranslate) ) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"selectedElement()?.color\"\n (ngModelChange)=\"setValueByPath('color', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd}.save-btn{background:#0052cc;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px!important;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;width:35px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i5.NgClass, i5.NgForOf, i5.NgIf, i6.NgSelectOption, i6.ɵNgSelectMultipleOption, i6.DefaultValueAccessor, i6.NumberValueAccessor, i6.RangeValueAccessor, i6.CheckboxControlValueAccessor, i6.SelectControlValueAccessor, i6.NgControlStatus, i6.MinValidator, i6.NgModel, Promise.resolve().then(function () { return searchBox_component; }).then(m => m.NxtSearchBox), GetValueByPathPipe, NxtCustomTranslatePipe, Promise.resolve().then(function () { return formulaInput_component; }).then(m => m.FormulaInputComponent)], () => [i5.NgClass, i5.NgIf, Promise.resolve().then(function () { return imageCropper_component; }).then(m => m.ImageCropperComponent), NxtCustomTranslatePipe], () => [i5.NgForOf, i5.NgIf, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe, Promise.resolve().then(function () { return formulaInput_component; }).then(m => m.FormulaInputComponent)], () => [i5.NgForOf, i5.NgIf, i6.NgSelectOption, i6.ɵNgSelectMultipleOption, i6.DefaultValueAccessor, i6.SelectControlValueAccessor, i6.NgControlStatus, i6.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe]] });
|
|
63927
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: PropertiesComponent, isStandalone: true, selector: "app-properties", inputs: { templateSelected: "templateSelected", selectedElementType: "selectedElementType" }, outputs: { formButtonHandler: "formButtonHandler", templateSaveHandler: "templateSaveHandler" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_ID' | nxtCustomTranslate : 'Button ID' }}</label>\n <input type=\"text\" [ngModel]=\"btn.id\" (ngModelChange)=\"onButtonPropertyChange(i, 'id', $event,true)\" placeholder=\"Enter button id\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <ng-container *ngIf=\"formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"(btn.id + '.name' | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n <span>{{ translated }}</span>\n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ACTION_DATA' | nxtCustomTranslate : 'Action Data' }}</label>\n <input type=\"text\" [ngModel]=\"btn.actionData\" (ngModelChange)=\"onButtonPropertyChange(i, 'actionData', $event)\" placeholder=\"Event to actionData\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_SIZE' | nxtCustomTranslate : 'Border Size' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderSize\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderSize', $event)\">\n <span>{{ btn.borderSize }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_COLOR' | nxtCustomTranslate : 'Border Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.borderColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <div class=\"form-group\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"btn.updateParentData\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'updateParentData', $event)\"\n />\n {{ 'UPDATE_PARENTDATA' | nxtCustomTranslate : 'updateParentData' }}\n </label>\n </div> \n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : 'isOptional')) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange('isOptional', $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : 'isReadOnly')) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange('isReadOnly', $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : 'isHidden')) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange('isHidden', $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text' || subProp.type === 'number'\"\n [type]=\"subProp.type\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getOptimizedSubPropValue(subProp)\"\n (change)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.checked, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.checked, prop.isTranslate)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key , prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) :setValueByPath(prop.key, $event, prop.isTranslate) ) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"selectedElement()?.color\"\n (ngModelChange)=\"setValueByPath('color', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd}.save-btn{background:#0052cc;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px!important;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;width:35px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i5.NgClass, i5.NgForOf, i5.NgIf, i6.NgSelectOption, i6.ɵNgSelectMultipleOption, i6.DefaultValueAccessor, i6.NumberValueAccessor, i6.RangeValueAccessor, i6.CheckboxControlValueAccessor, i6.SelectControlValueAccessor, i6.NgControlStatus, i6.MinValidator, i6.NgModel, Promise.resolve().then(function () { return searchBox_component; }).then(m => m.NxtSearchBox), GetValueByPathPipe, NxtCustomTranslatePipe, Promise.resolve().then(function () { return formulaInput_component; }).then(m => m.FormulaInputComponent)], () => [i5.NgClass, i5.NgIf, Promise.resolve().then(function () { return imageCropper_component; }).then(m => m.ImageCropperComponent), NxtCustomTranslatePipe], () => [i5.NgForOf, i5.NgIf, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe, Promise.resolve().then(function () { return formulaInput_component; }).then(m => m.FormulaInputComponent)], () => [i5.NgForOf, i5.NgIf, i6.NgSelectOption, i6.ɵNgSelectMultipleOption, i6.DefaultValueAccessor, i6.SelectControlValueAccessor, i6.NgControlStatus, i6.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe]] });
|
|
63968
63928
|
}
|
|
63969
63929
|
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "19.2.18", ngImport: i0, type: PropertiesComponent, resolveDeferredDeps: () => [Promise.resolve().then(function () { return searchBox_component; }).then(m => m.NxtSearchBox), Promise.resolve().then(function () { return formulaInput_component; }).then(m => m.FormulaInputComponent), Promise.resolve().then(function () { return imageCropper_component; }).then(m => m.ImageCropperComponent)], resolveMetadata: (NxtSearchBox, FormulaInputComponent, ImageCropperComponent) => ({ decorators: [{
|
|
63970
63930
|
type: Component,
|
|
63971
|
-
args: [{ selector: 'app-properties', standalone: true, imports: [CommonModule, FormsModule, ImageCropperComponent, NxtSearchBox, NgClass, NgFor, NgIf, GetValueByPathPipe, NxtCustomTranslatePipe, FormulaInputComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_ID' | nxtCustomTranslate : 'Button ID' }}</label>\n <input type=\"text\" [ngModel]=\"btn.id\" (ngModelChange)=\"onButtonPropertyChange(i, 'id', $event,true)\" placeholder=\"Enter button id\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <ng-container *ngIf=\"formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"(btn.id + '.name' | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n <span>{{ translated }}</span>\n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ACTION_DATA' | nxtCustomTranslate : 'Action Data' }}</label>\n <input type=\"text\" [ngModel]=\"btn.actionData\" (ngModelChange)=\"onButtonPropertyChange(i, 'actionData', $event)\" placeholder=\"Event to actionData\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_SIZE' | nxtCustomTranslate : 'Border Size' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderSize\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderSize', $event)\">\n <span>{{ btn.borderSize }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_COLOR' | nxtCustomTranslate : 'Border Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.borderColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <div class=\"form-group\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"btn.updateParentData\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'updateParentData', $event)\"\n />\n {{ 'UPDATE_PARENTDATA' | nxtCustomTranslate : 'updateParentData' }}\n </label>\n </div> \n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text' || subProp.type === 'number'\"\n [type]=\"subProp.type\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getOptimizedSubPropValue(subProp)\"\n (change)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.checked, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.checked, prop.isTranslate)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key , prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) :setValueByPath(prop.key, $event, prop.isTranslate) ) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"selectedElement()?.color\"\n (ngModelChange)=\"setValueByPath('color', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd}.save-btn{background:#0052cc;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px!important;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;width:35px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"] }]
|
|
63931
|
+
args: [{ selector: 'app-properties', standalone: true, imports: [CommonModule, FormsModule, ImageCropperComponent, NxtSearchBox, NgClass, NgFor, NgIf, GetValueByPathPipe, NxtCustomTranslatePipe, FormulaInputComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_ID' | nxtCustomTranslate : 'Button ID' }}</label>\n <input type=\"text\" [ngModel]=\"btn.id\" (ngModelChange)=\"onButtonPropertyChange(i, 'id', $event,true)\" placeholder=\"Enter button id\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <ng-container *ngIf=\"formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"(btn.id + '.name' | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n <span>{{ translated }}</span>\n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ACTION_DATA' | nxtCustomTranslate : 'Action Data' }}</label>\n <input type=\"text\" [ngModel]=\"btn.actionData\" (ngModelChange)=\"onButtonPropertyChange(i, 'actionData', $event)\" placeholder=\"Event to actionData\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_SIZE' | nxtCustomTranslate : 'Border Size' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderSize\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderSize', $event)\">\n <span>{{ btn.borderSize }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_COLOR' | nxtCustomTranslate : 'Border Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.borderColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" style=\"width: 100%;\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <div class=\"form-group\">\n <label>\n <input type=\"checkbox\" [ngModel]=\"btn.updateParentData\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'updateParentData', $event)\"\n />\n {{ 'UPDATE_PARENTDATA' | nxtCustomTranslate : 'updateParentData' }}\n </label>\n </div> \n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : 'isOptional')) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange('isOptional', $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : 'isReadOnly')) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange('isReadOnly', $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : 'isHidden')) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? ((prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange('isHidden', $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text' || subProp.type === 'number'\"\n [type]=\"subProp.type\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getOptimizedSubPropValue(subProp)\"\n (change)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.checked, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.checked, prop.isTranslate)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <!-- SKS16SEP25 formula -->\n <div *ngIf=\"prop.type === 'formula'\">\n <app-formula-input\n [attributes]=\"selectedElement['fieldsMeta']\"\n [initialFormula]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key , prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (formulaChange)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) :setValueByPath(prop.key, $event, prop.isTranslate) ) : setValueByPath(prop.key, $event, prop.isTranslate)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\" style=\"width: 100%;\"\n [ngModel]=\"selectedElement()?.color\"\n (ngModelChange)=\"setValueByPath('color', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd}.save-btn{background:#0052cc;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px!important;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;width:35px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"] }]
|
|
63972
63932
|
}], ctorParameters: () => [{ type: FormBuilderService }, { type: TemplateService }, { type: TranslationService }, { type: i0.ChangeDetectorRef }, { type: DataService }], propDecorators: { templateSelected: [{
|
|
63973
63933
|
type: Input
|
|
63974
63934
|
}], selectedElementType: [{
|