@rangertechnologies/ngnxt 2.1.349 → 2.1.350
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 +1938 -116
- package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
- package/lib/pages/pdfDesigner/pdf-designer/booklet.component.d.ts +44 -0
- package/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.d.ts +60 -3
- package/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.d.ts +270 -0
- package/lib/services/pdf-designer/pdf-designer.service.d.ts +110 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/rangertechnologies-ngnxt-2.1.350.tgz +0 -0
- package/rangertechnologies-ngnxt-2.1.349.tgz +0 -0
|
@@ -48502,7 +48502,7 @@ class nxtDropdown {
|
|
|
48502
48502
|
}
|
|
48503
48503
|
change['valueObj'] = value;
|
|
48504
48504
|
change['field'] = changeField;
|
|
48505
|
-
change['referenceField'] = this.
|
|
48505
|
+
change['referenceField'] = this.question?.referenceField;
|
|
48506
48506
|
this.valueChange.emit({ question: this.question, value: change });
|
|
48507
48507
|
if (this.apiMeta?.isCurrencyField) {
|
|
48508
48508
|
this.countryService.currencyCodeSet(change['valueObj']);
|
|
@@ -48542,7 +48542,7 @@ class nxtDropdown {
|
|
|
48542
48542
|
this.valueChange.emit({ question: this.question, value: {
|
|
48543
48543
|
fromQuestionId: this.question?.id,
|
|
48544
48544
|
valueObj: '',
|
|
48545
|
-
referenceField: this.
|
|
48545
|
+
referenceField: this.question?.referenceField,
|
|
48546
48546
|
} });
|
|
48547
48547
|
if (this.apiMeta?.isCurrencyField) {
|
|
48548
48548
|
this.countryService.currencyCodeSet('INR');
|
|
@@ -48567,7 +48567,7 @@ class nxtDropdown {
|
|
|
48567
48567
|
change['fromQuestionId'] = this.question?.id;
|
|
48568
48568
|
change['valueObj'] = value;
|
|
48569
48569
|
change['field'] = changeField;
|
|
48570
|
-
change['referenceField'] = this.
|
|
48570
|
+
change['referenceField'] = this.question?.referenceField;
|
|
48571
48571
|
this.valueChange.emit({ question: ques, value: change });
|
|
48572
48572
|
if (this.apiMeta?.isCurrencyField) {
|
|
48573
48573
|
this.countryService.currencyCodeSet(change['valueObj']);
|
|
@@ -50658,8 +50658,8 @@ class NxtSearchBox {
|
|
|
50658
50658
|
}
|
|
50659
50659
|
});
|
|
50660
50660
|
const queryParams = queryParamsArray.join('&');
|
|
50661
|
-
if (queryParams) {
|
|
50662
|
-
finalGetCall += this.apiMeta.endpoint.includes('?') ? `&${queryParams}` : `?${queryParams}`;
|
|
50661
|
+
if (queryParams) { //SKS29MAY26 fallback check added for '?'
|
|
50662
|
+
finalGetCall += (this.apiMeta.endpoint.includes('?') || finalGetCall.includes('?')) ? `&${queryParams}` : `?${queryParams}`;
|
|
50663
50663
|
}
|
|
50664
50664
|
}
|
|
50665
50665
|
if (finalGetCall) {
|
|
@@ -59067,7 +59067,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
59067
59067
|
type: Output
|
|
59068
59068
|
}] } });
|
|
59069
59069
|
|
|
59070
|
-
class BookletComponent {
|
|
59070
|
+
let BookletComponent$1 = class BookletComponent {
|
|
59071
59071
|
dataService;
|
|
59072
59072
|
changeService;
|
|
59073
59073
|
http;
|
|
@@ -59733,8 +59733,8 @@ class BookletComponent {
|
|
|
59733
59733
|
}
|
|
59734
59734
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BookletComponent, deps: [{ token: DataService }, { token: ChangeService }, { token: i1$1.HttpClient }, { token: TranslationService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
59735
59735
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", 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", formEditEvent: "formEditEvent" }, 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; trackBy: trackBooklet\" [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 <ng-container *ngFor=\"let ques of qb.subQuestions; trackBy: trackQuestion\">\n <div class=\"questiondiv1\">\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 *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]=\"qb.questions\"\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 </ng-container>\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 *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]=\"qb.questions\" (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; trackBy: trackAction\">\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 if(action.name === 'Cancel' ? isEditVal : true ) {\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", "bookStyle"], 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 });
|
|
59736
|
-
}
|
|
59737
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BookletComponent, decorators: [{
|
|
59736
|
+
};
|
|
59737
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BookletComponent$1, decorators: [{
|
|
59738
59738
|
type: Component,
|
|
59739
59739
|
args: [{ selector: 'lib-booklet', standalone: true, imports: [
|
|
59740
59740
|
CommonModule,
|
|
@@ -59812,7 +59812,7 @@ const VERSION = {
|
|
|
59812
59812
|
"semver": null,
|
|
59813
59813
|
"suffix": "ed0865a9-dirty",
|
|
59814
59814
|
"semverString": null,
|
|
59815
|
-
"version": "2.1.
|
|
59815
|
+
"version": "2.1.350"
|
|
59816
59816
|
};
|
|
59817
59817
|
/* tslint:enable */
|
|
59818
59818
|
|
|
@@ -60102,6 +60102,73 @@ class PdfDesignerService {
|
|
|
60102
60102
|
this.pdfElementsSubject.next([...this.pdfElements]);
|
|
60103
60103
|
}
|
|
60104
60104
|
}
|
|
60105
|
+
getDefaultPdfSettings() {
|
|
60106
|
+
return {
|
|
60107
|
+
pageSize: 'A4',
|
|
60108
|
+
pageOrientation: 'portrait',
|
|
60109
|
+
pageMargins: [40, 40, 40, 80],
|
|
60110
|
+
backgroundColor: '#ffffff',
|
|
60111
|
+
header: {
|
|
60112
|
+
enabled: false,
|
|
60113
|
+
showOn: 'all',
|
|
60114
|
+
text: '',
|
|
60115
|
+
leftText: '',
|
|
60116
|
+
centerText: '',
|
|
60117
|
+
rightText: '',
|
|
60118
|
+
alignment: 'center',
|
|
60119
|
+
fontSize: 9,
|
|
60120
|
+
color: '#666666',
|
|
60121
|
+
margin: [40, 20, 40, 0],
|
|
60122
|
+
bottomBorder: false,
|
|
60123
|
+
borderColor: '#2f9e44',
|
|
60124
|
+
borderWidth: 1
|
|
60125
|
+
},
|
|
60126
|
+
watermark: {
|
|
60127
|
+
enabled: false,
|
|
60128
|
+
text: '',
|
|
60129
|
+
color: '#9ca3af',
|
|
60130
|
+
opacity: 0.16,
|
|
60131
|
+
angle: -32,
|
|
60132
|
+
fontSize: 64
|
|
60133
|
+
},
|
|
60134
|
+
footer: {
|
|
60135
|
+
enabled: false,
|
|
60136
|
+
showOn: 'last',
|
|
60137
|
+
text: '',
|
|
60138
|
+
leftText: '',
|
|
60139
|
+
centerText: '',
|
|
60140
|
+
rightText: '',
|
|
60141
|
+
alignment: 'center',
|
|
60142
|
+
fontSize: 9,
|
|
60143
|
+
color: '#666666',
|
|
60144
|
+
margin: [40, 12, 40, 0],
|
|
60145
|
+
topBorder: false,
|
|
60146
|
+
borderColor: '#2f9e44',
|
|
60147
|
+
borderWidth: 1
|
|
60148
|
+
}
|
|
60149
|
+
};
|
|
60150
|
+
}
|
|
60151
|
+
ensurePdfSettings(pdf = this.pdf) {
|
|
60152
|
+
if (!pdf)
|
|
60153
|
+
return this.getDefaultPdfSettings();
|
|
60154
|
+
pdf.pdfSettings = {
|
|
60155
|
+
...this.getDefaultPdfSettings(),
|
|
60156
|
+
...(pdf.pdfSettings || {}),
|
|
60157
|
+
header: {
|
|
60158
|
+
...this.getDefaultPdfSettings().header,
|
|
60159
|
+
...(pdf.pdfSettings?.header || {})
|
|
60160
|
+
},
|
|
60161
|
+
watermark: {
|
|
60162
|
+
...this.getDefaultPdfSettings().watermark,
|
|
60163
|
+
...(pdf.pdfSettings?.watermark || {})
|
|
60164
|
+
},
|
|
60165
|
+
footer: {
|
|
60166
|
+
...this.getDefaultPdfSettings().footer,
|
|
60167
|
+
...(pdf.pdfSettings?.footer || {})
|
|
60168
|
+
}
|
|
60169
|
+
};
|
|
60170
|
+
return pdf.pdfSettings;
|
|
60171
|
+
}
|
|
60105
60172
|
intializeBook(pdf) {
|
|
60106
60173
|
// - Get the unique id in the pdf
|
|
60107
60174
|
this.unique_id = Object.keys(pdf)[0];
|
|
@@ -60118,6 +60185,7 @@ class PdfDesignerService {
|
|
|
60118
60185
|
});
|
|
60119
60186
|
pdf[this.unique_id] = tempbook;
|
|
60120
60187
|
this.pdf = pdf;
|
|
60188
|
+
this.ensurePdfSettings();
|
|
60121
60189
|
this.pdf[this.unique_id]?.forEach(element => {
|
|
60122
60190
|
this.addElement(element);
|
|
60123
60191
|
});
|
|
@@ -60141,6 +60209,7 @@ class PdfDesignerService {
|
|
|
60141
60209
|
this.pdf = {
|
|
60142
60210
|
[this.unique_id]: [],
|
|
60143
60211
|
'title': 'Untitled',
|
|
60212
|
+
'pdfSettings': this.getDefaultPdfSettings(),
|
|
60144
60213
|
};
|
|
60145
60214
|
}
|
|
60146
60215
|
// AP 26FEB25 - clear the form elements
|
|
@@ -60283,16 +60352,292 @@ class PdfDesignerService {
|
|
|
60283
60352
|
return this.pdf;
|
|
60284
60353
|
}
|
|
60285
60354
|
downloadElement() {
|
|
60286
|
-
|
|
60287
|
-
|
|
60355
|
+
return this.buildPdfBook(this.pdf, this.pdfElements);
|
|
60356
|
+
}
|
|
60357
|
+
buildPdfOutput(pdfJSON, dataBind = {}, pdfDefinitionOptions = {}, action = 'definition', elements) {
|
|
60358
|
+
const boundBook = this.buildBoundPdfBook(pdfJSON, dataBind, elements);
|
|
60359
|
+
const pdfDefinition = this.createPdfDefinition(boundBook, pdfDefinitionOptions);
|
|
60360
|
+
return {
|
|
60361
|
+
action,
|
|
60362
|
+
title: boundBook?.title || 'document',
|
|
60363
|
+
pdf: boundBook,
|
|
60364
|
+
book: boundBook,
|
|
60365
|
+
boundBook,
|
|
60366
|
+
pdfJson: boundBook?.pdfJson,
|
|
60367
|
+
pdfDefinition,
|
|
60368
|
+
dataBind
|
|
60369
|
+
};
|
|
60370
|
+
}
|
|
60371
|
+
buildPdfOutputFromConfig(config) {
|
|
60372
|
+
return this.buildPdfOutput(config?.pdfJSON, config?.dataBind || {}, config?.pdfDefinitionOptions || {}, config?.action || 'definition', config?.elements);
|
|
60373
|
+
}
|
|
60374
|
+
buildBoundPdfBook(pdfJSON = this.pdf, dataBind = {}, elements) {
|
|
60375
|
+
const sourcePdf = this.clonePlain(pdfJSON || this.pdf || {});
|
|
60376
|
+
sourcePdf.currencyCode = sourcePdf.currencyCode || dataBind?.currencyCode || dataBind?.customer?.currencyCode;
|
|
60377
|
+
sourcePdf.currency = sourcePdf.currency || dataBind?.currency;
|
|
60378
|
+
const uniqueId = this.getPdfUniqueId(sourcePdf);
|
|
60379
|
+
const sourceElements = elements || (uniqueId ? sourcePdf[uniqueId] : []);
|
|
60380
|
+
const boundElements = this.bindPdfElements(sourceElements, dataBind);
|
|
60381
|
+
return this.buildPdfBook(sourcePdf, boundElements);
|
|
60382
|
+
}
|
|
60383
|
+
bindPdfElements(elements = [], dataBind = {}) {
|
|
60384
|
+
const clonedElements = this.clonePlain(elements || []);
|
|
60385
|
+
if (dataBind && Object.keys(dataBind).length > 0) {
|
|
60386
|
+
clonedElements.forEach((question) => this.bindPdfQuestion(question, dataBind));
|
|
60387
|
+
}
|
|
60388
|
+
return clonedElements;
|
|
60389
|
+
}
|
|
60390
|
+
createPdfDefinition(boundBook, pdfDefinitionOptions = {}) {
|
|
60391
|
+
const pdfJson = boundBook?.pdfJson || {};
|
|
60392
|
+
const { defaultStyle, ...restOptions } = pdfDefinitionOptions || {};
|
|
60393
|
+
const pdfDefinition = {
|
|
60394
|
+
...pdfJson,
|
|
60395
|
+
...restOptions,
|
|
60396
|
+
content: Array.isArray(pdfJson.content) ? [...pdfJson.content] : [],
|
|
60397
|
+
styles: { ...(pdfJson.styles || {}) },
|
|
60398
|
+
defaultStyle: {
|
|
60399
|
+
...(pdfJson.defaultStyle || {}),
|
|
60400
|
+
...(defaultStyle || {})
|
|
60401
|
+
}
|
|
60402
|
+
};
|
|
60403
|
+
this.removeUnavailableFonts(pdfDefinition);
|
|
60404
|
+
this.replaceUnsupportedCurrencySymbols(pdfDefinition, boundBook, pdfDefinitionOptions);
|
|
60405
|
+
return pdfDefinition;
|
|
60406
|
+
}
|
|
60407
|
+
bindPdfQuestion(ques, dataBind) {
|
|
60408
|
+
if (!ques)
|
|
60409
|
+
return;
|
|
60410
|
+
this.normalizeBindableMetadata(ques);
|
|
60411
|
+
const questionType = (ques.type || '').toString().toLowerCase();
|
|
60412
|
+
const value = this.getBoundTemplateValue(ques.referenceTemplate || ques.bindingTemplate, dataBind)
|
|
60413
|
+
?? this.getBoundReferencePartsValue(ques.referenceParts || ques.referenceFields, dataBind)
|
|
60414
|
+
?? this.getBoundReferenceValue(ques.referenceField, ques.referenceJoiner, dataBind);
|
|
60415
|
+
const hasValue = this.hasBindableValue(value);
|
|
60416
|
+
if (questionType === 'pdf' && ques.pdfReferenceQuestions) {
|
|
60417
|
+
ques.pdfReferenceQuestions = typeof ques.pdfReferenceQuestions === 'object'
|
|
60418
|
+
? ques.pdfReferenceQuestions
|
|
60419
|
+
: this.parsePdfMakeJson(ques.pdfReferenceQuestions, {});
|
|
60420
|
+
ques.pdfReferenceQuestions?.[ques.pdfReference]?.forEach((inQues) => {
|
|
60421
|
+
this.bindPdfQuestion(inQues, dataBind);
|
|
60422
|
+
});
|
|
60423
|
+
return;
|
|
60424
|
+
}
|
|
60425
|
+
if (questionType === 'table') {
|
|
60426
|
+
const rows = hasValue ? this.getBoundTableRows(value) : this.getBoundTableRows(ques.value);
|
|
60427
|
+
const summaryValues = this.buildTableSummaryValues(ques, rows, dataBind);
|
|
60428
|
+
if (hasValue || Object.keys(summaryValues).length > 0) {
|
|
60429
|
+
ques.value = Object.keys(summaryValues).length > 0
|
|
60430
|
+
? { data: rows, summaryValues, summaryValue: summaryValues }
|
|
60431
|
+
: { data: rows };
|
|
60432
|
+
}
|
|
60433
|
+
return;
|
|
60434
|
+
}
|
|
60435
|
+
if (hasValue) {
|
|
60436
|
+
if (['dropdown', 'multiselect', 'radio'].includes(questionType)) {
|
|
60437
|
+
ques.value = value;
|
|
60438
|
+
ques.selectedValue = value;
|
|
60439
|
+
}
|
|
60440
|
+
else if (questionType === 'date' || questionType === 'datetime') {
|
|
60441
|
+
const dateValue = new Date(value?.toString());
|
|
60442
|
+
ques.value = Number.isNaN(dateValue.getTime()) ? value : dateValue;
|
|
60443
|
+
}
|
|
60444
|
+
else if (questionType === 'location') {
|
|
60445
|
+
ques.value = value?.['address'] ? value['address'] : value;
|
|
60446
|
+
}
|
|
60447
|
+
else if (questionType === 'boolean') {
|
|
60448
|
+
ques.value = value === true || value === 'true';
|
|
60449
|
+
}
|
|
60450
|
+
else if (questionType === 'image') {
|
|
60451
|
+
ques.imageData = value || ques.imageData;
|
|
60452
|
+
}
|
|
60453
|
+
else {
|
|
60454
|
+
ques.value = value;
|
|
60455
|
+
}
|
|
60456
|
+
return;
|
|
60457
|
+
}
|
|
60458
|
+
if (questionType === 'boolean') {
|
|
60459
|
+
ques.value = typeof ques.value !== 'undefined' ? ques.value === true || ques.value === 'true' : false;
|
|
60460
|
+
}
|
|
60461
|
+
else {
|
|
60462
|
+
ques.value = ques.value || null;
|
|
60463
|
+
}
|
|
60464
|
+
}
|
|
60465
|
+
normalizeBindableMetadata(ques) {
|
|
60466
|
+
if (ques.subText && typeof ques.subText === 'string') {
|
|
60467
|
+
ques.subText = this.parsePdfMakeJson(ques.subText, {});
|
|
60468
|
+
}
|
|
60469
|
+
if (Array.isArray(ques.fieldsMeta)) {
|
|
60470
|
+
ques.fieldsMeta.forEach((field) => {
|
|
60471
|
+
if (field?.subText && typeof field.subText === 'string') {
|
|
60472
|
+
field.subText = this.parsePdfMakeJson(field.subText, {});
|
|
60473
|
+
}
|
|
60474
|
+
});
|
|
60475
|
+
}
|
|
60476
|
+
}
|
|
60477
|
+
getBoundReferenceValue(referenceField, referenceJoiner = ' ', dataBind) {
|
|
60478
|
+
if (!referenceField)
|
|
60479
|
+
return undefined;
|
|
60480
|
+
if (Array.isArray(referenceField)) {
|
|
60481
|
+
return referenceField
|
|
60482
|
+
.map((fieldPath) => this.dataService.getValue(dataBind, fieldPath))
|
|
60483
|
+
.filter(value => this.hasBindableValue(value))
|
|
60484
|
+
.join(referenceJoiner || ' ');
|
|
60485
|
+
}
|
|
60486
|
+
return this.dataService.getValue(dataBind, referenceField);
|
|
60487
|
+
}
|
|
60488
|
+
getBoundReferencePartsValue(referenceParts, dataBind) {
|
|
60489
|
+
if (!Array.isArray(referenceParts) || referenceParts.length === 0)
|
|
60490
|
+
return undefined;
|
|
60491
|
+
let output = '';
|
|
60492
|
+
referenceParts.forEach((part) => {
|
|
60493
|
+
if (typeof part === 'string') {
|
|
60494
|
+
const value = this.dataService.getValue(dataBind, part);
|
|
60495
|
+
if (this.hasBindableValue(value)) {
|
|
60496
|
+
output += String(value);
|
|
60497
|
+
}
|
|
60498
|
+
return;
|
|
60499
|
+
}
|
|
60500
|
+
if (part?.text !== undefined) {
|
|
60501
|
+
output += String(part.text);
|
|
60502
|
+
return;
|
|
60503
|
+
}
|
|
60504
|
+
const fieldPath = part?.field || part?.referenceField || part?.path;
|
|
60505
|
+
const value = this.getBoundReferenceValue(fieldPath, part?.referenceJoiner, dataBind);
|
|
60506
|
+
if (!this.hasBindableValue(value)) {
|
|
60507
|
+
if (part?.fallback !== undefined) {
|
|
60508
|
+
output += `${part.prefix || ''}${part.fallback}${part.suffix || part.after || ''}`;
|
|
60509
|
+
}
|
|
60510
|
+
return;
|
|
60511
|
+
}
|
|
60512
|
+
output += `${part.prefix || ''}${value}${part.suffix || part.after || ''}`;
|
|
60513
|
+
});
|
|
60514
|
+
return output
|
|
60515
|
+
.replace(/[ \t]+\n/g, '\n')
|
|
60516
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
60517
|
+
.trim();
|
|
60518
|
+
}
|
|
60519
|
+
getBoundTemplateValue(template, dataBind) {
|
|
60520
|
+
if (!template || typeof template !== 'string')
|
|
60521
|
+
return undefined;
|
|
60522
|
+
return template.replace(/\{\{\s*([^}|]+?)(?:\s*\|\s*([^}]+?))?\s*\}\}/g, (_match, fieldPath, pipeName) => {
|
|
60523
|
+
const value = this.dataService.getValue(dataBind, fieldPath.trim());
|
|
60524
|
+
if (!this.hasBindableValue(value))
|
|
60525
|
+
return '';
|
|
60526
|
+
if ((pipeName || '').trim().toLowerCase() === 'date') {
|
|
60527
|
+
return this.formatBoundDateValue(value);
|
|
60528
|
+
}
|
|
60529
|
+
return String(value);
|
|
60530
|
+
});
|
|
60531
|
+
}
|
|
60532
|
+
formatBoundDateValue(value) {
|
|
60533
|
+
const dateValue = new Date(value);
|
|
60534
|
+
if (Number.isNaN(dateValue.getTime()))
|
|
60535
|
+
return String(value);
|
|
60536
|
+
return dateValue.toLocaleDateString('en-GB');
|
|
60537
|
+
}
|
|
60538
|
+
hasBindableValue(value) {
|
|
60539
|
+
if (value === undefined || value === null)
|
|
60540
|
+
return false;
|
|
60541
|
+
if (typeof value === 'string')
|
|
60542
|
+
return value.length > 0;
|
|
60543
|
+
if (Array.isArray(value))
|
|
60544
|
+
return value.length > 0;
|
|
60545
|
+
return true;
|
|
60546
|
+
}
|
|
60547
|
+
getBoundTableRows(value) {
|
|
60548
|
+
if (Array.isArray(value))
|
|
60549
|
+
return value;
|
|
60550
|
+
if (Array.isArray(value?.data))
|
|
60551
|
+
return value.data;
|
|
60552
|
+
return [];
|
|
60553
|
+
}
|
|
60554
|
+
buildTableSummaryValues(ques, rows, dataBind) {
|
|
60555
|
+
const summaryValues = {};
|
|
60556
|
+
const refs = ques.summaryValuesReferenceField;
|
|
60557
|
+
const setSummaryValue = (apiName, referenceField) => {
|
|
60558
|
+
if (!apiName || !referenceField)
|
|
60559
|
+
return;
|
|
60560
|
+
const value = this.dataService.getValue(dataBind, referenceField);
|
|
60561
|
+
if (this.hasBindableValue(value)) {
|
|
60562
|
+
summaryValues[apiName] = value;
|
|
60563
|
+
}
|
|
60564
|
+
};
|
|
60565
|
+
if (Array.isArray(refs)) {
|
|
60566
|
+
refs.forEach((ref) => {
|
|
60567
|
+
if (typeof ref === 'string') {
|
|
60568
|
+
setSummaryValue(ref, ref);
|
|
60569
|
+
}
|
|
60570
|
+
else if (ref && typeof ref === 'object') {
|
|
60571
|
+
setSummaryValue(ref.apiName || ref.name || ref.key, ref.referenceField || ref.field || ref.path);
|
|
60572
|
+
}
|
|
60573
|
+
});
|
|
60574
|
+
}
|
|
60575
|
+
else if (typeof refs === 'string') {
|
|
60576
|
+
setSummaryValue(refs, refs);
|
|
60577
|
+
}
|
|
60578
|
+
else if (refs && typeof refs === 'object') {
|
|
60579
|
+
Object.keys(refs).forEach(apiName => setSummaryValue(apiName, refs[apiName]));
|
|
60580
|
+
}
|
|
60581
|
+
(ques.fieldsMeta || [])
|
|
60582
|
+
.filter((column) => column?.summaryRow && column?.apiName && !this.hasBindableValue(summaryValues[column.apiName]))
|
|
60583
|
+
.forEach((column) => {
|
|
60584
|
+
const computedValue = this.computeTableSummaryValue(column, rows, summaryValues, dataBind);
|
|
60585
|
+
if (this.hasBindableValue(computedValue)) {
|
|
60586
|
+
summaryValues[column.apiName] = computedValue;
|
|
60587
|
+
}
|
|
60588
|
+
});
|
|
60589
|
+
return summaryValues;
|
|
60590
|
+
}
|
|
60591
|
+
computeTableSummaryValue(column, rows, summaryValues, dataBind) {
|
|
60592
|
+
const operation = (column?.operation || '').toString().toLowerCase();
|
|
60593
|
+
if (operation === 'sum' && column?.column) {
|
|
60594
|
+
return rows.reduce((total, row) => total + this.toNumericValue(this.dataService.getValue(row, column.column)), 0);
|
|
60595
|
+
}
|
|
60596
|
+
if (operation === 'subtract' && Array.isArray(column?.operands) && column.operands.length > 0) {
|
|
60597
|
+
const [first, ...rest] = column.operands.map((operand) => this.resolveSummaryOperand(operand, rows, summaryValues, dataBind));
|
|
60598
|
+
return rest.reduce((total, value) => total - value, first);
|
|
60599
|
+
}
|
|
60600
|
+
return undefined;
|
|
60601
|
+
}
|
|
60602
|
+
resolveSummaryOperand(operand, rows, summaryValues, dataBind) {
|
|
60603
|
+
if (this.hasBindableValue(summaryValues?.[operand])) {
|
|
60604
|
+
return this.toNumericValue(summaryValues[operand]);
|
|
60605
|
+
}
|
|
60606
|
+
const rootValue = this.dataService.getValue(dataBind, operand);
|
|
60607
|
+
if (this.hasBindableValue(rootValue)) {
|
|
60608
|
+
return this.toNumericValue(rootValue);
|
|
60609
|
+
}
|
|
60610
|
+
return rows.reduce((total, row) => total + this.toNumericValue(this.dataService.getValue(row, operand)), 0);
|
|
60611
|
+
}
|
|
60612
|
+
toNumericValue(value) {
|
|
60613
|
+
if (typeof value === 'number')
|
|
60614
|
+
return Number.isFinite(value) ? value : 0;
|
|
60615
|
+
const numericValue = Number(String(value ?? '').replace(/[^0-9.-]/g, ''));
|
|
60616
|
+
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
60617
|
+
}
|
|
60618
|
+
getPdfUniqueId(pdfJSON) {
|
|
60619
|
+
return Object.keys(pdfJSON || {}).find(key => Array.isArray(pdfJSON[key])) || this.unique_id || this.addElementWithId();
|
|
60620
|
+
}
|
|
60621
|
+
clonePlain(value) {
|
|
60622
|
+
return JSON.parse(JSON.stringify(value ?? null));
|
|
60623
|
+
}
|
|
60624
|
+
buildPdfBook(pdf = this.pdf, elements = this.pdfElements) {
|
|
60625
|
+
const originalUniqueId = this.unique_id;
|
|
60626
|
+
const sourcePdf = pdf || this.pdf;
|
|
60627
|
+
const clonedPdf = JSON.parse(JSON.stringify(sourcePdf || {}));
|
|
60628
|
+
const uniqueId = Object.keys(clonedPdf).find(key => Array.isArray(clonedPdf[key])) || originalUniqueId || this.addElementWithId();
|
|
60629
|
+
this.unique_id = uniqueId;
|
|
60630
|
+
this.ensurePdfSettings(clonedPdf);
|
|
60631
|
+
const clonedElements = JSON.parse(JSON.stringify(elements || []));
|
|
60632
|
+
clonedElements.forEach(element => {
|
|
60288
60633
|
if (element.subText && typeof element.subText === 'object') {
|
|
60289
60634
|
element.subText = element.subText;
|
|
60290
60635
|
}
|
|
60291
60636
|
});
|
|
60292
|
-
|
|
60293
|
-
|
|
60637
|
+
clonedPdf[uniqueId] = clonedElements;
|
|
60638
|
+
clonedPdf['pdfJson'] = this.convertToPdfLayout(clonedPdf);
|
|
60294
60639
|
// Scale widths for columns
|
|
60295
|
-
|
|
60640
|
+
clonedPdf?.pdfJson?.content?.forEach((row) => {
|
|
60296
60641
|
let canvasX = 0;
|
|
60297
60642
|
let canvasY = 0;
|
|
60298
60643
|
if (row?.table?.body && Array.isArray(row.table.body)) {
|
|
@@ -60339,25 +60684,144 @@ class PdfDesignerService {
|
|
|
60339
60684
|
if (typeof col.width === 'number' && col.width < 520) {
|
|
60340
60685
|
col.width = col.width * 5.2;
|
|
60341
60686
|
canvasY = col.image ? col.fit[1] : 0;
|
|
60342
|
-
backgroundCanvas.push({
|
|
60343
|
-
type: "rect",
|
|
60344
|
-
x: canvasX,
|
|
60345
|
-
y: col.image ? col.fit[1] : 0,
|
|
60346
|
-
w: col.width,
|
|
60347
|
-
h: col.image ? col.fit[1] : 140,
|
|
60348
|
-
color: "#ffffff",
|
|
60349
|
-
id: col.style
|
|
60350
|
-
});
|
|
60351
60687
|
canvasX = col.width;
|
|
60352
60688
|
}
|
|
60353
60689
|
});
|
|
60354
60690
|
}
|
|
60355
60691
|
});
|
|
60356
|
-
this.
|
|
60357
|
-
|
|
60692
|
+
this.applyPdfPageSettings(clonedPdf.pdfJson, clonedPdf);
|
|
60693
|
+
this.unique_id = originalUniqueId || uniqueId;
|
|
60694
|
+
return clonedPdf;
|
|
60695
|
+
}
|
|
60696
|
+
applyPdfPageSettings(pdfJson, sourcePdf = this.pdf) {
|
|
60697
|
+
if (!pdfJson)
|
|
60698
|
+
return;
|
|
60699
|
+
const settings = this.ensurePdfSettings(sourcePdf);
|
|
60700
|
+
pdfJson.pageSize = settings.pageSize || 'A4';
|
|
60701
|
+
pdfJson.pageOrientation = settings.pageOrientation || 'portrait';
|
|
60702
|
+
pdfJson.pageMargins = this.normalizeMargin(settings.pageMargins || [40, 40, 40, 80]);
|
|
60703
|
+
const backgroundColor = settings.backgroundColor || '#ffffff';
|
|
60704
|
+
pdfJson.background = (_currentPage, pageSize) => ({
|
|
60705
|
+
canvas: [{
|
|
60706
|
+
type: 'rect',
|
|
60707
|
+
x: 0,
|
|
60708
|
+
y: 0,
|
|
60709
|
+
w: pageSize.width,
|
|
60710
|
+
h: pageSize.height,
|
|
60711
|
+
color: backgroundColor
|
|
60712
|
+
}]
|
|
60713
|
+
});
|
|
60714
|
+
if (settings.watermark?.enabled && settings.watermark?.text) {
|
|
60715
|
+
pdfJson.watermark = {
|
|
60716
|
+
text: settings.watermark.text,
|
|
60717
|
+
color: settings.watermark.color || '#9ca3af',
|
|
60718
|
+
opacity: Number(settings.watermark.opacity ?? 0.16),
|
|
60719
|
+
angle: Number(settings.watermark.angle ?? -32),
|
|
60720
|
+
fontSize: Number(settings.watermark.fontSize ?? 64)
|
|
60721
|
+
};
|
|
60722
|
+
}
|
|
60723
|
+
else if (pdfJson.watermark) {
|
|
60724
|
+
delete pdfJson.watermark;
|
|
60725
|
+
}
|
|
60726
|
+
if (settings.header?.enabled && this.hasRunningBandContent(settings.header)) {
|
|
60727
|
+
pdfJson.header = (currentPage, pageCount, pageSize) => {
|
|
60728
|
+
if (settings.header.showOn === 'first' && currentPage !== 1) {
|
|
60729
|
+
return '';
|
|
60730
|
+
}
|
|
60731
|
+
if (settings.header.showOn === 'notFirst' && currentPage === 1) {
|
|
60732
|
+
return '';
|
|
60733
|
+
}
|
|
60734
|
+
if (settings.header.content) {
|
|
60735
|
+
return settings.header.content;
|
|
60736
|
+
}
|
|
60737
|
+
return this.buildRunningBand(settings.header, currentPage, pageCount, pageSize, 'header');
|
|
60738
|
+
};
|
|
60739
|
+
}
|
|
60740
|
+
else if (pdfJson.header) {
|
|
60741
|
+
delete pdfJson.header;
|
|
60742
|
+
}
|
|
60743
|
+
if (settings.footer?.enabled && this.hasRunningBandContent(settings.footer)) {
|
|
60744
|
+
pdfJson.footer = (currentPage, pageCount, pageSize) => {
|
|
60745
|
+
if (settings.footer.showOn === 'last' && currentPage !== pageCount) {
|
|
60746
|
+
return '';
|
|
60747
|
+
}
|
|
60748
|
+
if (settings.footer.content) {
|
|
60749
|
+
return settings.footer.content;
|
|
60750
|
+
}
|
|
60751
|
+
return this.buildRunningBand(settings.footer, currentPage, pageCount, pageSize, 'footer');
|
|
60752
|
+
};
|
|
60753
|
+
}
|
|
60754
|
+
else if (pdfJson.footer) {
|
|
60755
|
+
delete pdfJson.footer;
|
|
60756
|
+
}
|
|
60757
|
+
}
|
|
60758
|
+
hasRunningBandContent(settings) {
|
|
60759
|
+
return !!(settings?.content || settings?.text || settings?.leftText || settings?.centerText || settings?.rightText);
|
|
60760
|
+
}
|
|
60761
|
+
buildRunningBand(settings, currentPage, pageCount, pageSize, placement) {
|
|
60762
|
+
const margin = this.normalizeMargin(settings.margin || [40, 12, 40, 0]);
|
|
60763
|
+
const lineWidth = Math.max((pageSize?.width || 595) - margin[0] - margin[2], 0);
|
|
60764
|
+
const stack = [];
|
|
60765
|
+
if (placement === 'footer' && settings.topBorder) {
|
|
60766
|
+
stack.push({
|
|
60767
|
+
canvas: [{
|
|
60768
|
+
type: 'line',
|
|
60769
|
+
x1: 0,
|
|
60770
|
+
y1: 0,
|
|
60771
|
+
x2: lineWidth,
|
|
60772
|
+
y2: 0,
|
|
60773
|
+
lineWidth: Number(settings.borderWidth ?? 1),
|
|
60774
|
+
lineColor: settings.borderColor || '#2f9e44'
|
|
60775
|
+
}],
|
|
60776
|
+
margin: [0, 0, 0, 8]
|
|
60777
|
+
});
|
|
60778
|
+
}
|
|
60779
|
+
const leftText = this.replacePageTokens(settings.leftText || settings.text || '', currentPage, pageCount);
|
|
60780
|
+
const centerText = this.replacePageTokens(settings.centerText || '', currentPage, pageCount);
|
|
60781
|
+
const rightText = this.replacePageTokens(settings.rightText || '', currentPage, pageCount);
|
|
60782
|
+
if (settings.leftText || settings.centerText || settings.rightText) {
|
|
60783
|
+
stack.push({
|
|
60784
|
+
columns: [
|
|
60785
|
+
{ width: '*', text: leftText, alignment: 'left' },
|
|
60786
|
+
{ width: '*', text: centerText, alignment: 'center' },
|
|
60787
|
+
{ width: '*', text: rightText, alignment: 'right' }
|
|
60788
|
+
],
|
|
60789
|
+
columnGap: 12,
|
|
60790
|
+
fontSize: Number(settings.fontSize ?? 9),
|
|
60791
|
+
color: settings.color || '#666666'
|
|
60792
|
+
});
|
|
60793
|
+
}
|
|
60794
|
+
else {
|
|
60795
|
+
stack.push({
|
|
60796
|
+
text: this.replacePageTokens(settings.text || '', currentPage, pageCount),
|
|
60797
|
+
alignment: settings.alignment || 'center',
|
|
60798
|
+
fontSize: Number(settings.fontSize ?? 9),
|
|
60799
|
+
color: settings.color || '#666666'
|
|
60800
|
+
});
|
|
60801
|
+
}
|
|
60802
|
+
if (placement === 'header' && settings.bottomBorder) {
|
|
60803
|
+
stack.push({
|
|
60804
|
+
canvas: [{
|
|
60805
|
+
type: 'line',
|
|
60806
|
+
x1: 0,
|
|
60807
|
+
y1: 0,
|
|
60808
|
+
x2: lineWidth,
|
|
60809
|
+
y2: 0,
|
|
60810
|
+
lineWidth: Number(settings.borderWidth ?? 1),
|
|
60811
|
+
lineColor: settings.borderColor || '#2f9e44'
|
|
60812
|
+
}],
|
|
60813
|
+
margin: [0, 8, 0, 0]
|
|
60814
|
+
});
|
|
60815
|
+
}
|
|
60816
|
+
return { margin, stack };
|
|
60817
|
+
}
|
|
60818
|
+
replacePageTokens(text, currentPage, pageCount) {
|
|
60819
|
+
return String(text || '')
|
|
60820
|
+
.replace(/\{\{\s*currentPage\s*\}\}/g, String(currentPage))
|
|
60821
|
+
.replace(/\{\{\s*pageCount\s*\}\}/g, String(pageCount));
|
|
60358
60822
|
}
|
|
60359
60823
|
convertToPdfLayout(input) {
|
|
60360
|
-
this.currencyOption = this.
|
|
60824
|
+
this.currencyOption = this.resolveCurrencyOption(input);
|
|
60361
60825
|
const result = { content: [] };
|
|
60362
60826
|
const items = JSON.parse(JSON.stringify(input[this.unique_id]));
|
|
60363
60827
|
const processItems = (items, from, fromWidth) => {
|
|
@@ -60429,6 +60893,32 @@ class PdfDesignerService {
|
|
|
60429
60893
|
if (item.type === 'date') {
|
|
60430
60894
|
item.value = this.dateTransform(item.value, 'date', 'en', 'gregorian');
|
|
60431
60895
|
}
|
|
60896
|
+
if (item.type === 'PageBreak' && item.hideInPdf !== true) {
|
|
60897
|
+
if (currentRow.columns.length > 0) {
|
|
60898
|
+
const arrayCheck = currentRow.columns.some(col => Array.isArray(col) && col.some(col2 => Array.isArray(col2.columns)));
|
|
60899
|
+
rows.push(arrayCheck ? { 'table': { 'body': [currentRow.columns] }, layout: 'noBorders' } : currentRow);
|
|
60900
|
+
currentRow = { columns: [] };
|
|
60901
|
+
currentWidth = 0;
|
|
60902
|
+
}
|
|
60903
|
+
rows.push({ text: '', pageBreak: item.pageBreak || 'after' });
|
|
60904
|
+
continue;
|
|
60905
|
+
}
|
|
60906
|
+
if (item.type === 'PdfMake' && item.hideInPdf !== true) {
|
|
60907
|
+
if (currentRow.columns.length > 0) {
|
|
60908
|
+
const arrayCheck = currentRow.columns.some(col => Array.isArray(col) && col.some(col2 => Array.isArray(col2.columns)));
|
|
60909
|
+
rows.push(arrayCheck ? { 'table': { 'body': [currentRow.columns] }, layout: 'noBorders' } : currentRow);
|
|
60910
|
+
currentRow = { columns: [] };
|
|
60911
|
+
currentWidth = 0;
|
|
60912
|
+
}
|
|
60913
|
+
const rawContent = this.parsePdfMakeJson(item.pdfMakeContent || item.value, null);
|
|
60914
|
+
if (Array.isArray(rawContent)) {
|
|
60915
|
+
rows.push(...rawContent);
|
|
60916
|
+
}
|
|
60917
|
+
else if (rawContent) {
|
|
60918
|
+
rows.push(rawContent);
|
|
60919
|
+
}
|
|
60920
|
+
continue;
|
|
60921
|
+
}
|
|
60432
60922
|
if (item.type === "Space" || item.hideInPdf === true) {
|
|
60433
60923
|
currentRow.columns.push({ width: fromWidth || width, text: '' });
|
|
60434
60924
|
}
|
|
@@ -60446,6 +60936,54 @@ class PdfDesignerService {
|
|
|
60446
60936
|
];
|
|
60447
60937
|
currentRow.columns.push(element);
|
|
60448
60938
|
}
|
|
60939
|
+
else if (item.type === 'Section') {
|
|
60940
|
+
element = {
|
|
60941
|
+
width: fromWidth || width,
|
|
60942
|
+
table: {
|
|
60943
|
+
widths: ['*'],
|
|
60944
|
+
body: [[{
|
|
60945
|
+
text: item.value || item.questionText || 'Section',
|
|
60946
|
+
style: item.styleClass,
|
|
60947
|
+
fillColor: item.style?.fillColor || item.style?.backgroundColor || '#2f9e44',
|
|
60948
|
+
border: [false, false, false, false],
|
|
60949
|
+
margin: this.normalizeMargin(item.innerMargin || [8, 6, 8, 6])
|
|
60950
|
+
}]]
|
|
60951
|
+
},
|
|
60952
|
+
layout: 'noBorders',
|
|
60953
|
+
margin: this.normalizeMargin(item.style?.margin || [0, 8, 0, 0])
|
|
60954
|
+
};
|
|
60955
|
+
currentRow.columns.push(element);
|
|
60956
|
+
}
|
|
60957
|
+
else if (item.type === 'Note') {
|
|
60958
|
+
element = {
|
|
60959
|
+
width: fromWidth || width,
|
|
60960
|
+
table: {
|
|
60961
|
+
widths: ['*'],
|
|
60962
|
+
body: [[{
|
|
60963
|
+
text: item.value || '',
|
|
60964
|
+
style: item.styleClass,
|
|
60965
|
+
fillColor: item.style?.fillColor || item.style?.backgroundColor || '#e7f2e8',
|
|
60966
|
+
borderColor: item.style?.borderColor || '#2f9e44',
|
|
60967
|
+
margin: this.normalizeMargin(item.innerMargin || [8, 6, 8, 6])
|
|
60968
|
+
}]]
|
|
60969
|
+
},
|
|
60970
|
+
layout: {
|
|
60971
|
+
hLineColor: () => item.style?.borderColor || '#2f9e44',
|
|
60972
|
+
vLineColor: () => item.style?.borderColor || '#2f9e44'
|
|
60973
|
+
},
|
|
60974
|
+
margin: this.normalizeMargin(item.style?.margin || [0, 8, 0, 8])
|
|
60975
|
+
};
|
|
60976
|
+
currentRow.columns.push(element);
|
|
60977
|
+
}
|
|
60978
|
+
else if (item.type === 'RichText') {
|
|
60979
|
+
element = {
|
|
60980
|
+
width: fromWidth || width,
|
|
60981
|
+
stack: this.buildRichTextStack(item),
|
|
60982
|
+
style: item.styleClass,
|
|
60983
|
+
margin: this.normalizeMargin(item.style?.margin || [0, 6, 0, 6])
|
|
60984
|
+
};
|
|
60985
|
+
currentRow.columns.push(element);
|
|
60986
|
+
}
|
|
60449
60987
|
else if (item.type === "Pdf" && item.pdfReferenceQuestions) {
|
|
60450
60988
|
const nestedQuestions = item.pdfReferenceQuestions[item.pdfReference];
|
|
60451
60989
|
const nestedContent = processItems(nestedQuestions, 'pdf', item.width); // recursive processing
|
|
@@ -60471,47 +61009,59 @@ class PdfDesignerService {
|
|
|
60471
61009
|
text: col.label, style: col.uniqueIdentifier
|
|
60472
61010
|
})));
|
|
60473
61011
|
// Table data
|
|
60474
|
-
item?.
|
|
61012
|
+
const dataRows = item.tableConfig?.hideEmptyRows === false
|
|
61013
|
+
? (item?.value?.data || [])
|
|
61014
|
+
: (item?.value?.data || []).filter((tableData) => !this.isEmptyTableDataRow(tableData, mainColumns));
|
|
61015
|
+
dataRows.forEach?.(tableData => {
|
|
60475
61016
|
body?.push(mainColumns?.map((col) => {
|
|
60476
61017
|
if (col.fldType === 'currency') {
|
|
61018
|
+
const cellValue = this.dataService.getValue(tableData, col.apiName);
|
|
60477
61019
|
return {
|
|
60478
|
-
text: this.
|
|
60479
|
-
fontSize: 12,
|
|
61020
|
+
text: this.formatCurrencyText(cellValue, col),
|
|
61021
|
+
fontSize: Number(col.style?.fontSize) || 12,
|
|
60480
61022
|
nowrap: false,
|
|
60481
|
-
alignment: 'right',
|
|
61023
|
+
alignment: col.style?.alignment || 'right',
|
|
60482
61024
|
style: col.uniqueIdentifier + 'column'
|
|
60483
61025
|
};
|
|
60484
61026
|
}
|
|
60485
61027
|
else {
|
|
60486
61028
|
return {
|
|
60487
61029
|
text: this.dataService.getValue(tableData, col.apiName) || '',
|
|
60488
|
-
fontSize: 12,
|
|
61030
|
+
fontSize: Number(col.style?.fontSize) || 12,
|
|
60489
61031
|
nowrap: false,
|
|
61032
|
+
alignment: col.style?.alignment || undefined,
|
|
60490
61033
|
style: col.uniqueIdentifier + 'column'
|
|
60491
61034
|
};
|
|
60492
61035
|
}
|
|
60493
61036
|
}));
|
|
60494
61037
|
});
|
|
60495
61038
|
// Summary rows
|
|
61039
|
+
const summaryValues = item?.value?.summaryValues || item?.value?.summaryValue || {};
|
|
60496
61040
|
summaryRow.forEach((col) => {
|
|
60497
61041
|
//AP-14JUN25 - Create an empty row with same number of columns as main table, filled with blank cells (no borders)
|
|
60498
61042
|
const row = new Array(mainColumns.length).fill({ text: '', "border": [false, false, false, false] });
|
|
60499
61043
|
//AP-14JUN25 - Set the label text at the left summary position with bottom-side border
|
|
60500
|
-
|
|
60501
|
-
|
|
61044
|
+
const valueIndex = Math.min(Math.max(summaryRowPosition, 1), Math.max(mainColumns.length - 1, 0));
|
|
61045
|
+
const labelIndex = Math.max(valueIndex - 1, 0);
|
|
61046
|
+
row[labelIndex] = { text: col.label, "border": [false, false, false, false], style: col.uniqueIdentifier };
|
|
61047
|
+
const summaryValue = this.dataService.getValue(summaryValues, col.apiName);
|
|
61048
|
+
row[valueIndex] = { text: col.fldType === 'currency' ? this.formatCurrencyText(summaryValue, col) : summaryValue ?? '', "border": [false, false, false, false], style: col.uniqueIdentifier };
|
|
60502
61049
|
body.push(row);
|
|
60503
61050
|
});
|
|
60504
61051
|
// table column widths
|
|
60505
61052
|
let tableColumnWidths = [];
|
|
60506
61053
|
mainColumns.forEach((mCol) => {
|
|
60507
|
-
|
|
61054
|
+
const columnWidth = mCol.style?.width;
|
|
61055
|
+
tableColumnWidths.push(typeof columnWidth === 'number' ? columnWidth : columnWidth || '*');
|
|
60508
61056
|
});
|
|
60509
61057
|
element = {
|
|
60510
61058
|
width: item.width || 520,
|
|
60511
61059
|
table: {
|
|
60512
61060
|
body,
|
|
60513
|
-
widths: tableColumnWidths
|
|
61061
|
+
widths: tableColumnWidths,
|
|
61062
|
+
dontBreakRows: item.tableConfig?.dontBreakRows === true
|
|
60514
61063
|
},
|
|
61064
|
+
layout: this.buildTableLayout(item.tableLayout)
|
|
60515
61065
|
};
|
|
60516
61066
|
currentRow.columns.push(element);
|
|
60517
61067
|
// AP-24JUNE 25 - Adjust image width to compensate for external *5.2 scaling
|
|
@@ -60562,7 +61112,7 @@ class PdfDesignerService {
|
|
|
60562
61112
|
},
|
|
60563
61113
|
{
|
|
60564
61114
|
width: fromWidth || width,
|
|
60565
|
-
text:
|
|
61115
|
+
text: this.formatCurrencyText(val, item),
|
|
60566
61116
|
style: item.styleClass
|
|
60567
61117
|
}
|
|
60568
61118
|
]
|
|
@@ -60571,12 +61121,13 @@ class PdfDesignerService {
|
|
|
60571
61121
|
else {
|
|
60572
61122
|
currentRow.columns.push({
|
|
60573
61123
|
width: fromWidth || width,
|
|
60574
|
-
text: val, style: item.styleClass,
|
|
61124
|
+
text: this.formatCurrencyText(val, item), style: item.styleClass,
|
|
60575
61125
|
});
|
|
60576
61126
|
}
|
|
60577
61127
|
}
|
|
60578
61128
|
else {
|
|
60579
61129
|
const val = item.value || '';
|
|
61130
|
+
const valueNode = this.buildTextValueNode(item, val, fromWidth || width);
|
|
60580
61131
|
if (item.showLabelInPdf === true) {
|
|
60581
61132
|
currentRow.columns.push({
|
|
60582
61133
|
width: fromWidth || width,
|
|
@@ -60588,18 +61139,12 @@ class PdfDesignerService {
|
|
|
60588
61139
|
text: item.questionText || '',
|
|
60589
61140
|
style: item.styleClass + 'label'
|
|
60590
61141
|
},
|
|
60591
|
-
|
|
60592
|
-
width: fromWidth || width,
|
|
60593
|
-
text: val, style: item.styleClass,
|
|
60594
|
-
}
|
|
61142
|
+
valueNode
|
|
60595
61143
|
]
|
|
60596
61144
|
});
|
|
60597
61145
|
}
|
|
60598
61146
|
else {
|
|
60599
|
-
currentRow.columns.push(
|
|
60600
|
-
width: fromWidth || width,
|
|
60601
|
-
text: val, style: item.styleClass,
|
|
60602
|
-
});
|
|
61147
|
+
currentRow.columns.push(valueNode);
|
|
60603
61148
|
}
|
|
60604
61149
|
}
|
|
60605
61150
|
currentWidth += width;
|
|
@@ -60629,28 +61174,42 @@ class PdfDesignerService {
|
|
|
60629
61174
|
if (field?.style?.margin) {
|
|
60630
61175
|
field.style.margin = field.style.margin.map(Number);
|
|
60631
61176
|
}
|
|
60632
|
-
styleJson[field.uniqueIdentifier] = field.style;
|
|
61177
|
+
styleJson[field.uniqueIdentifier] = this.normalizePdfStyle(field.style);
|
|
60633
61178
|
let tempStyle = field.style ? JSON.parse(JSON.stringify(field.style)) : {};
|
|
60634
61179
|
delete tempStyle.fillColor;
|
|
60635
|
-
|
|
60636
|
-
|
|
61180
|
+
if (tempStyle.cellColor) {
|
|
61181
|
+
tempStyle.color = tempStyle.cellColor;
|
|
61182
|
+
}
|
|
61183
|
+
else {
|
|
61184
|
+
delete tempStyle.color;
|
|
61185
|
+
}
|
|
61186
|
+
if (tempStyle.cellFillColor) {
|
|
61187
|
+
tempStyle.fillColor = tempStyle.cellFillColor;
|
|
61188
|
+
}
|
|
61189
|
+
styleJson[field.uniqueIdentifier + 'column'] = this.normalizePdfStyle(tempStyle);
|
|
60637
61190
|
}
|
|
60638
61191
|
}
|
|
60639
61192
|
}
|
|
61193
|
+
if (item.type === 'PdfMake') {
|
|
61194
|
+
Object.assign(styleJson, this.parsePdfMakeJson(item.pdfMakeStyles, {}));
|
|
61195
|
+
continue;
|
|
61196
|
+
}
|
|
60640
61197
|
if (item?.style?.margin) {
|
|
60641
61198
|
item.style.margin = item.style.margin.map(Number);
|
|
60642
61199
|
}
|
|
60643
61200
|
if (item.showLabelInPdf === true) {
|
|
60644
61201
|
// Deep copy so original item.style is safe
|
|
60645
61202
|
let tempStyle1 = item.style ? JSON.parse(JSON.stringify(item.style)) : {};
|
|
61203
|
+
tempStyle1.margin = this.normalizeMargin(tempStyle1.margin || [0, 0, 0, 2]);
|
|
60646
61204
|
tempStyle1.margin[3] = 2;
|
|
60647
|
-
styleJson[item.styleClass + "label"] = tempStyle1;
|
|
61205
|
+
styleJson[item.styleClass + "label"] = this.normalizePdfStyle(tempStyle1);
|
|
60648
61206
|
let tempStyle2 = item.style ? JSON.parse(JSON.stringify(item.style)) : {};
|
|
61207
|
+
tempStyle2.margin = this.normalizeMargin(tempStyle2.margin || [0, 0, 0, 0]);
|
|
60649
61208
|
tempStyle2.margin[1] = 0;
|
|
60650
|
-
styleJson[item.styleClass] = tempStyle2;
|
|
61209
|
+
styleJson[item.styleClass] = this.normalizePdfStyle(tempStyle2);
|
|
60651
61210
|
}
|
|
60652
61211
|
else {
|
|
60653
|
-
styleJson[item.styleClass] = item.style;
|
|
61212
|
+
styleJson[item.styleClass] = this.normalizePdfStyle(item.style);
|
|
60654
61213
|
}
|
|
60655
61214
|
// Recursive step for Pdf
|
|
60656
61215
|
if (item.type === "Pdf" && item.pdfReferenceQuestions) {
|
|
@@ -60670,6 +61229,258 @@ class PdfDesignerService {
|
|
|
60670
61229
|
result['styles'] = styleJson;
|
|
60671
61230
|
return result;
|
|
60672
61231
|
}
|
|
61232
|
+
buildTableLayout(tableLayout) {
|
|
61233
|
+
if (!tableLayout)
|
|
61234
|
+
return undefined;
|
|
61235
|
+
if (typeof tableLayout === 'string')
|
|
61236
|
+
return tableLayout;
|
|
61237
|
+
const hLineColor = tableLayout.hLineColor || tableLayout.lineColor || '#cfd8d1';
|
|
61238
|
+
const vLineColor = tableLayout.vLineColor || tableLayout.lineColor || '#cfd8d1';
|
|
61239
|
+
const hLineWidth = tableLayout.hLineWidth ?? tableLayout.lineWidth ?? 0.5;
|
|
61240
|
+
const vLineWidth = tableLayout.vLineWidth ?? tableLayout.lineWidth ?? 0.5;
|
|
61241
|
+
const paddingLeft = tableLayout.paddingLeft ?? tableLayout.paddingX ?? 5;
|
|
61242
|
+
const paddingRight = tableLayout.paddingRight ?? tableLayout.paddingX ?? 5;
|
|
61243
|
+
const paddingTop = tableLayout.paddingTop ?? tableLayout.paddingY ?? 4;
|
|
61244
|
+
const paddingBottom = tableLayout.paddingBottom ?? tableLayout.paddingY ?? 4;
|
|
61245
|
+
return {
|
|
61246
|
+
hLineColor: () => hLineColor,
|
|
61247
|
+
vLineColor: () => vLineColor,
|
|
61248
|
+
hLineWidth: () => Number(hLineWidth),
|
|
61249
|
+
vLineWidth: () => Number(vLineWidth),
|
|
61250
|
+
paddingLeft: () => Number(paddingLeft),
|
|
61251
|
+
paddingRight: () => Number(paddingRight),
|
|
61252
|
+
paddingTop: () => Number(paddingTop),
|
|
61253
|
+
paddingBottom: () => Number(paddingBottom)
|
|
61254
|
+
};
|
|
61255
|
+
}
|
|
61256
|
+
isEmptyTableDataRow(tableData, columns = []) {
|
|
61257
|
+
if (!tableData || typeof tableData !== 'object')
|
|
61258
|
+
return true;
|
|
61259
|
+
return !(columns || []).some((column) => {
|
|
61260
|
+
const value = this.normalizeCurrencyValue(this.dataService.getValue(tableData, column.apiName));
|
|
61261
|
+
if (!this.hasBindableValue(value))
|
|
61262
|
+
return false;
|
|
61263
|
+
if (typeof value === 'number')
|
|
61264
|
+
return value !== 0;
|
|
61265
|
+
const text = String(value).trim();
|
|
61266
|
+
if (!text)
|
|
61267
|
+
return false;
|
|
61268
|
+
if (column?.fldType === 'currency' && this.toNumericValue(text) === 0)
|
|
61269
|
+
return false;
|
|
61270
|
+
return true;
|
|
61271
|
+
});
|
|
61272
|
+
}
|
|
61273
|
+
buildRichTextStack(item) {
|
|
61274
|
+
const style = item?.style || {};
|
|
61275
|
+
const paragraphGap = Number(style.paragraphGap ?? 1);
|
|
61276
|
+
const paragraphBottom = Number(style.paragraphBottom ?? 1);
|
|
61277
|
+
const headingBottom = Number(style.headingBottom ?? 5);
|
|
61278
|
+
const bulletTop = Number(style.bulletTop ?? 2);
|
|
61279
|
+
const bulletBottom = Number(style.bulletBottom ?? 5);
|
|
61280
|
+
const lines = String(item.value || '')
|
|
61281
|
+
.split(/\r?\n/)
|
|
61282
|
+
.map(line => line.trim())
|
|
61283
|
+
.filter(Boolean);
|
|
61284
|
+
const stack = [];
|
|
61285
|
+
let bulletBuffer = [];
|
|
61286
|
+
const flushBullets = () => {
|
|
61287
|
+
if (!bulletBuffer.length)
|
|
61288
|
+
return;
|
|
61289
|
+
stack.push({
|
|
61290
|
+
ul: bulletBuffer,
|
|
61291
|
+
margin: [0, stack.length ? bulletTop : 0, 0, bulletBottom]
|
|
61292
|
+
});
|
|
61293
|
+
bulletBuffer = [];
|
|
61294
|
+
};
|
|
61295
|
+
lines.forEach((line, index) => {
|
|
61296
|
+
const bulletMatch = line.match(/^([•*-])\s*(.*)$/);
|
|
61297
|
+
if (bulletMatch) {
|
|
61298
|
+
bulletBuffer.push(bulletMatch[2]);
|
|
61299
|
+
return;
|
|
61300
|
+
}
|
|
61301
|
+
flushBullets();
|
|
61302
|
+
stack.push({
|
|
61303
|
+
text: line,
|
|
61304
|
+
bold: item.headingFirstLine !== false && index === 0,
|
|
61305
|
+
color: item.headingFirstLine !== false && index === 0 ? (item.style?.headingColor || item.style?.color || '#2f9e44') : undefined,
|
|
61306
|
+
margin: [
|
|
61307
|
+
0,
|
|
61308
|
+
stack.length ? paragraphGap : 0,
|
|
61309
|
+
0,
|
|
61310
|
+
item.headingFirstLine !== false && index === 0 ? headingBottom : paragraphBottom
|
|
61311
|
+
]
|
|
61312
|
+
});
|
|
61313
|
+
});
|
|
61314
|
+
flushBullets();
|
|
61315
|
+
return stack.length ? stack : [{ text: '' }];
|
|
61316
|
+
}
|
|
61317
|
+
buildTextValueNode(item, value, width) {
|
|
61318
|
+
if (item?.type !== 'text' || (item?.headingFirstLine !== true && !this.isQuotationHeadingText(item))) {
|
|
61319
|
+
return {
|
|
61320
|
+
width,
|
|
61321
|
+
text: value,
|
|
61322
|
+
style: item.styleClass
|
|
61323
|
+
};
|
|
61324
|
+
}
|
|
61325
|
+
return {
|
|
61326
|
+
width,
|
|
61327
|
+
stack: this.buildStyledTextStack(item, value),
|
|
61328
|
+
margin: this.normalizeMargin(item.style?.margin || [0, 0, 0, 0])
|
|
61329
|
+
};
|
|
61330
|
+
}
|
|
61331
|
+
buildStyledTextStack(item, value) {
|
|
61332
|
+
const style = item?.style || {};
|
|
61333
|
+
const bodyStyle = this.normalizePdfStyle({
|
|
61334
|
+
...style,
|
|
61335
|
+
margin: [0, 0, 0, 0]
|
|
61336
|
+
});
|
|
61337
|
+
const lines = String(value || '').split(/\r?\n/);
|
|
61338
|
+
return lines.map((line, index) => {
|
|
61339
|
+
if (index === 0 && String(line || '').trim()) {
|
|
61340
|
+
return {
|
|
61341
|
+
...bodyStyle,
|
|
61342
|
+
text: line,
|
|
61343
|
+
color: style.headingColor || this.getDefaultTextHeadingColor(item) || style.color || '#2f9e44',
|
|
61344
|
+
fontSize: Number(style.headingFontSize) || this.getDefaultTextHeadingSize(item) || Number(style.fontSize) || 12,
|
|
61345
|
+
bold: style.headingBold === undefined ? !this.isQuotationHeadingText(item) : style.headingBold !== false,
|
|
61346
|
+
margin: this.normalizeMargin(style.headingMargin || [0, 0, 0, 2])
|
|
61347
|
+
};
|
|
61348
|
+
}
|
|
61349
|
+
if (!line) {
|
|
61350
|
+
return {
|
|
61351
|
+
text: ' ',
|
|
61352
|
+
fontSize: Number(style.blankLineHeight) || 10,
|
|
61353
|
+
margin: [0, 0, 0, 0]
|
|
61354
|
+
};
|
|
61355
|
+
}
|
|
61356
|
+
return {
|
|
61357
|
+
...bodyStyle,
|
|
61358
|
+
text: line
|
|
61359
|
+
};
|
|
61360
|
+
});
|
|
61361
|
+
}
|
|
61362
|
+
isQuotationHeadingText(item) {
|
|
61363
|
+
const firstLine = String(item?.value || '').split(/\r?\n/)[0]?.trim();
|
|
61364
|
+
return firstLine === 'VALAR HR' || firstLine === 'QUOTATION';
|
|
61365
|
+
}
|
|
61366
|
+
getDefaultTextHeadingColor(item) {
|
|
61367
|
+
return this.isQuotationHeadingText(item) ? '#3fa34d' : '';
|
|
61368
|
+
}
|
|
61369
|
+
getDefaultTextHeadingSize(item) {
|
|
61370
|
+
return this.isQuotationHeadingText(item) ? 24 : 0;
|
|
61371
|
+
}
|
|
61372
|
+
parsePdfMakeJson(value, fallback) {
|
|
61373
|
+
if (!value)
|
|
61374
|
+
return fallback;
|
|
61375
|
+
if (typeof value === 'object')
|
|
61376
|
+
return value;
|
|
61377
|
+
try {
|
|
61378
|
+
return JSON.parse(value);
|
|
61379
|
+
}
|
|
61380
|
+
catch (error) {
|
|
61381
|
+
console.warn('Invalid pdfmake JSON block ignored', error);
|
|
61382
|
+
return fallback;
|
|
61383
|
+
}
|
|
61384
|
+
}
|
|
61385
|
+
formatCurrencyText(value, field) {
|
|
61386
|
+
value = this.normalizeCurrencyValue(value);
|
|
61387
|
+
if (value === undefined || value === null || value === '')
|
|
61388
|
+
return '';
|
|
61389
|
+
const symbol = this.resolveCurrencySymbol(field);
|
|
61390
|
+
return `${symbol ? symbol + ' ' : ''}${value}`;
|
|
61391
|
+
}
|
|
61392
|
+
normalizeCurrencyValue(value) {
|
|
61393
|
+
if (!value || typeof value !== 'object')
|
|
61394
|
+
return value;
|
|
61395
|
+
const scalarValue = value.value ?? value.amount ?? value.total ?? value.totalAmount ?? value.taxAmount;
|
|
61396
|
+
if (scalarValue !== undefined && scalarValue !== null && typeof scalarValue !== 'object') {
|
|
61397
|
+
return scalarValue;
|
|
61398
|
+
}
|
|
61399
|
+
if (Array.isArray(value.group)) {
|
|
61400
|
+
return value.group.reduce((total, entry) => {
|
|
61401
|
+
return total + this.toNumericValue(entry?.value ?? entry?.amount ?? entry?.taxAmount ?? entry?.total);
|
|
61402
|
+
}, 0);
|
|
61403
|
+
}
|
|
61404
|
+
return '';
|
|
61405
|
+
}
|
|
61406
|
+
resolveCurrencySymbol(field) {
|
|
61407
|
+
if (field && Object.prototype.hasOwnProperty.call(field, 'currencySymbol')) {
|
|
61408
|
+
return field.currencySymbol || '';
|
|
61409
|
+
}
|
|
61410
|
+
return this.currencyOption?.symbol || this.currencyOption?.currencySymbol || '';
|
|
61411
|
+
}
|
|
61412
|
+
resolveCurrencyOption(source) {
|
|
61413
|
+
const configuredCurrency = source?.currency || source?.pdfSettings?.currency;
|
|
61414
|
+
if (configuredCurrency?.symbol || configuredCurrency?.currencySymbol) {
|
|
61415
|
+
return {
|
|
61416
|
+
code: configuredCurrency.code || configuredCurrency.currencyCode,
|
|
61417
|
+
name: configuredCurrency.name || configuredCurrency.currencyName,
|
|
61418
|
+
symbol: configuredCurrency.symbol || configuredCurrency.currencySymbol
|
|
61419
|
+
};
|
|
61420
|
+
}
|
|
61421
|
+
const currencyCode = source?.currencyCode || source?.pdfSettings?.currencyCode || source?.customer?.currencyCode;
|
|
61422
|
+
if (currencyCode) {
|
|
61423
|
+
const currencyOption = this.countryService.getCountryData(['currencies'])?.find((option) => option.code === currencyCode);
|
|
61424
|
+
if (currencyOption)
|
|
61425
|
+
return currencyOption;
|
|
61426
|
+
}
|
|
61427
|
+
return this.countryService.getCurrentCurrency();
|
|
61428
|
+
}
|
|
61429
|
+
removeUnavailableFonts(pdfDefinition) {
|
|
61430
|
+
const availableFonts = new Set([
|
|
61431
|
+
...Object.keys(pdfDefinition?.fonts || {}),
|
|
61432
|
+
...(pdfDefinition?.defaultStyle?.font ? [pdfDefinition.defaultStyle.font] : [])
|
|
61433
|
+
]);
|
|
61434
|
+
if (availableFonts.size === 0)
|
|
61435
|
+
return;
|
|
61436
|
+
const sanitize = (node) => {
|
|
61437
|
+
if (!node || typeof node !== 'object')
|
|
61438
|
+
return;
|
|
61439
|
+
if (Array.isArray(node)) {
|
|
61440
|
+
node.forEach(sanitize);
|
|
61441
|
+
return;
|
|
61442
|
+
}
|
|
61443
|
+
if (node.font && !availableFonts.has(node.font)) {
|
|
61444
|
+
delete node.font;
|
|
61445
|
+
}
|
|
61446
|
+
Object.keys(node).forEach(key => {
|
|
61447
|
+
if (typeof node[key] !== 'function') {
|
|
61448
|
+
sanitize(node[key]);
|
|
61449
|
+
}
|
|
61450
|
+
});
|
|
61451
|
+
};
|
|
61452
|
+
sanitize(pdfDefinition.styles);
|
|
61453
|
+
sanitize(pdfDefinition.content);
|
|
61454
|
+
}
|
|
61455
|
+
replaceUnsupportedCurrencySymbols(pdfDefinition, boundBook, pdfDefinitionOptions = {}) {
|
|
61456
|
+
if (pdfDefinitionOptions?.preserveCurrencySymbol === true)
|
|
61457
|
+
return;
|
|
61458
|
+
const defaultFont = pdfDefinition?.defaultStyle?.font;
|
|
61459
|
+
const shouldReplaceRupee = defaultFont === 'Amiri';
|
|
61460
|
+
if (!shouldReplaceRupee)
|
|
61461
|
+
return;
|
|
61462
|
+
const replacement = pdfDefinitionOptions?.currencySymbolFallback
|
|
61463
|
+
|| boundBook?.currency?.code
|
|
61464
|
+
|| boundBook?.currencyCode
|
|
61465
|
+
|| 'INR';
|
|
61466
|
+
const sanitize = (node) => {
|
|
61467
|
+
if (!node || typeof node !== 'object')
|
|
61468
|
+
return;
|
|
61469
|
+
if (Array.isArray(node)) {
|
|
61470
|
+
node.forEach(sanitize);
|
|
61471
|
+
return;
|
|
61472
|
+
}
|
|
61473
|
+
if (typeof node.text === 'string') {
|
|
61474
|
+
node.text = node.text.replace(/₹/g, replacement);
|
|
61475
|
+
}
|
|
61476
|
+
Object.keys(node).forEach(key => {
|
|
61477
|
+
if (typeof node[key] !== 'function') {
|
|
61478
|
+
sanitize(node[key]);
|
|
61479
|
+
}
|
|
61480
|
+
});
|
|
61481
|
+
};
|
|
61482
|
+
sanitize(pdfDefinition.content);
|
|
61483
|
+
}
|
|
60673
61484
|
// AP-06MAR25 - Element new order update
|
|
60674
61485
|
updateElementsOrder(updatedElements) {
|
|
60675
61486
|
this.pdfElements = [...updatedElements];
|
|
@@ -60745,6 +61556,64 @@ class PdfDesignerService {
|
|
|
60745
61556
|
const easternArabicNumerals = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
|
|
60746
61557
|
return input.replace(/\d/g, d => easternArabicNumerals[+d]);
|
|
60747
61558
|
}
|
|
61559
|
+
normalizeMargin(margin) {
|
|
61560
|
+
const fallback = [0, 0, 0, 0];
|
|
61561
|
+
if (!Array.isArray(margin))
|
|
61562
|
+
return fallback;
|
|
61563
|
+
return [0, 1, 2, 3].map(index => Number(margin[index]) || 0);
|
|
61564
|
+
}
|
|
61565
|
+
normalizePdfStyle(style = {}) {
|
|
61566
|
+
const normalized = JSON.parse(JSON.stringify(style || {}));
|
|
61567
|
+
if (normalized.fontSize !== undefined) {
|
|
61568
|
+
normalized.fontSize = Number(normalized.fontSize) || 12;
|
|
61569
|
+
}
|
|
61570
|
+
if (normalized.lineHeight !== undefined) {
|
|
61571
|
+
normalized.lineHeight = Number(normalized.lineHeight) || 1;
|
|
61572
|
+
}
|
|
61573
|
+
if (normalized.characterSpacing !== undefined) {
|
|
61574
|
+
normalized.characterSpacing = Number(normalized.characterSpacing) || 0;
|
|
61575
|
+
}
|
|
61576
|
+
if (normalized.opacity !== undefined) {
|
|
61577
|
+
normalized.opacity = Number(normalized.opacity);
|
|
61578
|
+
}
|
|
61579
|
+
if (normalized.margin) {
|
|
61580
|
+
normalized.margin = this.normalizeMargin(normalized.margin);
|
|
61581
|
+
}
|
|
61582
|
+
if (normalized.fontWeight !== undefined && normalized.bold === undefined) {
|
|
61583
|
+
normalized.bold = Number(normalized.fontWeight) >= 600;
|
|
61584
|
+
}
|
|
61585
|
+
if (normalized.fontStyle === 'bold') {
|
|
61586
|
+
normalized.bold = true;
|
|
61587
|
+
}
|
|
61588
|
+
if (normalized.fontStyle === 'italic') {
|
|
61589
|
+
normalized.italics = true;
|
|
61590
|
+
}
|
|
61591
|
+
if (normalized.italic !== undefined && normalized.italics === undefined) {
|
|
61592
|
+
normalized.italics = !!normalized.italic;
|
|
61593
|
+
}
|
|
61594
|
+
if (normalized.fillColor && !normalized.background) {
|
|
61595
|
+
normalized.background = normalized.fillColor;
|
|
61596
|
+
}
|
|
61597
|
+
if (normalized.backgroundColor && !normalized.background) {
|
|
61598
|
+
normalized.background = normalized.backgroundColor;
|
|
61599
|
+
}
|
|
61600
|
+
delete normalized.italic;
|
|
61601
|
+
delete normalized.fontWeight;
|
|
61602
|
+
delete normalized.fontStyle;
|
|
61603
|
+
delete normalized.backgroundColor;
|
|
61604
|
+
delete normalized.cellColor;
|
|
61605
|
+
delete normalized.cellFillColor;
|
|
61606
|
+
delete normalized.labelColor;
|
|
61607
|
+
delete normalized.labelFontSize;
|
|
61608
|
+
delete normalized.labelBold;
|
|
61609
|
+
delete normalized.headingColor;
|
|
61610
|
+
delete normalized.headingFontSize;
|
|
61611
|
+
delete normalized.headingBold;
|
|
61612
|
+
delete normalized.headingMargin;
|
|
61613
|
+
delete normalized.blankLineHeight;
|
|
61614
|
+
delete normalized.borderColor;
|
|
61615
|
+
return normalized;
|
|
61616
|
+
}
|
|
60748
61617
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfDesignerService, deps: [{ token: CountryService }, { token: i1$1.HttpClient }, { token: DataService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
60749
61618
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfDesignerService, providedIn: 'root' });
|
|
60750
61619
|
}
|
|
@@ -61361,13 +62230,119 @@ class PdfPropertiesComponent {
|
|
|
61361
62230
|
}
|
|
61362
62231
|
]
|
|
61363
62232
|
},
|
|
61364
|
-
'
|
|
62233
|
+
'Section': {
|
|
61365
62234
|
elementProps: [
|
|
61366
62235
|
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
61367
|
-
{ label: '
|
|
62236
|
+
{ label: 'Section Text', placeholder: 'Section Title', type: 'text', key: 'value' },
|
|
61368
62237
|
{ label: 'width', labelPath: 'WIDTH', type: 'fieldSize', key: 'width' },
|
|
61369
62238
|
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' },
|
|
61370
|
-
|
|
62239
|
+
],
|
|
62240
|
+
fieldProps: [
|
|
62241
|
+
{ label: 'Reference Field', labelPath: 'REFERENCEFIELD', placeholder: 'Reference Field', type: 'text', key: 'referenceField' },
|
|
62242
|
+
this.subtext
|
|
62243
|
+
],
|
|
62244
|
+
appearance: [
|
|
62245
|
+
{ label: 'Font Color', labelPath: 'color', type: 'color', key: 'style.color', value: '' },
|
|
62246
|
+
{ label: 'Background Color', type: 'color', key: 'style.fillColor', value: '' },
|
|
62247
|
+
{ label: 'Font Size', labelPath: 'FONTSIZE', type: 'number', key: 'style.fontSize', value: 12 },
|
|
62248
|
+
{
|
|
62249
|
+
label: 'Font Weight', labelPath: 'FONTWEIGHT', type: 'select', key: 'style.fontWeight', value: '',
|
|
62250
|
+
options: [
|
|
62251
|
+
{ value: '400', label: '400-Normal', labelPath: 'FONTWEIGHT_NORMAL' },
|
|
62252
|
+
{ value: '500', label: '500-Medium', labelPath: 'FONTWEIGHT_MEDIUM' },
|
|
62253
|
+
{ value: '600', label: '600-Semi Bold', labelPath: 'FONTWEIGHT_SEMIBOLD' },
|
|
62254
|
+
{ value: '700', label: '700-Bold', labelPath: 'FONTWEIGHT_BOLD' }
|
|
62255
|
+
]
|
|
62256
|
+
},
|
|
62257
|
+
{ label: 'Margin', labelPath: 'MARGIN', type: 'marginPicker', key: 'style.margin', placeholder: 'Left, Top, Right, Bottom', value: [0, 0, 0, 0] },
|
|
62258
|
+
{
|
|
62259
|
+
label: 'Align Item', labelPath: 'ALIGNITEM', type: 'select', key: 'style.alignment', value: '',
|
|
62260
|
+
options: [
|
|
62261
|
+
{ label: 'Left', labelPath: 'ALIGNITEM_LEFT', value: 'left' },
|
|
62262
|
+
{ label: 'Center', labelPath: 'ALIGNITEM_CENTER', value: 'center' },
|
|
62263
|
+
{ label: 'Right', labelPath: 'ALIGNITEM_RIGHT', value: 'right' }
|
|
62264
|
+
]
|
|
62265
|
+
}
|
|
62266
|
+
]
|
|
62267
|
+
},
|
|
62268
|
+
'RichText': {
|
|
62269
|
+
elementProps: [
|
|
62270
|
+
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
62271
|
+
{ label: 'width', labelPath: 'WIDTH', type: 'fieldSize', key: 'width' },
|
|
62272
|
+
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' },
|
|
62273
|
+
],
|
|
62274
|
+
fieldProps: [
|
|
62275
|
+
{ label: 'Content', labelPath: 'VALUE', placeholder: 'Use one line for heading and lines starting with •, -, or * for bullets', type: 'textarea', key: 'value' },
|
|
62276
|
+
{ label: 'Reference Field', labelPath: 'REFERENCEFIELD', placeholder: 'Reference Field', type: 'text', key: 'referenceField' },
|
|
62277
|
+
this.subtext
|
|
62278
|
+
],
|
|
62279
|
+
appearance: [
|
|
62280
|
+
{ label: 'Font Color', labelPath: 'color', type: 'color', key: 'style.color', value: '' },
|
|
62281
|
+
{ label: 'Heading Color', type: 'color', key: 'style.headingColor', value: '' },
|
|
62282
|
+
{ label: 'Font Size', labelPath: 'FONTSIZE', type: 'number', key: 'style.fontSize', value: 12 },
|
|
62283
|
+
{ label: 'Margin', labelPath: 'MARGIN', type: 'marginPicker', key: 'style.margin', placeholder: 'Left, Top, Right, Bottom', value: [0, 0, 0, 0] },
|
|
62284
|
+
{
|
|
62285
|
+
label: 'Align Item', labelPath: 'ALIGNITEM', type: 'select', key: 'style.alignment', value: '',
|
|
62286
|
+
options: [
|
|
62287
|
+
{ label: 'Left', labelPath: 'ALIGNITEM_LEFT', value: 'left' },
|
|
62288
|
+
{ label: 'Center', labelPath: 'ALIGNITEM_CENTER', value: 'center' },
|
|
62289
|
+
{ label: 'Right', labelPath: 'ALIGNITEM_RIGHT', value: 'right' }
|
|
62290
|
+
]
|
|
62291
|
+
}
|
|
62292
|
+
]
|
|
62293
|
+
},
|
|
62294
|
+
'Note': {
|
|
62295
|
+
elementProps: [
|
|
62296
|
+
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
62297
|
+
{ label: 'Note Text', placeholder: 'Enter note', type: 'textarea', key: 'value' },
|
|
62298
|
+
{ label: 'width', labelPath: 'WIDTH', type: 'fieldSize', key: 'width' },
|
|
62299
|
+
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' },
|
|
62300
|
+
],
|
|
62301
|
+
fieldProps: [
|
|
62302
|
+
{ label: 'Reference Field', labelPath: 'REFERENCEFIELD', placeholder: 'Reference Field', type: 'text', key: 'referenceField' },
|
|
62303
|
+
this.subtext
|
|
62304
|
+
],
|
|
62305
|
+
appearance: [
|
|
62306
|
+
{ label: 'Font Color', labelPath: 'color', type: 'color', key: 'style.color', value: '' },
|
|
62307
|
+
{ label: 'Background Color', type: 'color', key: 'style.fillColor', value: '' },
|
|
62308
|
+
{ label: 'Border Color', type: 'color', key: 'style.borderColor', value: '' },
|
|
62309
|
+
{ label: 'Font Size', labelPath: 'FONTSIZE', type: 'number', key: 'style.fontSize', value: 12 },
|
|
62310
|
+
{ label: 'Margin', labelPath: 'MARGIN', type: 'marginPicker', key: 'style.margin', placeholder: 'Left, Top, Right, Bottom', value: [0, 0, 0, 0] },
|
|
62311
|
+
]
|
|
62312
|
+
},
|
|
62313
|
+
'PageBreak': {
|
|
62314
|
+
elementProps: [
|
|
62315
|
+
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
62316
|
+
{
|
|
62317
|
+
label: 'Break Position', type: 'select', key: 'pageBreak', value: 'after',
|
|
62318
|
+
options: [
|
|
62319
|
+
{ label: 'After This Point', value: 'after' },
|
|
62320
|
+
{ label: 'Before This Point', value: 'before' }
|
|
62321
|
+
]
|
|
62322
|
+
},
|
|
62323
|
+
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' }
|
|
62324
|
+
],
|
|
62325
|
+
fieldProps: [],
|
|
62326
|
+
appearance: []
|
|
62327
|
+
},
|
|
62328
|
+
'PdfMake': {
|
|
62329
|
+
elementProps: [
|
|
62330
|
+
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
62331
|
+
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' }
|
|
62332
|
+
],
|
|
62333
|
+
fieldProps: [
|
|
62334
|
+
{ label: 'Content JSON', placeholder: '{ \"text\": \"Hello\" }', type: 'textarea', key: 'pdfMakeContent' },
|
|
62335
|
+
{ label: 'Styles JSON', placeholder: '{ \"myStyle\": { \"fontSize\": 12 } }', type: 'textarea', key: 'pdfMakeStyles' }
|
|
62336
|
+
],
|
|
62337
|
+
appearance: []
|
|
62338
|
+
},
|
|
62339
|
+
'Pdf': {
|
|
62340
|
+
elementProps: [
|
|
62341
|
+
{ label: 'Element', labelPath: 'ELEMENT', type: 'number', key: 'questionNumber' },
|
|
62342
|
+
{ label: 'Help Text', placeholder: 'Enter Text', type: 'text', key: 'helpText', isTranslate: true, labelPath: 'HELP_TEXT' },
|
|
62343
|
+
{ label: 'width', labelPath: 'WIDTH', type: 'fieldSize', key: 'width' },
|
|
62344
|
+
{ label: 'Hide In Pdf', labelPath: 'HIDEINPDF', type: 'checkbox', key: 'hideInPdf' },
|
|
62345
|
+
{ label: 'Label', placeholder: 'Field label', type: 'text', key: 'questionText', isTranslate: true, labelPath: 'LABEL' },
|
|
61371
62346
|
{ label: 'Show Label In Pdf', labelPath: 'SHOW_LABEL_IN_PDF', type: 'checkbox', key: 'showLabelInPdf' },
|
|
61372
62347
|
],
|
|
61373
62348
|
fieldProps: [
|
|
@@ -61950,6 +62925,154 @@ class PdfPropertiesComponent {
|
|
|
61950
62925
|
updateTitle(event) {
|
|
61951
62926
|
this.pdfDesignerService.updateTitle(event);
|
|
61952
62927
|
}
|
|
62928
|
+
getPdfSettings() {
|
|
62929
|
+
this.pdf = this.pdfDesignerService.getBook();
|
|
62930
|
+
if (!this.pdf)
|
|
62931
|
+
return {};
|
|
62932
|
+
if (!this.pdf.pdfSettings) {
|
|
62933
|
+
this.pdf.pdfSettings = this.pdfDesignerService.getDefaultPdfSettings();
|
|
62934
|
+
}
|
|
62935
|
+
return this.pdf.pdfSettings;
|
|
62936
|
+
}
|
|
62937
|
+
getPdfSetting(path, fallback = '') {
|
|
62938
|
+
const settings = this.getPdfSettings();
|
|
62939
|
+
const value = path.split('.').reduce((obj, key) => obj?.[key], settings);
|
|
62940
|
+
return value === undefined || value === null ? fallback : value;
|
|
62941
|
+
}
|
|
62942
|
+
setPdfSetting(path, value) {
|
|
62943
|
+
const settings = this.getPdfSettings();
|
|
62944
|
+
const keys = path.split('.');
|
|
62945
|
+
let obj = settings;
|
|
62946
|
+
keys.forEach((key, index) => {
|
|
62947
|
+
if (index === keys.length - 1) {
|
|
62948
|
+
obj[key] = this.normalizePdfSettingValue(path, value);
|
|
62949
|
+
}
|
|
62950
|
+
else {
|
|
62951
|
+
obj[key] = obj[key] || {};
|
|
62952
|
+
obj = obj[key];
|
|
62953
|
+
}
|
|
62954
|
+
});
|
|
62955
|
+
}
|
|
62956
|
+
onPdfSettingInput(path, event) {
|
|
62957
|
+
const input = event.target;
|
|
62958
|
+
this.setPdfSetting(path, input.type === 'checkbox' ? input.checked : input.value);
|
|
62959
|
+
}
|
|
62960
|
+
getStyleBuilderTitle() {
|
|
62961
|
+
if (this.selectedElement?.type === 'Table' && this.selectColumn) {
|
|
62962
|
+
const column = this.getSelectedTableColumn();
|
|
62963
|
+
return `Table Column Style${column?.label ? ': ' + column.label : ''}`;
|
|
62964
|
+
}
|
|
62965
|
+
return `${this.selectedElement?.type || 'Element'} Style Builder`;
|
|
62966
|
+
}
|
|
62967
|
+
getActiveStyleValue(path, fallback = '') {
|
|
62968
|
+
const style = this.getActiveStyleTarget(false);
|
|
62969
|
+
const value = path.split('.').reduce((obj, key) => obj?.[key], style);
|
|
62970
|
+
return value === undefined || value === null || value === '' ? fallback : value;
|
|
62971
|
+
}
|
|
62972
|
+
onActiveStyleInput(path, event) {
|
|
62973
|
+
const input = event.target;
|
|
62974
|
+
const rawValue = input.type === 'checkbox' ? input.checked : input.value;
|
|
62975
|
+
this.setActiveStyleValue(path, this.normalizeStyleInputValue(path, rawValue));
|
|
62976
|
+
}
|
|
62977
|
+
setActiveStyleValue(path, value) {
|
|
62978
|
+
const style = this.getActiveStyleTarget(true);
|
|
62979
|
+
if (!style)
|
|
62980
|
+
return;
|
|
62981
|
+
const keys = path.split('.');
|
|
62982
|
+
let obj = style;
|
|
62983
|
+
keys.forEach((key, index) => {
|
|
62984
|
+
if (index === keys.length - 1) {
|
|
62985
|
+
obj[key] = value;
|
|
62986
|
+
}
|
|
62987
|
+
else {
|
|
62988
|
+
obj[key] = obj[key] || {};
|
|
62989
|
+
obj = obj[key];
|
|
62990
|
+
}
|
|
62991
|
+
});
|
|
62992
|
+
if (path === 'fontWeight') {
|
|
62993
|
+
style.bold = Number(value) >= 600;
|
|
62994
|
+
}
|
|
62995
|
+
if (path === 'bold' && value === true && !style.fontWeight) {
|
|
62996
|
+
style.fontWeight = '700';
|
|
62997
|
+
}
|
|
62998
|
+
this.updateElement(this.selectedElement);
|
|
62999
|
+
}
|
|
63000
|
+
getActiveMargin(index) {
|
|
63001
|
+
return this.normalizeStyleMargin(this.getActiveStyleValue('margin', [0, 0, 0, 0]))[index];
|
|
63002
|
+
}
|
|
63003
|
+
onActiveMarginInput(index, event) {
|
|
63004
|
+
const input = event.target;
|
|
63005
|
+
const margin = this.normalizeStyleMargin(this.getActiveStyleValue('margin', [0, 0, 0, 0]));
|
|
63006
|
+
margin[index] = Number(input.value) || 0;
|
|
63007
|
+
this.setActiveStyleValue('margin', margin);
|
|
63008
|
+
}
|
|
63009
|
+
getElementArrayValue(path, index, fallback = 0) {
|
|
63010
|
+
const value = this.getValueByPath(path);
|
|
63011
|
+
return Array.isArray(value) && value[index] !== undefined ? Number(value[index]) || 0 : fallback;
|
|
63012
|
+
}
|
|
63013
|
+
onElementArrayInput(path, index, event) {
|
|
63014
|
+
const input = event.target;
|
|
63015
|
+
const value = Array.isArray(this.getValueByPath(path)) ? [...this.getValueByPath(path)] : [0, 0, 0, 0];
|
|
63016
|
+
value[index] = Number(input.value) || 0;
|
|
63017
|
+
this.setValueByPath(path, value);
|
|
63018
|
+
}
|
|
63019
|
+
getActiveColumnWidthMode() {
|
|
63020
|
+
const width = this.getActiveStyleValue('width', '*');
|
|
63021
|
+
if (width === '*' || width === 'auto')
|
|
63022
|
+
return width;
|
|
63023
|
+
return 'custom';
|
|
63024
|
+
}
|
|
63025
|
+
onActiveColumnWidthModeChange(event) {
|
|
63026
|
+
const value = event.target.value;
|
|
63027
|
+
if (value === 'custom') {
|
|
63028
|
+
const currentWidth = this.getActiveStyleValue('width', 80);
|
|
63029
|
+
this.setActiveStyleValue('width', currentWidth === '*' || currentWidth === 'auto' ? 80 : currentWidth);
|
|
63030
|
+
return;
|
|
63031
|
+
}
|
|
63032
|
+
this.setActiveStyleValue('width', value);
|
|
63033
|
+
}
|
|
63034
|
+
getActiveStyleTarget(create = true) {
|
|
63035
|
+
if (this.selectedElement?.type === 'Table' && this.selectColumn) {
|
|
63036
|
+
const column = this.getSelectedTableColumn();
|
|
63037
|
+
if (!column)
|
|
63038
|
+
return null;
|
|
63039
|
+
if (create && !column.style)
|
|
63040
|
+
column.style = {};
|
|
63041
|
+
return column.style || {};
|
|
63042
|
+
}
|
|
63043
|
+
if (!this.selectedElement)
|
|
63044
|
+
return null;
|
|
63045
|
+
if (create && !this.selectedElement.style)
|
|
63046
|
+
this.selectedElement.style = {};
|
|
63047
|
+
return this.selectedElement.style || {};
|
|
63048
|
+
}
|
|
63049
|
+
getSelectedTableColumn() {
|
|
63050
|
+
if (!this.selectedElement?.fieldsMeta || !this.selectColumn)
|
|
63051
|
+
return null;
|
|
63052
|
+
return this.selectedElement.fieldsMeta.find(column => column.uniqueIdentifier === this.selectColumn);
|
|
63053
|
+
}
|
|
63054
|
+
normalizeStyleInputValue(path, value) {
|
|
63055
|
+
const numericPaths = ['fontSize', 'headingFontSize', 'blankLineHeight', 'lineHeight', 'characterSpacing', 'labelFontSize', 'opacity', 'width'];
|
|
63056
|
+
if (numericPaths.includes(path)) {
|
|
63057
|
+
return Number(value);
|
|
63058
|
+
}
|
|
63059
|
+
return value;
|
|
63060
|
+
}
|
|
63061
|
+
normalizeStyleMargin(value) {
|
|
63062
|
+
if (!Array.isArray(value))
|
|
63063
|
+
return [0, 0, 0, 0];
|
|
63064
|
+
return [0, 1, 2, 3].map(index => Number(value[index]) || 0);
|
|
63065
|
+
}
|
|
63066
|
+
normalizePdfSettingValue(path, value) {
|
|
63067
|
+
const numberPaths = ['watermark.opacity', 'watermark.angle', 'watermark.fontSize', 'header.fontSize', 'header.borderWidth', 'footer.fontSize', 'footer.borderWidth'];
|
|
63068
|
+
if (numberPaths.includes(path)) {
|
|
63069
|
+
return Number(value);
|
|
63070
|
+
}
|
|
63071
|
+
if (path.startsWith('pageMargins.') || path.startsWith('header.margin.') || path.startsWith('footer.margin.')) {
|
|
63072
|
+
return Number(value) || 0;
|
|
63073
|
+
}
|
|
63074
|
+
return value;
|
|
63075
|
+
}
|
|
61953
63076
|
updatePdfpData() {
|
|
61954
63077
|
// SKS28MAR25 Convert array to comma-separated string
|
|
61955
63078
|
this.fieldAsString = this.bookSubtext?.field?.join(', ') || '';
|
|
@@ -62390,11 +63513,11 @@ class PdfPropertiesComponent {
|
|
|
62390
63513
|
}
|
|
62391
63514
|
}
|
|
62392
63515
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfPropertiesComponent, deps: [{ token: DataService }, { token: i1$1.HttpClient }, { token: PdfDesignerService }, { token: TemplateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
62393
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: PdfPropertiesComponent, isStandalone: true, selector: "app-pdf-properties", inputs: { selectedElementType: "selectedElementType", templateSelected: "templateSelected" }, outputs: { formButtonHandler: "formButtonHandler", templateSaveHandler: "templateSaveHandler" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<!-- - Field and Element Properties -->\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n {{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n {{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n {{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <!-- Element Properrties -->\n <!-- Select element type show -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type] as props\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.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 <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\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 <!-- SKS28MAR25 search pdf specific for pdf element -->\n <div *ngIf=\"selectedElement?.type === 'Pdf'\">\n <label class=\"text-sm\">{{ 'SEARCHPDF' | nxtCustomTranslate : 'Search Pdf' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [readOnly]=\"selectedElement.isReadOnly\" [apiMeta]=\"bookSubtext\"\n [placeHolderText]=\"selectedElement.question || ''\"\n [mode]=\"'edit'\"\n (searchValueChange)=\"childEventCapture($event)\">\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>{{ 'ENDPOINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>{{ 'DEFAULTFIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label \n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\"></option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n\n </div>\n <!-- SKS20MAR25 Subquestion Type -->\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 type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n 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 <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- Change key width -->\n <div *ngIf=\"prop.type === 'fieldSize'\" [ngClass]=\"{'flex-container': true, 'custom-active': selectedElement?.width !== '*' && selectedElement?.width !== 'auto'}\">\n <select\n class=\"size-select\"\n [value]=\"selectedElement?.width === '*' ? 'Default' : selectedElement?.width === 'auto' ? 'Auto' : 'Custom'\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom') : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' ) ) : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' )\">\n <option value=\"Default\">{{ 'DEFAULT' | nxtCustomTranslate : 'Default' }}</option>\n <option value=\"Auto\">{{ 'AUTO' | nxtCustomTranslate : 'Auto' }}</option>\n <option value=\"Custom\">{{ 'CUSTOM' | nxtCustomTranslate : 'Custom' }}</option>\n </select>\n \n <input\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== '*' && selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== 'auto'\"\n type=\"number\"\n class=\"size-input\"\n min=\"1\"\n max=\"100\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) ) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber)\"\n />\n </div> \n\n <!-- Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- Show elements ID -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\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 }}</div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n </div>\n\n <!-- - handled options with UUID -->\n <div *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" \n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n \n <!-- Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (change)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.checked) ) : setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : 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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div class=\"flex-container\">\n <!-- Type select -->\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.labelPath | nxtCustomTranslate : option.label }}\n </option>\n </select>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Type number -->\n <div *ngIf=\"prop.type === 'number'\">\n <input type=\"number\" min=\"1\" max=\"100\" step=\"1\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n <!-- margin: [0, 10, 0, 0] // [ left, top, right, bottom ] -->\n <div *ngIf=\"prop.type === 'marginPicker'\">\n <div class=\"margin-inputs\">\n <div>\n <label>Right</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[0] : getValueByPath(prop.key)?.[0] ) : getValueByPath(prop.key)?.[0])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.0', $event) : setValueByPath(prop.key+'.0', $event.target.value) ) : setValueByPath(prop.key+'.0', $event.target.value)\" />\n </div>\n <div>\n <label>Top</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[1] : getValueByPath(prop.key)?.[1] ) : getValueByPath(prop.key)?.[1])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.1', $event) : setValueByPath(prop.key+'.1', $event.target.value) ) : setValueByPath(prop.key+'.1', $event.target.value)\" />\n </div>\n <div>\n <label>Left</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[2] : getValueByPath(prop.key)?.[2] ) : getValueByPath(prop.key)?.[2])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.2', $event) : setValueByPath(prop.key+'.2', $event.target.value) ) : setValueByPath(prop.key+'.2', $event.target.value)\" />\n </div>\n <div>\n <label>Bottom</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[3] : getValueByPath(prop.key)?.[3] ) : getValueByPath(prop.key)?.[3])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.3', $event) : setValueByPath(prop.key+'.3', $event.target.value) ) : setValueByPath(prop.key+'.3', $event.target.value)\" />\n </div>\n </div>\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Default Save Button -->\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n </div>\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap\";*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.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}.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}label{font-size:14px;font-weight:500;color:#444;margin-bottom:5px;display:block}input[type=text],input[type=number],select{width:100%;height:40px;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:.3s;background:#f8f8f8;text-align:left}input:focus,select:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}button{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:.3s}button:hover{background:#0056b3;transform:translateY(-2px)}.toggle-group{display:flex;align-items:center;gap:20px}.toggle-item{display:flex;align-items:center;gap:10px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background-color:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background-color:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.options-container{display:flex;flex-direction:column;gap:12px}.options{width:100%}.field-size-controls{display:flex;align-items:center;gap:12px}.size-input{width:110px;text-align:center}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.design-footer .btn{background:#007bff;color:#fff;padding:10px 18px;border-radius:6px;font-size:15px;transition:.3s}.design-footer .btn:hover{background:#0056b3}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.container{width:100%;max-width:500px;margin:0 auto;background-color:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.tabs{display:flex;background-color:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background-color:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:77vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:flex;gap:16px;margin-bottom:8px;color:#666;font-size:14px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],select{width:100%;padding:10px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;font-size:14px}.select-container{position:relative;width:100%}.dropdown-arrow{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.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}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.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-color:#4caf50}.view-icon{background-color:#2196f3}.delete-icon{background-color:#f44336}.color-picker-row{display:flex;align-items:center}.color-picker-container{display:flex;align-items:center;border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box{width:30px;border:none;height:30px}.hex-label{color:#999;margin-right:5px}.hex-input{width:100px}.divider{border-top:1px dashed #ddd;margin:20px 0}.button-container{display:flex;padding:15px;background-color:#f9f9f9;border-top:1px solid #eee}.cancel-btn,.save-btn{padding:12px;border:none;border-radius:4px;cursor:pointer;font-weight:700}.cancel-btn{flex:1;background-color:#fff;color:#666;border:1px solid #ddd}.cancel-btn:hover{background-color:#0052cc!important;color:#fff!important}.save-btn{flex:1;background-color:#0052cc;color:#fff;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;padding:8px}textarea{width:100%;min-height:55px;padding:8px;border:1px solid #ccc;border-radius:5px;font-size:14px;resize:vertical}.flex-container{display:flex;align-items:center;gap:12px;margin-bottom:1rem}.input-box-field select{background-color:#28343e;color:#fff;border:none;padding:10px 14px;border-radius:6px;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;font-size:14px;font-family:inherit}.input-box-field{position:relative}.input-box-field select::-ms-expand{display:none}.input-box-field:after{content:\"\\25bc\";position:absolute;top:50%;right:10px;transform:translateY(-50%);color:#1c1b1f;pointer-events:none;font-size:10px}.color-selector input[type=color]{width:40px;height:40px;border-radius:4px;background:none;cursor:pointer}.hex-input-container{display:flex;font-size:12px;gap:20px;color:#b0b0b0;align-items:center}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input-container input[type=text]{padding:10px 12px;border:1px solid #d1d1d1;border-radius:6px;font-size:14px;width:120px;color:#28343e}input{width:auto}@media screen and (max-width:1099px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:768px){.container{height:calc(100vh - 20px) h;min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}@media screen and (max-width:768px){.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}.logo-icon{width:20px;height:20px;display:flex;width:35px;justify-content:center;background-color:#d0d9ff;border-radius:4px}.link-icon{background-color:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:background-color .3s,transform .2s}.link-icon:hover{background-color:#d0e5ff}.link-icon:active{background-color:#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}.drag-handle{cursor:grab}.option-items:active{opacity:.5}.style-toggle-header{display:flex;justify-content:space-between;align-items:center;background-color:#f8f8f8;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;margin-bottom:6px}.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-color:#2c6dd5}.flex-container{display:flex;gap:8px;align-items:center}.size-select{transition:width .3s ease;width:100%;max-width:200px}.flex-container.custom-active .size-select{max-width:100px}.size-input{width:60px}.margin-inputs{display:flex;gap:15px;margin-top:5px}.margin-inputs>div{display:flex;flex-direction:column;width:60px}.margin-inputs label{font-size:12px;margin-bottom:3px}.pdf-actions-container{width:100%;max-width:400px;padding:10px}.pdf-action-card{background-color:#fff;border-radius:6px;padding:9px;box-shadow:0 2px 6px #0000001a;display:flex;flex-direction:column;gap:10px}.pdf-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px;background-color:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s}.pdf-btn:hover{background-color:#5a6268}\n"], dependencies: [{ 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NxtSearchBox, selector: "nxt-search-box", inputs: ["placeHolderText", "question", "apiMeta", "id", "readOnly", "mode", "from", "value", "onlyView", "rowData"], outputs: ["searchValueChange"] }, { 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }, { kind: "component", type: FormulaInputComponent, selector: "app-formula-input", inputs: ["attributes", "initialFormula"], outputs: ["formulaChange", "formulaValidation"] }] });
|
|
63516
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: PdfPropertiesComponent, isStandalone: true, selector: "app-pdf-properties", inputs: { selectedElementType: "selectedElementType", templateSelected: "templateSelected" }, outputs: { formButtonHandler: "formButtonHandler", templateSaveHandler: "templateSaveHandler" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<!-- - Field and Element Properties -->\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n {{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n {{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n {{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <div *ngIf=\"headerSelect\" class=\"document-settings\">\n <div class=\"document-settings-title\">Document Canvas</div>\n <div class=\"form-group\">\n <label>Page Size</label>\n <select [value]=\"getPdfSetting('pageSize', 'A4')\" (change)=\"onPdfSettingInput('pageSize', $event)\">\n <option value=\"A4\">A4</option>\n <option value=\"LETTER\">Letter</option>\n <option value=\"LEGAL\">Legal</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Orientation</label>\n <select [value]=\"getPdfSetting('pageOrientation', 'portrait')\" (change)=\"onPdfSettingInput('pageOrientation', $event)\">\n <option value=\"portrait\">Portrait</option>\n <option value=\"landscape\">Landscape</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Background Color</label>\n <div class=\"document-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Page Margins</label>\n <div class=\"margin-inputs\">\n <div><label>Left</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.0', 40)\" (change)=\"onPdfSettingInput('pageMargins.0', $event)\" /></div>\n <div><label>Top</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.1', 40)\" (change)=\"onPdfSettingInput('pageMargins.1', $event)\" /></div>\n <div><label>Right</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.2', 40)\" (change)=\"onPdfSettingInput('pageMargins.2', $event)\" /></div>\n <div><label>Bottom</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.3', 80)\" (change)=\"onPdfSettingInput('pageMargins.3', $event)\" /></div>\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.enabled', false)\" (change)=\"onPdfSettingInput('header.enabled', $event)\" />\n Running Header\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('header.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Show Header</label>\n <select [value]=\"getPdfSetting('header.showOn', 'all')\" (change)=\"onPdfSettingInput('header.showOn', $event)\">\n <option value=\"all\">All Pages</option>\n <option value=\"first\">First Page Only</option>\n <option value=\"notFirst\">Skip First Page</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Header Left</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.leftText', '')\" (input)=\"onPdfSettingInput('header.leftText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Center</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.centerText', '')\" (input)=\"onPdfSettingInput('header.centerText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Right</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.rightText', '')\" (input)=\"onPdfSettingInput('header.rightText', $event)\" />\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.bottomBorder', false)\" (change)=\"onPdfSettingInput('header.bottomBorder', $event)\" />\n Bottom Line\n </label>\n </div>\n <div class=\"form-group\">\n <label>Header Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('header.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('header.borderColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('watermark.enabled', false)\" (change)=\"onPdfSettingInput('watermark.enabled', $event)\" />\n Watermark\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('watermark.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Watermark Text</label>\n <input type=\"text\" [value]=\"getPdfSetting('watermark.text', '')\" (input)=\"onPdfSettingInput('watermark.text', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Watermark Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('watermark.color', '#9ca3af')\" (change)=\"onPdfSettingInput('watermark.color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getPdfSetting('watermark.opacity', 0.16)\" (change)=\"onPdfSettingInput('watermark.opacity', $event)\" />\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.enabled', false)\" (change)=\"onPdfSettingInput('footer.enabled', $event)\" />\n Footer\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('footer.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Show Footer</label>\n <select [value]=\"getPdfSetting('footer.showOn', 'last')\" (change)=\"onPdfSettingInput('footer.showOn', $event)\">\n <option value=\"last\">Last Page Only</option>\n <option value=\"all\">All Pages</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Footer Content</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.text', '')\" (input)=\"onPdfSettingInput('footer.text', $event)\" />\n </div>\n <div class=\"document-help\">Use {{'{{currentPage}}'}} and {{'{{pageCount}}'}} for page numbers.</div>\n <div class=\"form-group\">\n <label>Footer Left</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.leftText', '')\" (input)=\"onPdfSettingInput('footer.leftText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Footer Center</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.centerText', '')\" (input)=\"onPdfSettingInput('footer.centerText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Footer Right</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.rightText', '')\" (input)=\"onPdfSettingInput('footer.rightText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Alignment</label>\n <select [value]=\"getPdfSetting('footer.alignment', 'center')\" (change)=\"onPdfSettingInput('footer.alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.topBorder', false)\" (change)=\"onPdfSettingInput('footer.topBorder', $event)\" />\n Top Line\n </label>\n </div>\n <div class=\"form-group\">\n <label>Footer Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('footer.borderColor', $event)\" />\n </div>\n </div>\n </div>\n <!-- Element Properrties -->\n <!-- Select element type show -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type] as props\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.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 <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\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 <!-- SKS28MAR25 search pdf specific for pdf element -->\n <div *ngIf=\"selectedElement?.type === 'Pdf'\">\n <label class=\"text-sm\">{{ 'SEARCHPDF' | nxtCustomTranslate : 'Search Pdf' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [readOnly]=\"selectedElement.isReadOnly\" [apiMeta]=\"bookSubtext\"\n [placeHolderText]=\"selectedElement.question || ''\"\n [mode]=\"'edit'\"\n (searchValueChange)=\"childEventCapture($event)\">\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>{{ 'ENDPOINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>{{ 'DEFAULTFIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label \n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <textarea *ngIf=\"prop.type === 'textarea'\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (input)=\"selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </textarea>\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\"></option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <select *ngIf=\"prop.type === 'select' && prop.key !== 'supportType' && prop.key !== 'lineStyle'\" [value]=\"getValueByPath(prop.key)\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n\n </div>\n <!-- SKS20MAR25 Subquestion Type -->\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 type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n 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 <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- Change key width -->\n <div *ngIf=\"prop.type === 'fieldSize'\" [ngClass]=\"{'flex-container': true, 'custom-active': selectedElement?.width !== '*' && selectedElement?.width !== 'auto'}\">\n <select\n class=\"size-select\"\n [value]=\"selectedElement?.width === '*' ? 'Default' : selectedElement?.width === 'auto' ? 'Auto' : 'Custom'\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom') : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' ) ) : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' )\">\n <option value=\"Default\">{{ 'DEFAULT' | nxtCustomTranslate : 'Default' }}</option>\n <option value=\"Auto\">{{ 'AUTO' | nxtCustomTranslate : 'Auto' }}</option>\n <option value=\"Custom\">{{ 'CUSTOM' | nxtCustomTranslate : 'Custom' }}</option>\n </select>\n \n <input\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== '*' && selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== 'auto'\"\n type=\"number\"\n class=\"size-input\"\n min=\"1\"\n max=\"100\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) ) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber)\"\n />\n </div> \n\n <!-- Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- Show elements ID -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\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 }}</div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n </div>\n\n <!-- - handled options with UUID -->\n <div *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <textarea *ngIf=\"prop.type === 'textarea'\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (input)=\"selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </textarea>\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" \n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n \n <!-- Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (change)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.checked) ) : setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : 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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <!-- SKS26MAY26 builder stype tool -->\n <div *ngIf=\"headerSelect\" class=\"style-builder\">\n <div class=\"style-builder-title\">Document Style Builder</div>\n <div class=\"style-section-title\">Page</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Page Size</label>\n <select [value]=\"getPdfSetting('pageSize', 'A4')\" (change)=\"onPdfSettingInput('pageSize', $event)\">\n <option value=\"A4\">A4</option>\n <option value=\"LETTER\">Letter</option>\n <option value=\"LEGAL\">Legal</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Orientation</label>\n <select [value]=\"getPdfSetting('pageOrientation', 'portrait')\" (change)=\"onPdfSettingInput('pageOrientation', $event)\">\n <option value=\"portrait\">Portrait</option>\n <option value=\"landscape\">Landscape</option>\n </select>\n </div>\n </div>\n <div class=\"form-group\">\n <label>Background</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Page Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.0', 40)\" (change)=\"onPdfSettingInput('pageMargins.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.1', 40)\" (change)=\"onPdfSettingInput('pageMargins.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.2', 40)\" (change)=\"onPdfSettingInput('pageMargins.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.3', 80)\" (change)=\"onPdfSettingInput('pageMargins.3', $event)\" /></div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Running Header</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.enabled', false)\" (change)=\"onPdfSettingInput('header.enabled', $event)\" />\n <span>Enable header</span>\n </label>\n <div *ngIf=\"getPdfSetting('header.enabled', false)\" class=\"style-nested\">\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Show On</label>\n <select [value]=\"getPdfSetting('header.showOn', 'all')\" (change)=\"onPdfSettingInput('header.showOn', $event)\">\n <option value=\"all\">All Pages</option>\n <option value=\"first\">First Page Only</option>\n <option value=\"notFirst\">Skip First Page</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('header.fontSize', 9)\" (change)=\"onPdfSettingInput('header.fontSize', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('header.color', '#666666')\" (change)=\"onPdfSettingInput('header.color', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('header.color', '#666666')\" (change)=\"onPdfSettingInput('header.color', $event)\" />\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\"><label>Left</label><input type=\"text\" [value]=\"getPdfSetting('header.leftText', '')\" (input)=\"onPdfSettingInput('header.leftText', $event)\" /></div>\n <div class=\"form-group\"><label>Center</label><input type=\"text\" [value]=\"getPdfSetting('header.centerText', '')\" (input)=\"onPdfSettingInput('header.centerText', $event)\" /></div>\n <div class=\"form-group\"><label>Right</label><input type=\"text\" [value]=\"getPdfSetting('header.rightText', '')\" (input)=\"onPdfSettingInput('header.rightText', $event)\" /></div>\n </div>\n <div class=\"form-group\">\n <label>Header Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.0', 40)\" (change)=\"onPdfSettingInput('header.margin.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.1', 20)\" (change)=\"onPdfSettingInput('header.margin.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.2', 40)\" (change)=\"onPdfSettingInput('header.margin.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.3', 0)\" (change)=\"onPdfSettingInput('header.margin.3', $event)\" /></div>\n </div>\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.bottomBorder', false)\" (change)=\"onPdfSettingInput('header.bottomBorder', $event)\" />\n <span>Bottom line</span>\n </label>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('header.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('header.borderColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Width</label>\n <input type=\"number\" min=\"0\" [value]=\"getPdfSetting('header.borderWidth', 1)\" (change)=\"onPdfSettingInput('header.borderWidth', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Watermark</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('watermark.enabled', false)\" (change)=\"onPdfSettingInput('watermark.enabled', $event)\" />\n <span>Enable watermark</span>\n </label>\n <div *ngIf=\"getPdfSetting('watermark.enabled', false)\" class=\"style-nested\">\n <div class=\"form-group\">\n <label>Text</label>\n <input type=\"text\" [value]=\"getPdfSetting('watermark.text', '')\" (input)=\"onPdfSettingInput('watermark.text', $event)\" />\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('watermark.color', '#9ca3af')\" (change)=\"onPdfSettingInput('watermark.color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getPdfSetting('watermark.opacity', 0.16)\" (change)=\"onPdfSettingInput('watermark.opacity', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('watermark.fontSize', 64)\" (change)=\"onPdfSettingInput('watermark.fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Angle</label>\n <input type=\"number\" [value]=\"getPdfSetting('watermark.angle', -32)\" (change)=\"onPdfSettingInput('watermark.angle', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Footer</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.enabled', false)\" (change)=\"onPdfSettingInput('footer.enabled', $event)\" />\n <span>Enable footer</span>\n </label>\n <div *ngIf=\"getPdfSetting('footer.enabled', false)\" class=\"style-nested\">\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Show On</label>\n <select [value]=\"getPdfSetting('footer.showOn', 'last')\" (change)=\"onPdfSettingInput('footer.showOn', $event)\">\n <option value=\"last\">Last Page Only</option>\n <option value=\"all\">All Pages</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Alignment</label>\n <select [value]=\"getPdfSetting('footer.alignment', 'center')\" (change)=\"onPdfSettingInput('footer.alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\"><label>Left</label><input type=\"text\" [value]=\"getPdfSetting('footer.leftText', '')\" (input)=\"onPdfSettingInput('footer.leftText', $event)\" /></div>\n <div class=\"form-group\"><label>Center</label><input type=\"text\" [value]=\"getPdfSetting('footer.centerText', '')\" (input)=\"onPdfSettingInput('footer.centerText', $event)\" /></div>\n <div class=\"form-group\"><label>Right</label><input type=\"text\" [value]=\"getPdfSetting('footer.rightText', '')\" (input)=\"onPdfSettingInput('footer.rightText', $event)\" /></div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('footer.fontSize', 9)\" (change)=\"onPdfSettingInput('footer.fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.color', '#666666')\" (change)=\"onPdfSettingInput('footer.color', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Footer Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.0', 40)\" (change)=\"onPdfSettingInput('footer.margin.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.1', 12)\" (change)=\"onPdfSettingInput('footer.margin.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.2', 40)\" (change)=\"onPdfSettingInput('footer.margin.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.3', 0)\" (change)=\"onPdfSettingInput('footer.margin.3', $event)\" /></div>\n </div>\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.topBorder', false)\" (change)=\"onPdfSettingInput('footer.topBorder', $event)\" />\n <span>Top line</span>\n </label>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('footer.borderColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Width</label>\n <input type=\"number\" min=\"0\" [value]=\"getPdfSetting('footer.borderWidth', 1)\" (change)=\"onPdfSettingInput('footer.borderWidth', $event)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!headerSelect && selectedElement\" class=\"style-builder\">\n <div class=\"style-builder-title\">{{ getStyleBuilderTitle() }}</div>\n\n <div class=\"style-section-title\">Typography</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Font</label>\n <select [value]=\"getActiveStyleValue('font', 'Helvetica Neue')\" (change)=\"onActiveStyleInput('font', $event)\">\n <option value=\"Helvetica Neue\">Helvetica Neue</option>\n <option value=\"Arial\">Arial</option>\n <option value=\"Times New Roman\">Times New Roman</option>\n <option value=\"Roboto\">Roboto</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('fontSize', 12)\" (change)=\"onActiveStyleInput('fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Height</label>\n <input type=\"number\" min=\"0.5\" step=\"0.1\" [value]=\"getActiveStyleValue('lineHeight', 1.2)\" (change)=\"onActiveStyleInput('lineHeight', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Letter Space</label>\n <input type=\"number\" step=\"0.5\" [value]=\"getActiveStyleValue('characterSpacing', 0)\" (change)=\"onActiveStyleInput('characterSpacing', $event)\" />\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Weight</label>\n <select [value]=\"getActiveStyleValue('fontWeight', '400')\" (change)=\"onActiveStyleInput('fontWeight', $event)\">\n <option value=\"400\">400 Normal</option>\n <option value=\"500\">500 Medium</option>\n <option value=\"600\">600 Semi Bold</option>\n <option value=\"700\">700 Bold</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Align</label>\n <select [value]=\"getActiveStyleValue('alignment', 'left')\" (change)=\"onActiveStyleInput('alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n <option value=\"justify\">Justify</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Decoration</label>\n <select [value]=\"getActiveStyleValue('decoration', '')\" (change)=\"onActiveStyleInput('decoration', $event)\">\n <option value=\"\">None</option>\n <option value=\"underline\">Underline</option>\n <option value=\"lineThrough\">Line Through</option>\n <option value=\"overline\">Overline</option>\n </select>\n </div>\n </div>\n <div class=\"style-toggle-row\">\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('bold', false)\" (change)=\"onActiveStyleInput('bold', $event)\" />\n <span>Bold</span>\n </label>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('italic', false)\" (change)=\"onActiveStyleInput('italic', $event)\" />\n <span>Italic</span>\n </label>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Text Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('color', '#000000')\" (change)=\"onActiveStyleInput('color', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('color', '#000000')\" (change)=\"onActiveStyleInput('color', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Background</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('fillColor', '#ffffff')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('fillColor', '#ffffff')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Spacing</div>\n <div class=\"form-group\">\n <label>Margin</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getActiveMargin(0)\" (change)=\"onActiveMarginInput(0, $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getActiveMargin(1)\" (change)=\"onActiveMarginInput(1, $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getActiveMargin(2)\" (change)=\"onActiveMarginInput(2, $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getActiveMargin(3)\" (change)=\"onActiveMarginInput(3, $event)\" /></div>\n </div>\n </div>\n <div class=\"form-group\" *ngIf=\"selectedElement?.type === 'Section' || selectedElement?.type === 'Note'\">\n <label>Inner Padding</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 0, 8)\" (change)=\"onElementArrayInput('innerMargin', 0, $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 1, 6)\" (change)=\"onElementArrayInput('innerMargin', 1, $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 2, 8)\" (change)=\"onElementArrayInput('innerMargin', 2, $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 3, 6)\" (change)=\"onElementArrayInput('innerMargin', 3, $event)\" /></div>\n </div>\n </div>\n\n <div class=\"style-section-title\">PDF Box Style</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Border Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('borderColor', '#2f9e44')\" (change)=\"onActiveStyleInput('borderColor', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('borderColor', '#2f9e44')\" (change)=\"onActiveStyleInput('borderColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getActiveStyleValue('opacity', 1)\" (change)=\"onActiveStyleInput('opacity', $event)\" />\n </div>\n </div>\n\n <div *ngIf=\"selectedElement?.type !== 'Table' || !selectColumn\" class=\"style-section-title\">Label Style</div>\n <div *ngIf=\"selectedElement?.type !== 'Table' || !selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Label Color</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('labelColor', '#222222')\" (change)=\"onActiveStyleInput('labelColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Label Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('labelFontSize', getActiveStyleValue('fontSize', 12))\" (change)=\"onActiveStyleInput('labelFontSize', $event)\" />\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('labelBold', true)\" (change)=\"onActiveStyleInput('labelBold', $event)\" />\n <span>Bold label</span>\n </label>\n </div>\n\n <div *ngIf=\"selectedElement?.type === 'RichText' || selectedElement?.type === 'text'\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Heading Color</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('headingColor', '#2f9e44')\" (change)=\"onActiveStyleInput('headingColor', $event)\" />\n </div>\n <div class=\"form-group\" *ngIf=\"selectedElement?.type === 'text'\">\n <label>Heading Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('headingFontSize', getActiveStyleValue('fontSize', 12))\" (change)=\"onActiveStyleInput('headingFontSize', $event)\" />\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.type === 'RichText' ? selectedElement?.headingFirstLine !== false : selectedElement?.headingFirstLine === true\" (change)=\"setValueByPath('headingFirstLine', $event.target.checked)\" />\n <span>First line heading</span>\n </label>\n </div>\n\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-section-title\">Table Column</div>\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Header Fill</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('fillColor', '#f1f5f9')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Text</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('color', '#111827')\" (change)=\"onActiveStyleInput('color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Cell Fill</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('cellFillColor', '#ffffff')\" (change)=\"onActiveStyleInput('cellFillColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Cell Text</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('cellColor', '#374151')\" (change)=\"onActiveStyleInput('cellColor', $event)\" />\n </div>\n </div>\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Column Width</label>\n <select [value]=\"getActiveColumnWidthMode()\" (change)=\"onActiveColumnWidthModeChange($event)\">\n <option value=\"*\">Default</option>\n <option value=\"auto\">Auto</option>\n <option value=\"custom\">Custom</option>\n </select>\n </div>\n <div class=\"form-group\" *ngIf=\"getActiveColumnWidthMode() === 'custom'\">\n <label>Width</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('width', 80)\" (change)=\"onActiveStyleInput('width', $event)\" />\n </div>\n </div>\n </div>\n\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div class=\"flex-container\">\n <!-- Type select -->\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.labelPath | nxtCustomTranslate : option.label }}\n </option>\n </select>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Type number -->\n <div *ngIf=\"prop.type === 'number'\">\n <input type=\"number\" min=\"1\" max=\"100\" step=\"1\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n <!-- margin: [0, 10, 0, 0] // [ left, top, right, bottom ] -->\n <div *ngIf=\"prop.type === 'marginPicker'\">\n <div class=\"margin-inputs\">\n <div>\n <label>Right</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[0] : getValueByPath(prop.key)?.[0] ) : getValueByPath(prop.key)?.[0])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.0', $event) : setValueByPath(prop.key+'.0', $event.target.value) ) : setValueByPath(prop.key+'.0', $event.target.value)\" />\n </div>\n <div>\n <label>Top</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[1] : getValueByPath(prop.key)?.[1] ) : getValueByPath(prop.key)?.[1])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.1', $event) : setValueByPath(prop.key+'.1', $event.target.value) ) : setValueByPath(prop.key+'.1', $event.target.value)\" />\n </div>\n <div>\n <label>Left</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[2] : getValueByPath(prop.key)?.[2] ) : getValueByPath(prop.key)?.[2])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.2', $event) : setValueByPath(prop.key+'.2', $event.target.value) ) : setValueByPath(prop.key+'.2', $event.target.value)\" />\n </div>\n <div>\n <label>Bottom</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[3] : getValueByPath(prop.key)?.[3] ) : getValueByPath(prop.key)?.[3])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.3', $event) : setValueByPath(prop.key+'.3', $event.target.value) ) : setValueByPath(prop.key+'.3', $event.target.value)\" />\n </div>\n </div>\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Default Save Button -->\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n </div>\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap\";*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.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}.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}label{font-size:14px;font-weight:500;color:#444;margin-bottom:5px;display:block}input[type=text],input[type=number],textarea,select{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:.3s;background:#f8f8f8;text-align:left}input[type=text],input[type=number],select{height:40px}textarea{min-height:120px;resize:vertical;line-height:1.4}input:focus,textarea:focus,select:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}button{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:.3s}button:hover{background:#0056b3;transform:translateY(-2px)}.toggle-group{display:flex;align-items:center;gap:20px}.toggle-item{display:flex;align-items:center;gap:10px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background-color:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background-color:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.options-container{display:flex;flex-direction:column;gap:12px}.options{width:100%}.field-size-controls{display:flex;align-items:center;gap:12px}.size-input{width:110px;text-align:center}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.design-footer .btn{background:#007bff;color:#fff;padding:10px 18px;border-radius:6px;font-size:15px;transition:.3s}.design-footer .btn:hover{background:#0056b3}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.container{width:100%;max-width:500px;margin:0 auto;background-color:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.tabs{display:flex;background-color:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background-color:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:77vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}.document-settings{border:1px solid #dbe4ef;background:#f8fafc;border-radius:6px;padding:10px;margin-bottom:14px}.document-settings-title{font-size:14px;font-weight:700;color:#1f2937;margin-bottom:10px}.document-color-row{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center}.document-color-row input[type=color]{width:44px;height:40px;padding:3px}.document-toggle label{align-items:center;color:#334155}.document-subpanel{border-left:3px solid #2c6dd5;padding-left:10px;margin-bottom:12px}.document-help{color:#64748b;font-size:12px;line-height:1.4;margin:-4px 0 10px}.style-builder{border:1px solid #dbe4ef;background:#fff;border-radius:6px;padding:12px;margin-bottom:14px}.style-builder-title{font-size:14px;font-weight:700;color:#1f2937;margin-bottom:10px}.style-section-title{font-size:12px;font-weight:700;color:#334155;text-transform:uppercase;letter-spacing:0;border-top:1px solid #e5e7eb;padding-top:12px;margin:14px 0 10px}.style-section-title:first-of-type{border-top:0;padding-top:0}.style-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.style-grid .form-group{min-width:0}.style-color-row{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center}.style-color-row input[type=color],.style-builder input[type=color]{width:44px;height:40px;padding:3px}.style-four-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.style-four-grid span{display:block;color:#64748b;font-size:11px;margin-bottom:4px}.style-four-grid input{width:100%}.style-toggle-row{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:12px}.style-check-row{display:inline-flex;align-items:center;gap:8px;margin:0 0 12px;color:#334155;font-size:13px}.style-check-row input{width:auto}.style-nested{border-left:3px solid #2c6dd5;padding-left:10px;margin-bottom:12px}label{display:flex;gap:16px;margin-bottom:8px;color:#666;font-size:14px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],textarea,select{width:100%;padding:10px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;font-size:14px}.select-container{position:relative;width:100%}.dropdown-arrow{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.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}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.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-color:#4caf50}.view-icon{background-color:#2196f3}.delete-icon{background-color:#f44336}.color-picker-row{display:flex;align-items:center}.color-picker-container{display:flex;align-items:center;border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box{width:30px;border:none;height:30px}.hex-label{color:#999;margin-right:5px}.hex-input{width:100px}.divider{border-top:1px dashed #ddd;margin:20px 0}.button-container{display:flex;padding:15px;background-color:#f9f9f9;border-top:1px solid #eee}.cancel-btn,.save-btn{padding:12px;border:none;border-radius:4px;cursor:pointer;font-weight:700}.cancel-btn{flex:1;background-color:#fff;color:#666;border:1px solid #ddd}.cancel-btn:hover{background-color:#0052cc!important;color:#fff!important}.save-btn{flex:1;background-color:#0052cc;color:#fff;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;padding:8px}textarea{width:100%;min-height:55px;padding:8px;border:1px solid #ccc;border-radius:5px;font-size:14px;resize:vertical}.flex-container{display:flex;align-items:center;gap:12px;margin-bottom:1rem}.input-box-field select{background-color:#28343e;color:#fff;border:none;padding:10px 14px;border-radius:6px;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;font-size:14px;font-family:inherit}.input-box-field{position:relative}.input-box-field select::-ms-expand{display:none}.input-box-field:after{content:\"\\25bc\";position:absolute;top:50%;right:10px;transform:translateY(-50%);color:#1c1b1f;pointer-events:none;font-size:10px}.color-selector input[type=color]{width:40px;height:40px;border-radius:4px;background:none;cursor:pointer}.hex-input-container{display:flex;font-size:12px;gap:20px;color:#b0b0b0;align-items:center}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input-container input[type=text]{padding:10px 12px;border:1px solid #d1d1d1;border-radius:6px;font-size:14px;width:120px;color:#28343e}input{width:auto}@media screen and (max-width:1099px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:768px){.container{height:calc(100vh - 20px) h;min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}@media screen and (max-width:768px){.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}.logo-icon{width:20px;height:20px;display:flex;width:35px;justify-content:center;background-color:#d0d9ff;border-radius:4px}.link-icon{background-color:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:background-color .3s,transform .2s}.link-icon:hover{background-color:#d0e5ff}.link-icon:active{background-color:#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}.drag-handle{cursor:grab}.option-items:active{opacity:.5}.style-toggle-header{display:flex;justify-content:space-between;align-items:center;background-color:#f8f8f8;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;margin-bottom:6px}.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-color:#2c6dd5}.flex-container{display:flex;gap:8px;align-items:center}.size-select{transition:width .3s ease;width:100%;max-width:200px}.flex-container.custom-active .size-select{max-width:100px}.size-input{width:60px}.margin-inputs{display:flex;gap:15px;margin-top:5px}.margin-inputs>div{display:flex;flex-direction:column;width:60px}.margin-inputs label{font-size:12px;margin-bottom:3px}.pdf-actions-container{width:100%;max-width:400px;padding:10px}.pdf-action-card{background-color:#fff;border-radius:6px;padding:9px;box-shadow:0 2px 6px #0000001a;display:flex;flex-direction:column;gap:10px}.pdf-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px;background-color:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s}.pdf-btn:hover{background-color:#5a6268}\n"], dependencies: [{ 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: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NxtSearchBox, selector: "nxt-search-box", inputs: ["placeHolderText", "question", "apiMeta", "id", "readOnly", "mode", "from", "value", "onlyView", "rowData"], outputs: ["searchValueChange"] }, { 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }, { kind: "component", type: FormulaInputComponent, selector: "app-formula-input", inputs: ["attributes", "initialFormula"], outputs: ["formulaChange", "formulaValidation"] }] });
|
|
62394
63517
|
}
|
|
62395
63518
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfPropertiesComponent, decorators: [{
|
|
62396
63519
|
type: Component,
|
|
62397
|
-
args: [{ selector: 'app-pdf-properties', standalone: true, imports: [CommonModule, FormsModule, NxtSearchBox, ImageCropperComponent, NxtCustomTranslatePipe, FormulaInputComponent], template: "<!-- - Field and Element Properties -->\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n {{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n {{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n {{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <!-- Element Properrties -->\n <!-- Select element type show -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type] as props\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.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 <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\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 <!-- SKS28MAR25 search pdf specific for pdf element -->\n <div *ngIf=\"selectedElement?.type === 'Pdf'\">\n <label class=\"text-sm\">{{ 'SEARCHPDF' | nxtCustomTranslate : 'Search Pdf' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [readOnly]=\"selectedElement.isReadOnly\" [apiMeta]=\"bookSubtext\"\n [placeHolderText]=\"selectedElement.question || ''\"\n [mode]=\"'edit'\"\n (searchValueChange)=\"childEventCapture($event)\">\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>{{ 'ENDPOINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>{{ 'DEFAULTFIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label \n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\"></option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n\n </div>\n <!-- SKS20MAR25 Subquestion Type -->\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 type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n 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 <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- Change key width -->\n <div *ngIf=\"prop.type === 'fieldSize'\" [ngClass]=\"{'flex-container': true, 'custom-active': selectedElement?.width !== '*' && selectedElement?.width !== 'auto'}\">\n <select\n class=\"size-select\"\n [value]=\"selectedElement?.width === '*' ? 'Default' : selectedElement?.width === 'auto' ? 'Auto' : 'Custom'\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom') : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' ) ) : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' )\">\n <option value=\"Default\">{{ 'DEFAULT' | nxtCustomTranslate : 'Default' }}</option>\n <option value=\"Auto\">{{ 'AUTO' | nxtCustomTranslate : 'Auto' }}</option>\n <option value=\"Custom\">{{ 'CUSTOM' | nxtCustomTranslate : 'Custom' }}</option>\n </select>\n \n <input\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== '*' && selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== 'auto'\"\n type=\"number\"\n class=\"size-input\"\n min=\"1\"\n max=\"100\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) ) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber)\"\n />\n </div> \n\n <!-- Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- Show elements ID -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\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 }}</div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n </div>\n\n <!-- - handled options with UUID -->\n <div *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" \n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n \n <!-- Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (change)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.checked) ) : setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : 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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div class=\"flex-container\">\n <!-- Type select -->\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.labelPath | nxtCustomTranslate : option.label }}\n </option>\n </select>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Type number -->\n <div *ngIf=\"prop.type === 'number'\">\n <input type=\"number\" min=\"1\" max=\"100\" step=\"1\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n <!-- margin: [0, 10, 0, 0] // [ left, top, right, bottom ] -->\n <div *ngIf=\"prop.type === 'marginPicker'\">\n <div class=\"margin-inputs\">\n <div>\n <label>Right</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[0] : getValueByPath(prop.key)?.[0] ) : getValueByPath(prop.key)?.[0])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.0', $event) : setValueByPath(prop.key+'.0', $event.target.value) ) : setValueByPath(prop.key+'.0', $event.target.value)\" />\n </div>\n <div>\n <label>Top</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[1] : getValueByPath(prop.key)?.[1] ) : getValueByPath(prop.key)?.[1])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.1', $event) : setValueByPath(prop.key+'.1', $event.target.value) ) : setValueByPath(prop.key+'.1', $event.target.value)\" />\n </div>\n <div>\n <label>Left</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[2] : getValueByPath(prop.key)?.[2] ) : getValueByPath(prop.key)?.[2])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.2', $event) : setValueByPath(prop.key+'.2', $event.target.value) ) : setValueByPath(prop.key+'.2', $event.target.value)\" />\n </div>\n <div>\n <label>Bottom</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[3] : getValueByPath(prop.key)?.[3] ) : getValueByPath(prop.key)?.[3])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.3', $event) : setValueByPath(prop.key+'.3', $event.target.value) ) : setValueByPath(prop.key+'.3', $event.target.value)\" />\n </div>\n </div>\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Default Save Button -->\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n </div>\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap\";*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.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}.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}label{font-size:14px;font-weight:500;color:#444;margin-bottom:5px;display:block}input[type=text],input[type=number],select{width:100%;height:40px;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:.3s;background:#f8f8f8;text-align:left}input:focus,select:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}button{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:.3s}button:hover{background:#0056b3;transform:translateY(-2px)}.toggle-group{display:flex;align-items:center;gap:20px}.toggle-item{display:flex;align-items:center;gap:10px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background-color:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background-color:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.options-container{display:flex;flex-direction:column;gap:12px}.options{width:100%}.field-size-controls{display:flex;align-items:center;gap:12px}.size-input{width:110px;text-align:center}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.design-footer .btn{background:#007bff;color:#fff;padding:10px 18px;border-radius:6px;font-size:15px;transition:.3s}.design-footer .btn:hover{background:#0056b3}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.container{width:100%;max-width:500px;margin:0 auto;background-color:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.tabs{display:flex;background-color:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background-color:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:77vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:flex;gap:16px;margin-bottom:8px;color:#666;font-size:14px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],select{width:100%;padding:10px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;font-size:14px}.select-container{position:relative;width:100%}.dropdown-arrow{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.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}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.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-color:#4caf50}.view-icon{background-color:#2196f3}.delete-icon{background-color:#f44336}.color-picker-row{display:flex;align-items:center}.color-picker-container{display:flex;align-items:center;border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box{width:30px;border:none;height:30px}.hex-label{color:#999;margin-right:5px}.hex-input{width:100px}.divider{border-top:1px dashed #ddd;margin:20px 0}.button-container{display:flex;padding:15px;background-color:#f9f9f9;border-top:1px solid #eee}.cancel-btn,.save-btn{padding:12px;border:none;border-radius:4px;cursor:pointer;font-weight:700}.cancel-btn{flex:1;background-color:#fff;color:#666;border:1px solid #ddd}.cancel-btn:hover{background-color:#0052cc!important;color:#fff!important}.save-btn{flex:1;background-color:#0052cc;color:#fff;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;padding:8px}textarea{width:100%;min-height:55px;padding:8px;border:1px solid #ccc;border-radius:5px;font-size:14px;resize:vertical}.flex-container{display:flex;align-items:center;gap:12px;margin-bottom:1rem}.input-box-field select{background-color:#28343e;color:#fff;border:none;padding:10px 14px;border-radius:6px;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;font-size:14px;font-family:inherit}.input-box-field{position:relative}.input-box-field select::-ms-expand{display:none}.input-box-field:after{content:\"\\25bc\";position:absolute;top:50%;right:10px;transform:translateY(-50%);color:#1c1b1f;pointer-events:none;font-size:10px}.color-selector input[type=color]{width:40px;height:40px;border-radius:4px;background:none;cursor:pointer}.hex-input-container{display:flex;font-size:12px;gap:20px;color:#b0b0b0;align-items:center}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input-container input[type=text]{padding:10px 12px;border:1px solid #d1d1d1;border-radius:6px;font-size:14px;width:120px;color:#28343e}input{width:auto}@media screen and (max-width:1099px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:768px){.container{height:calc(100vh - 20px) h;min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}@media screen and (max-width:768px){.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}.logo-icon{width:20px;height:20px;display:flex;width:35px;justify-content:center;background-color:#d0d9ff;border-radius:4px}.link-icon{background-color:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:background-color .3s,transform .2s}.link-icon:hover{background-color:#d0e5ff}.link-icon:active{background-color:#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}.drag-handle{cursor:grab}.option-items:active{opacity:.5}.style-toggle-header{display:flex;justify-content:space-between;align-items:center;background-color:#f8f8f8;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;margin-bottom:6px}.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-color:#2c6dd5}.flex-container{display:flex;gap:8px;align-items:center}.size-select{transition:width .3s ease;width:100%;max-width:200px}.flex-container.custom-active .size-select{max-width:100px}.size-input{width:60px}.margin-inputs{display:flex;gap:15px;margin-top:5px}.margin-inputs>div{display:flex;flex-direction:column;width:60px}.margin-inputs label{font-size:12px;margin-bottom:3px}.pdf-actions-container{width:100%;max-width:400px;padding:10px}.pdf-action-card{background-color:#fff;border-radius:6px;padding:9px;box-shadow:0 2px 6px #0000001a;display:flex;flex-direction:column;gap:10px}.pdf-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px;background-color:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s}.pdf-btn:hover{background-color:#5a6268}\n"] }]
|
|
63520
|
+
args: [{ selector: 'app-pdf-properties', standalone: true, imports: [CommonModule, FormsModule, NxtSearchBox, ImageCropperComponent, NxtCustomTranslatePipe, FormulaInputComponent], template: "<!-- - Field and Element Properties -->\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n {{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n {{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n {{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <div *ngIf=\"headerSelect\" class=\"document-settings\">\n <div class=\"document-settings-title\">Document Canvas</div>\n <div class=\"form-group\">\n <label>Page Size</label>\n <select [value]=\"getPdfSetting('pageSize', 'A4')\" (change)=\"onPdfSettingInput('pageSize', $event)\">\n <option value=\"A4\">A4</option>\n <option value=\"LETTER\">Letter</option>\n <option value=\"LEGAL\">Legal</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Orientation</label>\n <select [value]=\"getPdfSetting('pageOrientation', 'portrait')\" (change)=\"onPdfSettingInput('pageOrientation', $event)\">\n <option value=\"portrait\">Portrait</option>\n <option value=\"landscape\">Landscape</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Background Color</label>\n <div class=\"document-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Page Margins</label>\n <div class=\"margin-inputs\">\n <div><label>Left</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.0', 40)\" (change)=\"onPdfSettingInput('pageMargins.0', $event)\" /></div>\n <div><label>Top</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.1', 40)\" (change)=\"onPdfSettingInput('pageMargins.1', $event)\" /></div>\n <div><label>Right</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.2', 40)\" (change)=\"onPdfSettingInput('pageMargins.2', $event)\" /></div>\n <div><label>Bottom</label><input type=\"number\" [value]=\"getPdfSetting('pageMargins.3', 80)\" (change)=\"onPdfSettingInput('pageMargins.3', $event)\" /></div>\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.enabled', false)\" (change)=\"onPdfSettingInput('header.enabled', $event)\" />\n Running Header\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('header.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Show Header</label>\n <select [value]=\"getPdfSetting('header.showOn', 'all')\" (change)=\"onPdfSettingInput('header.showOn', $event)\">\n <option value=\"all\">All Pages</option>\n <option value=\"first\">First Page Only</option>\n <option value=\"notFirst\">Skip First Page</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Header Left</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.leftText', '')\" (input)=\"onPdfSettingInput('header.leftText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Center</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.centerText', '')\" (input)=\"onPdfSettingInput('header.centerText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Right</label>\n <input type=\"text\" [value]=\"getPdfSetting('header.rightText', '')\" (input)=\"onPdfSettingInput('header.rightText', $event)\" />\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.bottomBorder', false)\" (change)=\"onPdfSettingInput('header.bottomBorder', $event)\" />\n Bottom Line\n </label>\n </div>\n <div class=\"form-group\">\n <label>Header Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('header.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('header.borderColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('watermark.enabled', false)\" (change)=\"onPdfSettingInput('watermark.enabled', $event)\" />\n Watermark\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('watermark.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Watermark Text</label>\n <input type=\"text\" [value]=\"getPdfSetting('watermark.text', '')\" (input)=\"onPdfSettingInput('watermark.text', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Watermark Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('watermark.color', '#9ca3af')\" (change)=\"onPdfSettingInput('watermark.color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getPdfSetting('watermark.opacity', 0.16)\" (change)=\"onPdfSettingInput('watermark.opacity', $event)\" />\n </div>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.enabled', false)\" (change)=\"onPdfSettingInput('footer.enabled', $event)\" />\n Footer\n </label>\n </div>\n <div *ngIf=\"getPdfSetting('footer.enabled', false)\" class=\"document-subpanel\">\n <div class=\"form-group\">\n <label>Show Footer</label>\n <select [value]=\"getPdfSetting('footer.showOn', 'last')\" (change)=\"onPdfSettingInput('footer.showOn', $event)\">\n <option value=\"last\">Last Page Only</option>\n <option value=\"all\">All Pages</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Footer Content</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.text', '')\" (input)=\"onPdfSettingInput('footer.text', $event)\" />\n </div>\n <div class=\"document-help\">Use {{'{{currentPage}}'}} and {{'{{pageCount}}'}} for page numbers.</div>\n <div class=\"form-group\">\n <label>Footer Left</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.leftText', '')\" (input)=\"onPdfSettingInput('footer.leftText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Footer Center</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.centerText', '')\" (input)=\"onPdfSettingInput('footer.centerText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Footer Right</label>\n <input type=\"text\" [value]=\"getPdfSetting('footer.rightText', '')\" (input)=\"onPdfSettingInput('footer.rightText', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Alignment</label>\n <select [value]=\"getPdfSetting('footer.alignment', 'center')\" (change)=\"onPdfSettingInput('footer.alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n <div class=\"form-group document-toggle\">\n <label>\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.topBorder', false)\" (change)=\"onPdfSettingInput('footer.topBorder', $event)\" />\n Top Line\n </label>\n </div>\n <div class=\"form-group\">\n <label>Footer Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('footer.borderColor', $event)\" />\n </div>\n </div>\n </div>\n <!-- Element Properrties -->\n <!-- Select element type show -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type] as props\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'image'\">\n <div style=\"height: 200px;\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.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 <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\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 <!-- SKS28MAR25 search pdf specific for pdf element -->\n <div *ngIf=\"selectedElement?.type === 'Pdf'\">\n <label class=\"text-sm\">{{ 'SEARCHPDF' | nxtCustomTranslate : 'Search Pdf' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [readOnly]=\"selectedElement.isReadOnly\" [apiMeta]=\"bookSubtext\"\n [placeHolderText]=\"selectedElement.question || ''\"\n [mode]=\"'edit'\"\n (searchValueChange)=\"childEventCapture($event)\">\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>{{ 'ENDPOINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>{{ 'DEFAULTFIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label \n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <textarea *ngIf=\"prop.type === 'textarea'\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (input)=\"selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </textarea>\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\"></option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <select *ngIf=\"prop.type === 'select' && prop.key !== 'supportType' && prop.key !== 'lineStyle'\" [value]=\"getValueByPath(prop.key)\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.labelPath | nxtCustomTranslate : option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n\n </div>\n <!-- SKS20MAR25 Subquestion Type -->\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 type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n 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 <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- Change key width -->\n <div *ngIf=\"prop.type === 'fieldSize'\" [ngClass]=\"{'flex-container': true, 'custom-active': selectedElement?.width !== '*' && selectedElement?.width !== 'auto'}\">\n <select\n class=\"size-select\"\n [value]=\"selectedElement?.width === '*' ? 'Default' : selectedElement?.width === 'auto' ? 'Auto' : 'Custom'\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom') : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' ) ) : onWidthSelect( $event.target.value === 'Default' ? '*' : $event.target.value === 'Auto' ? 'auto' : 'custom' )\">\n <option value=\"Default\">{{ 'DEFAULT' | nxtCustomTranslate : 'Default' }}</option>\n <option value=\"Auto\">{{ 'AUTO' | nxtCustomTranslate : 'Auto' }}</option>\n <option value=\"Custom\">{{ 'CUSTOM' | nxtCustomTranslate : 'Custom' }}</option>\n </select>\n \n <input\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== '*' && selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key) !== 'auto'\"\n type=\"number\"\n class=\"size-input\"\n min=\"1\"\n max=\"100\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber) ) : setValueByPath(prop.key, $event.target.valueAsNumber < 1 ? 1 :\n $event.target.valueAsNumber > 100 ? 100 :\n $event.target.valueAsNumber)\"\n />\n </div> \n\n <!-- Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- Show elements ID -->\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\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 }}</div>\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n </div>\n\n <!-- - handled options with UUID -->\n <div *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? pdf.title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <textarea *ngIf=\"prop.type === 'textarea'\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (input)=\"selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </textarea>\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" \n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n \n <!-- Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\" (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (change)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.checked) ) : setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : 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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <!-- SKS26MAY26 builder stype tool -->\n <div *ngIf=\"headerSelect\" class=\"style-builder\">\n <div class=\"style-builder-title\">Document Style Builder</div>\n <div class=\"style-section-title\">Page</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Page Size</label>\n <select [value]=\"getPdfSetting('pageSize', 'A4')\" (change)=\"onPdfSettingInput('pageSize', $event)\">\n <option value=\"A4\">A4</option>\n <option value=\"LETTER\">Letter</option>\n <option value=\"LEGAL\">Legal</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Orientation</label>\n <select [value]=\"getPdfSetting('pageOrientation', 'portrait')\" (change)=\"onPdfSettingInput('pageOrientation', $event)\">\n <option value=\"portrait\">Portrait</option>\n <option value=\"landscape\">Landscape</option>\n </select>\n </div>\n </div>\n <div class=\"form-group\">\n <label>Background</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('backgroundColor', '#ffffff')\" (change)=\"onPdfSettingInput('backgroundColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Page Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.0', 40)\" (change)=\"onPdfSettingInput('pageMargins.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.1', 40)\" (change)=\"onPdfSettingInput('pageMargins.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.2', 40)\" (change)=\"onPdfSettingInput('pageMargins.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('pageMargins.3', 80)\" (change)=\"onPdfSettingInput('pageMargins.3', $event)\" /></div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Running Header</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.enabled', false)\" (change)=\"onPdfSettingInput('header.enabled', $event)\" />\n <span>Enable header</span>\n </label>\n <div *ngIf=\"getPdfSetting('header.enabled', false)\" class=\"style-nested\">\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Show On</label>\n <select [value]=\"getPdfSetting('header.showOn', 'all')\" (change)=\"onPdfSettingInput('header.showOn', $event)\">\n <option value=\"all\">All Pages</option>\n <option value=\"first\">First Page Only</option>\n <option value=\"notFirst\">Skip First Page</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('header.fontSize', 9)\" (change)=\"onPdfSettingInput('header.fontSize', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getPdfSetting('header.color', '#666666')\" (change)=\"onPdfSettingInput('header.color', $event)\" />\n <input type=\"text\" [value]=\"getPdfSetting('header.color', '#666666')\" (change)=\"onPdfSettingInput('header.color', $event)\" />\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\"><label>Left</label><input type=\"text\" [value]=\"getPdfSetting('header.leftText', '')\" (input)=\"onPdfSettingInput('header.leftText', $event)\" /></div>\n <div class=\"form-group\"><label>Center</label><input type=\"text\" [value]=\"getPdfSetting('header.centerText', '')\" (input)=\"onPdfSettingInput('header.centerText', $event)\" /></div>\n <div class=\"form-group\"><label>Right</label><input type=\"text\" [value]=\"getPdfSetting('header.rightText', '')\" (input)=\"onPdfSettingInput('header.rightText', $event)\" /></div>\n </div>\n <div class=\"form-group\">\n <label>Header Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.0', 40)\" (change)=\"onPdfSettingInput('header.margin.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.1', 20)\" (change)=\"onPdfSettingInput('header.margin.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.2', 40)\" (change)=\"onPdfSettingInput('header.margin.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('header.margin.3', 0)\" (change)=\"onPdfSettingInput('header.margin.3', $event)\" /></div>\n </div>\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('header.bottomBorder', false)\" (change)=\"onPdfSettingInput('header.bottomBorder', $event)\" />\n <span>Bottom line</span>\n </label>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('header.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('header.borderColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Width</label>\n <input type=\"number\" min=\"0\" [value]=\"getPdfSetting('header.borderWidth', 1)\" (change)=\"onPdfSettingInput('header.borderWidth', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Watermark</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('watermark.enabled', false)\" (change)=\"onPdfSettingInput('watermark.enabled', $event)\" />\n <span>Enable watermark</span>\n </label>\n <div *ngIf=\"getPdfSetting('watermark.enabled', false)\" class=\"style-nested\">\n <div class=\"form-group\">\n <label>Text</label>\n <input type=\"text\" [value]=\"getPdfSetting('watermark.text', '')\" (input)=\"onPdfSettingInput('watermark.text', $event)\" />\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('watermark.color', '#9ca3af')\" (change)=\"onPdfSettingInput('watermark.color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getPdfSetting('watermark.opacity', 0.16)\" (change)=\"onPdfSettingInput('watermark.opacity', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('watermark.fontSize', 64)\" (change)=\"onPdfSettingInput('watermark.fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Angle</label>\n <input type=\"number\" [value]=\"getPdfSetting('watermark.angle', -32)\" (change)=\"onPdfSettingInput('watermark.angle', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Footer</div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.enabled', false)\" (change)=\"onPdfSettingInput('footer.enabled', $event)\" />\n <span>Enable footer</span>\n </label>\n <div *ngIf=\"getPdfSetting('footer.enabled', false)\" class=\"style-nested\">\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Show On</label>\n <select [value]=\"getPdfSetting('footer.showOn', 'last')\" (change)=\"onPdfSettingInput('footer.showOn', $event)\">\n <option value=\"last\">Last Page Only</option>\n <option value=\"all\">All Pages</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Alignment</label>\n <select [value]=\"getPdfSetting('footer.alignment', 'center')\" (change)=\"onPdfSettingInput('footer.alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\"><label>Left</label><input type=\"text\" [value]=\"getPdfSetting('footer.leftText', '')\" (input)=\"onPdfSettingInput('footer.leftText', $event)\" /></div>\n <div class=\"form-group\"><label>Center</label><input type=\"text\" [value]=\"getPdfSetting('footer.centerText', '')\" (input)=\"onPdfSettingInput('footer.centerText', $event)\" /></div>\n <div class=\"form-group\"><label>Right</label><input type=\"text\" [value]=\"getPdfSetting('footer.rightText', '')\" (input)=\"onPdfSettingInput('footer.rightText', $event)\" /></div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getPdfSetting('footer.fontSize', 9)\" (change)=\"onPdfSettingInput('footer.fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.color', '#666666')\" (change)=\"onPdfSettingInput('footer.color', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Footer Margins</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.0', 40)\" (change)=\"onPdfSettingInput('footer.margin.0', $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.1', 12)\" (change)=\"onPdfSettingInput('footer.margin.1', $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.2', 40)\" (change)=\"onPdfSettingInput('footer.margin.2', $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getPdfSetting('footer.margin.3', 0)\" (change)=\"onPdfSettingInput('footer.margin.3', $event)\" /></div>\n </div>\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getPdfSetting('footer.topBorder', false)\" (change)=\"onPdfSettingInput('footer.topBorder', $event)\" />\n <span>Top line</span>\n </label>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Line Color</label>\n <input type=\"color\" [value]=\"getPdfSetting('footer.borderColor', '#2f9e44')\" (change)=\"onPdfSettingInput('footer.borderColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Width</label>\n <input type=\"number\" min=\"0\" [value]=\"getPdfSetting('footer.borderWidth', 1)\" (change)=\"onPdfSettingInput('footer.borderWidth', $event)\" />\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!headerSelect && selectedElement\" class=\"style-builder\">\n <div class=\"style-builder-title\">{{ getStyleBuilderTitle() }}</div>\n\n <div class=\"style-section-title\">Typography</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Font</label>\n <select [value]=\"getActiveStyleValue('font', 'Helvetica Neue')\" (change)=\"onActiveStyleInput('font', $event)\">\n <option value=\"Helvetica Neue\">Helvetica Neue</option>\n <option value=\"Arial\">Arial</option>\n <option value=\"Times New Roman\">Times New Roman</option>\n <option value=\"Roboto\">Roboto</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Font Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('fontSize', 12)\" (change)=\"onActiveStyleInput('fontSize', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Line Height</label>\n <input type=\"number\" min=\"0.5\" step=\"0.1\" [value]=\"getActiveStyleValue('lineHeight', 1.2)\" (change)=\"onActiveStyleInput('lineHeight', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Letter Space</label>\n <input type=\"number\" step=\"0.5\" [value]=\"getActiveStyleValue('characterSpacing', 0)\" (change)=\"onActiveStyleInput('characterSpacing', $event)\" />\n </div>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Weight</label>\n <select [value]=\"getActiveStyleValue('fontWeight', '400')\" (change)=\"onActiveStyleInput('fontWeight', $event)\">\n <option value=\"400\">400 Normal</option>\n <option value=\"500\">500 Medium</option>\n <option value=\"600\">600 Semi Bold</option>\n <option value=\"700\">700 Bold</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Align</label>\n <select [value]=\"getActiveStyleValue('alignment', 'left')\" (change)=\"onActiveStyleInput('alignment', $event)\">\n <option value=\"left\">Left</option>\n <option value=\"center\">Center</option>\n <option value=\"right\">Right</option>\n <option value=\"justify\">Justify</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>Decoration</label>\n <select [value]=\"getActiveStyleValue('decoration', '')\" (change)=\"onActiveStyleInput('decoration', $event)\">\n <option value=\"\">None</option>\n <option value=\"underline\">Underline</option>\n <option value=\"lineThrough\">Line Through</option>\n <option value=\"overline\">Overline</option>\n </select>\n </div>\n </div>\n <div class=\"style-toggle-row\">\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('bold', false)\" (change)=\"onActiveStyleInput('bold', $event)\" />\n <span>Bold</span>\n </label>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('italic', false)\" (change)=\"onActiveStyleInput('italic', $event)\" />\n <span>Italic</span>\n </label>\n </div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Text Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('color', '#000000')\" (change)=\"onActiveStyleInput('color', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('color', '#000000')\" (change)=\"onActiveStyleInput('color', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Background</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('fillColor', '#ffffff')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('fillColor', '#ffffff')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n </div>\n </div>\n </div>\n\n <div class=\"style-section-title\">Spacing</div>\n <div class=\"form-group\">\n <label>Margin</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getActiveMargin(0)\" (change)=\"onActiveMarginInput(0, $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getActiveMargin(1)\" (change)=\"onActiveMarginInput(1, $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getActiveMargin(2)\" (change)=\"onActiveMarginInput(2, $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getActiveMargin(3)\" (change)=\"onActiveMarginInput(3, $event)\" /></div>\n </div>\n </div>\n <div class=\"form-group\" *ngIf=\"selectedElement?.type === 'Section' || selectedElement?.type === 'Note'\">\n <label>Inner Padding</label>\n <div class=\"style-four-grid\">\n <div><span>Left</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 0, 8)\" (change)=\"onElementArrayInput('innerMargin', 0, $event)\" /></div>\n <div><span>Top</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 1, 6)\" (change)=\"onElementArrayInput('innerMargin', 1, $event)\" /></div>\n <div><span>Right</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 2, 8)\" (change)=\"onElementArrayInput('innerMargin', 2, $event)\" /></div>\n <div><span>Bottom</span><input type=\"number\" [value]=\"getElementArrayValue('innerMargin', 3, 6)\" (change)=\"onElementArrayInput('innerMargin', 3, $event)\" /></div>\n </div>\n </div>\n\n <div class=\"style-section-title\">PDF Box Style</div>\n <div class=\"style-grid\">\n <div class=\"form-group\">\n <label>Border Color</label>\n <div class=\"style-color-row\">\n <input type=\"color\" [value]=\"getActiveStyleValue('borderColor', '#2f9e44')\" (change)=\"onActiveStyleInput('borderColor', $event)\" />\n <input type=\"text\" [value]=\"getActiveStyleValue('borderColor', '#2f9e44')\" (change)=\"onActiveStyleInput('borderColor', $event)\" />\n </div>\n </div>\n <div class=\"form-group\">\n <label>Opacity</label>\n <input type=\"number\" min=\"0\" max=\"1\" step=\"0.05\" [value]=\"getActiveStyleValue('opacity', 1)\" (change)=\"onActiveStyleInput('opacity', $event)\" />\n </div>\n </div>\n\n <div *ngIf=\"selectedElement?.type !== 'Table' || !selectColumn\" class=\"style-section-title\">Label Style</div>\n <div *ngIf=\"selectedElement?.type !== 'Table' || !selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Label Color</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('labelColor', '#222222')\" (change)=\"onActiveStyleInput('labelColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Label Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('labelFontSize', getActiveStyleValue('fontSize', 12))\" (change)=\"onActiveStyleInput('labelFontSize', $event)\" />\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"getActiveStyleValue('labelBold', true)\" (change)=\"onActiveStyleInput('labelBold', $event)\" />\n <span>Bold label</span>\n </label>\n </div>\n\n <div *ngIf=\"selectedElement?.type === 'RichText' || selectedElement?.type === 'text'\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Heading Color</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('headingColor', '#2f9e44')\" (change)=\"onActiveStyleInput('headingColor', $event)\" />\n </div>\n <div class=\"form-group\" *ngIf=\"selectedElement?.type === 'text'\">\n <label>Heading Size</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('headingFontSize', getActiveStyleValue('fontSize', 12))\" (change)=\"onActiveStyleInput('headingFontSize', $event)\" />\n </div>\n <label class=\"style-check-row\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.type === 'RichText' ? selectedElement?.headingFirstLine !== false : selectedElement?.headingFirstLine === true\" (change)=\"setValueByPath('headingFirstLine', $event.target.checked)\" />\n <span>First line heading</span>\n </label>\n </div>\n\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-section-title\">Table Column</div>\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Header Fill</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('fillColor', '#f1f5f9')\" (change)=\"onActiveStyleInput('fillColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Header Text</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('color', '#111827')\" (change)=\"onActiveStyleInput('color', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Cell Fill</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('cellFillColor', '#ffffff')\" (change)=\"onActiveStyleInput('cellFillColor', $event)\" />\n </div>\n <div class=\"form-group\">\n <label>Cell Text</label>\n <input type=\"color\" [value]=\"getActiveStyleValue('cellColor', '#374151')\" (change)=\"onActiveStyleInput('cellColor', $event)\" />\n </div>\n </div>\n <div *ngIf=\"selectedElement?.type === 'Table' && selectColumn\" class=\"style-grid\">\n <div class=\"form-group\">\n <label>Column Width</label>\n <select [value]=\"getActiveColumnWidthMode()\" (change)=\"onActiveColumnWidthModeChange($event)\">\n <option value=\"*\">Default</option>\n <option value=\"auto\">Auto</option>\n <option value=\"custom\">Custom</option>\n </select>\n </div>\n <div class=\"form-group\" *ngIf=\"getActiveColumnWidthMode() === 'custom'\">\n <label>Width</label>\n <input type=\"number\" min=\"1\" [value]=\"getActiveStyleValue('width', 80)\" (change)=\"onActiveStyleInput('width', $event)\" />\n </div>\n </div>\n </div>\n\n <div *ngIf=\"elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type]\">\n <ng-container *ngFor=\"let prop of elementProperties[selectedElement?.type === 'Table' && selectColumn !== '' && selectColumn !== null ? 'TableColumn' : selectedElement?.type].appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div class=\"flex-container\">\n <!-- Type select -->\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.labelPath | nxtCustomTranslate : option.label }}\n </option>\n </select>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Type number -->\n <div *ngIf=\"prop.type === 'number'\">\n <input type=\"number\" min=\"1\" max=\"100\" step=\"1\"\n [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [value]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value)\" />\n </div>\n <!-- margin: [0, 10, 0, 0] // [ left, top, right, bottom ] -->\n <div *ngIf=\"prop.type === 'marginPicker'\">\n <div class=\"margin-inputs\">\n <div>\n <label>Right</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[0] : getValueByPath(prop.key)?.[0] ) : getValueByPath(prop.key)?.[0])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.0', $event) : setValueByPath(prop.key+'.0', $event.target.value) ) : setValueByPath(prop.key+'.0', $event.target.value)\" />\n </div>\n <div>\n <label>Top</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[1] : getValueByPath(prop.key)?.[1] ) : getValueByPath(prop.key)?.[1])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.1', $event) : setValueByPath(prop.key+'.1', $event.target.value) ) : setValueByPath(prop.key+'.1', $event.target.value)\" />\n </div>\n <div>\n <label>Left</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[2] : getValueByPath(prop.key)?.[2] ) : getValueByPath(prop.key)?.[2])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.2', $event) : setValueByPath(prop.key+'.2', $event.target.value) ) : setValueByPath(prop.key+'.2', $event.target.value)\" />\n </div>\n <div>\n <label>Bottom</label>\n <input type=\"number\" [value]=\"(selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key )?.[3] : getValueByPath(prop.key)?.[3] ) : getValueByPath(prop.key)?.[3])\"\n (change)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key+'.3', $event) : setValueByPath(prop.key+'.3', $event.target.value) ) : setValueByPath(prop.key+'.3', $event.target.value)\" />\n </div>\n </div>\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 ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key)\"\n (formulaChange)=\"selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event) ) : setValueByPath(prop.key, $event)\">\n </app-formula-input>\n </div>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Default Save Button -->\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n </div>\n</div>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap\";*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.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}.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}label{font-size:14px;font-weight:500;color:#444;margin-bottom:5px;display:block}input[type=text],input[type=number],textarea,select{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:.3s;background:#f8f8f8;text-align:left}input[type=text],input[type=number],select{height:40px}textarea{min-height:120px;resize:vertical;line-height:1.4}input:focus,textarea:focus,select:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}button{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:.3s}button:hover{background:#0056b3;transform:translateY(-2px)}.toggle-group{display:flex;align-items:center;gap:20px}.toggle-item{display:flex;align-items:center;gap:10px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background-color:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background-color:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.options-container{display:flex;flex-direction:column;gap:12px}.options{width:100%}.field-size-controls{display:flex;align-items:center;gap:12px}.size-input{width:110px;text-align:center}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.design-footer .btn{background:#007bff;color:#fff;padding:10px 18px;border-radius:6px;font-size:15px;transition:.3s}.design-footer .btn:hover{background:#0056b3}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.container{width:100%;max-width:500px;margin:0 auto;background-color:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.tabs{display:flex;background-color:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background-color:#0052cc;color:#fff;font-weight:700}.tab-content{padding:5px;max-height:77vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}.document-settings{border:1px solid #dbe4ef;background:#f8fafc;border-radius:6px;padding:10px;margin-bottom:14px}.document-settings-title{font-size:14px;font-weight:700;color:#1f2937;margin-bottom:10px}.document-color-row{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center}.document-color-row input[type=color]{width:44px;height:40px;padding:3px}.document-toggle label{align-items:center;color:#334155}.document-subpanel{border-left:3px solid #2c6dd5;padding-left:10px;margin-bottom:12px}.document-help{color:#64748b;font-size:12px;line-height:1.4;margin:-4px 0 10px}.style-builder{border:1px solid #dbe4ef;background:#fff;border-radius:6px;padding:12px;margin-bottom:14px}.style-builder-title{font-size:14px;font-weight:700;color:#1f2937;margin-bottom:10px}.style-section-title{font-size:12px;font-weight:700;color:#334155;text-transform:uppercase;letter-spacing:0;border-top:1px solid #e5e7eb;padding-top:12px;margin:14px 0 10px}.style-section-title:first-of-type{border-top:0;padding-top:0}.style-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.style-grid .form-group{min-width:0}.style-color-row{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center}.style-color-row input[type=color],.style-builder input[type=color]{width:44px;height:40px;padding:3px}.style-four-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.style-four-grid span{display:block;color:#64748b;font-size:11px;margin-bottom:4px}.style-four-grid input{width:100%}.style-toggle-row{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:12px}.style-check-row{display:inline-flex;align-items:center;gap:8px;margin:0 0 12px;color:#334155;font-size:13px}.style-check-row input{width:auto}.style-nested{border-left:3px solid #2c6dd5;padding-left:10px;margin-bottom:12px}label{display:flex;gap:16px;margin-bottom:8px;color:#666;font-size:14px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],textarea,select{width:100%;padding:10px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;font-size:14px}.select-container{position:relative;width:100%}.dropdown-arrow{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.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}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.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-color:#4caf50}.view-icon{background-color:#2196f3}.delete-icon{background-color:#f44336}.color-picker-row{display:flex;align-items:center}.color-picker-container{display:flex;align-items:center;border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box{width:30px;border:none;height:30px}.hex-label{color:#999;margin-right:5px}.hex-input{width:100px}.divider{border-top:1px dashed #ddd;margin:20px 0}.button-container{display:flex;padding:15px;background-color:#f9f9f9;border-top:1px solid #eee}.cancel-btn,.save-btn{padding:12px;border:none;border-radius:4px;cursor:pointer;font-weight:700}.cancel-btn{flex:1;background-color:#fff;color:#666;border:1px solid #ddd}.cancel-btn:hover{background-color:#0052cc!important;color:#fff!important}.save-btn{flex:1;background-color:#0052cc;color:#fff;margin-right:10px}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;padding:8px}textarea{width:100%;min-height:55px;padding:8px;border:1px solid #ccc;border-radius:5px;font-size:14px;resize:vertical}.flex-container{display:flex;align-items:center;gap:12px;margin-bottom:1rem}.input-box-field select{background-color:#28343e;color:#fff;border:none;padding:10px 14px;border-radius:6px;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;font-size:14px;font-family:inherit}.input-box-field{position:relative}.input-box-field select::-ms-expand{display:none}.input-box-field:after{content:\"\\25bc\";position:absolute;top:50%;right:10px;transform:translateY(-50%);color:#1c1b1f;pointer-events:none;font-size:10px}.color-selector input[type=color]{width:40px;height:40px;border-radius:4px;background:none;cursor:pointer}.hex-input-container{display:flex;font-size:12px;gap:20px;color:#b0b0b0;align-items:center}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input-container input[type=text]{padding:10px 12px;border:1px solid #d1d1d1;border-radius:6px;font-size:14px;width:120px;color:#28343e}input{width:auto}@media screen and (max-width:1099px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:768px){.container{height:calc(100vh - 20px) h;min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;font-size:.9rem;text-align:center}.form-group{flex-direction:column}}@media screen and (max-width:480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{flex:1;padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}@media screen and (max-width:768px){.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}.logo-icon{width:20px;height:20px;display:flex;width:35px;justify-content:center;background-color:#d0d9ff;border-radius:4px}.link-icon{background-color:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:background-color .3s,transform .2s}.link-icon:hover{background-color:#d0e5ff}.link-icon:active{background-color:#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}.drag-handle{cursor:grab}.option-items:active{opacity:.5}.style-toggle-header{display:flex;justify-content:space-between;align-items:center;background-color:#f8f8f8;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;margin-bottom:6px}.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-color:#2c6dd5}.flex-container{display:flex;gap:8px;align-items:center}.size-select{transition:width .3s ease;width:100%;max-width:200px}.flex-container.custom-active .size-select{max-width:100px}.size-input{width:60px}.margin-inputs{display:flex;gap:15px;margin-top:5px}.margin-inputs>div{display:flex;flex-direction:column;width:60px}.margin-inputs label{font-size:12px;margin-bottom:3px}.pdf-actions-container{width:100%;max-width:400px;padding:10px}.pdf-action-card{background-color:#fff;border-radius:6px;padding:9px;box-shadow:0 2px 6px #0000001a;display:flex;flex-direction:column;gap:10px}.pdf-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:10px;background-color:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s}.pdf-btn:hover{background-color:#5a6268}\n"] }]
|
|
62398
63521
|
}], ctorParameters: () => [{ type: DataService }, { type: i1$1.HttpClient }, { type: PdfDesignerService }, { type: TemplateService }], propDecorators: { formButtonHandler: [{
|
|
62399
63522
|
type: Output
|
|
62400
63523
|
}], templateSaveHandler: [{
|
|
@@ -62411,6 +63534,201 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
62411
63534
|
args: ['document:click', ['$event']]
|
|
62412
63535
|
}] } });
|
|
62413
63536
|
|
|
63537
|
+
class BookletComponent {
|
|
63538
|
+
referenceKey;
|
|
63539
|
+
questions = [];
|
|
63540
|
+
isPreview = false;
|
|
63541
|
+
currencySymbol = '';
|
|
63542
|
+
questionChange = new EventEmitter();
|
|
63543
|
+
onQuestionChange(value, field) {
|
|
63544
|
+
this.questionChange.emit({ value, field });
|
|
63545
|
+
}
|
|
63546
|
+
isVisible(field) {
|
|
63547
|
+
return !!field && field.hideInPdf !== true && field.isHidden !== true;
|
|
63548
|
+
}
|
|
63549
|
+
getElementStyle(field) {
|
|
63550
|
+
const style = field?.style || {};
|
|
63551
|
+
return {
|
|
63552
|
+
width: `${field?.width || 100}%`,
|
|
63553
|
+
'font-family': style.font || 'Helvetica Neue',
|
|
63554
|
+
'font-size': `${Number(style.fontSize) || Number(field?.fontSize) || 12}px`,
|
|
63555
|
+
'font-weight': style.bold ? '700' : (style.fontWeight || field?.fontWeight || '400'),
|
|
63556
|
+
'font-style': style.italic ? 'italic' : 'normal',
|
|
63557
|
+
color: style.color || '#000000',
|
|
63558
|
+
'text-align': style.alignment || 'left',
|
|
63559
|
+
'background-color': style.fillColor || style.backgroundColor || 'transparent',
|
|
63560
|
+
padding: this.marginToCss(style.margin || field?.margin || [0, 0, 0, 0]),
|
|
63561
|
+
'line-height': style.lineHeight || 1.25,
|
|
63562
|
+
'letter-spacing': `${Number(style.characterSpacing) || 0}px`,
|
|
63563
|
+
'text-decoration': style.decoration === 'lineThrough' ? 'line-through' : (style.decoration || 'none'),
|
|
63564
|
+
opacity: style.opacity ?? 1,
|
|
63565
|
+
border: style.borderColor ? `1px solid ${style.borderColor}` : 'none',
|
|
63566
|
+
'--booklet-heading-color': style.headingColor || style.color || '#2f9e44'
|
|
63567
|
+
};
|
|
63568
|
+
}
|
|
63569
|
+
getLabelStyle(field) {
|
|
63570
|
+
const style = field?.style || {};
|
|
63571
|
+
return {
|
|
63572
|
+
color: style.labelColor || style.color || '#222222',
|
|
63573
|
+
'font-size': `${Number(style.labelFontSize) || Number(style.fontSize) || 12}px`,
|
|
63574
|
+
'font-weight': style.labelBold === false ? '400' : '700',
|
|
63575
|
+
'text-align': style.alignment || 'left'
|
|
63576
|
+
};
|
|
63577
|
+
}
|
|
63578
|
+
getValue(field) {
|
|
63579
|
+
if (!field)
|
|
63580
|
+
return '';
|
|
63581
|
+
if (field.type === 'currency') {
|
|
63582
|
+
return this.formatCurrency(field.value, field);
|
|
63583
|
+
}
|
|
63584
|
+
if (field.type === 'boolean') {
|
|
63585
|
+
return field.value === true || field.value === 'true' ? 'Yes' : 'No';
|
|
63586
|
+
}
|
|
63587
|
+
return field.value ?? '';
|
|
63588
|
+
}
|
|
63589
|
+
getMainColumns(field) {
|
|
63590
|
+
const columns = Array.isArray(field?.fieldsMeta) ? field.fieldsMeta : [];
|
|
63591
|
+
return columns.filter(column => column?.hideInPdf !== true && column?.isHidden !== true && column?.summaryRow !== true);
|
|
63592
|
+
}
|
|
63593
|
+
getSummaryColumns(field) {
|
|
63594
|
+
const columns = Array.isArray(field?.fieldsMeta) ? field.fieldsMeta : [];
|
|
63595
|
+
return columns.filter(column => column?.hideInPdf !== true && column?.isHidden !== true && column?.summaryRow === true);
|
|
63596
|
+
}
|
|
63597
|
+
getRows(field) {
|
|
63598
|
+
return field?.value?.data || [];
|
|
63599
|
+
}
|
|
63600
|
+
getHeaderStyle(column) {
|
|
63601
|
+
const style = column?.style || {};
|
|
63602
|
+
return {
|
|
63603
|
+
'background-color': style.fillColor || '#f1f5f9',
|
|
63604
|
+
color: style.color || '#111827',
|
|
63605
|
+
'text-align': style.alignment || 'left',
|
|
63606
|
+
width: this.getColumnWidth(column)
|
|
63607
|
+
};
|
|
63608
|
+
}
|
|
63609
|
+
getCellStyle(column, rowIndex) {
|
|
63610
|
+
const style = column?.style || {};
|
|
63611
|
+
return {
|
|
63612
|
+
'text-align': style.alignment || (column?.fldType === 'currency' ? 'right' : 'left'),
|
|
63613
|
+
width: this.getColumnWidth(column),
|
|
63614
|
+
'background-color': rowIndex % 2 === 1 ? '#f8fafc' : '#ffffff',
|
|
63615
|
+
color: style.cellColor || '#374151'
|
|
63616
|
+
};
|
|
63617
|
+
}
|
|
63618
|
+
getSummaryColspan(field) {
|
|
63619
|
+
return Math.max(this.getMainColumns(field).length - 1, 1);
|
|
63620
|
+
}
|
|
63621
|
+
getCellValue(row, column) {
|
|
63622
|
+
const value = this.getPathValue(row, column?.apiName);
|
|
63623
|
+
if (column?.fldType === 'currency') {
|
|
63624
|
+
return this.formatCurrency(value, column);
|
|
63625
|
+
}
|
|
63626
|
+
return value ?? '';
|
|
63627
|
+
}
|
|
63628
|
+
getSummaryValue(field, column) {
|
|
63629
|
+
const summaryValues = field?.value?.summaryValues || field?.value?.summaryValue || {};
|
|
63630
|
+
const value = this.getPathValue(summaryValues, column?.apiName);
|
|
63631
|
+
if (column?.fldType === 'currency') {
|
|
63632
|
+
return this.formatCurrency(value, column);
|
|
63633
|
+
}
|
|
63634
|
+
return value ?? '';
|
|
63635
|
+
}
|
|
63636
|
+
getRichTextLines(field) {
|
|
63637
|
+
return String(field?.value || '').split(/\r?\n/).filter(line => line.trim().length > 0);
|
|
63638
|
+
}
|
|
63639
|
+
shouldRenderStyledTextLines(field) {
|
|
63640
|
+
return field?.type === 'text' && (field?.headingFirstLine === true || this.isQuotationHeadingText(field));
|
|
63641
|
+
}
|
|
63642
|
+
getStyledTextLines(field) {
|
|
63643
|
+
return String(this.getValue(field) || '').split(/\r?\n/);
|
|
63644
|
+
}
|
|
63645
|
+
isTextHeadingLine(field, index, line) {
|
|
63646
|
+
return (field?.headingFirstLine === true || this.isQuotationHeadingText(field)) && index === 0 && String(line || '').trim().length > 0;
|
|
63647
|
+
}
|
|
63648
|
+
getStyledTextLineStyle(field, index, line) {
|
|
63649
|
+
const style = field?.style || {};
|
|
63650
|
+
if (this.isTextHeadingLine(field, index, line)) {
|
|
63651
|
+
return {
|
|
63652
|
+
color: style.headingColor || this.getDefaultTextHeadingColor(field) || style.color || '#2f9e44',
|
|
63653
|
+
'font-size': `${Number(style.headingFontSize) || this.getDefaultTextHeadingSize(field) || Number(style.fontSize) || 12}px`,
|
|
63654
|
+
'font-weight': style.headingBold === false || (style.headingBold === undefined && this.isQuotationHeadingText(field)) ? '400' : '700',
|
|
63655
|
+
margin: this.marginToCss(style.headingMargin || [0, 0, 0, 2])
|
|
63656
|
+
};
|
|
63657
|
+
}
|
|
63658
|
+
if (!line) {
|
|
63659
|
+
return {
|
|
63660
|
+
height: `${Number(style.blankLineHeight) || 10}px`,
|
|
63661
|
+
'min-height': `${Number(style.blankLineHeight) || 10}px`
|
|
63662
|
+
};
|
|
63663
|
+
}
|
|
63664
|
+
return {};
|
|
63665
|
+
}
|
|
63666
|
+
isQuotationHeadingText(field) {
|
|
63667
|
+
const firstLine = String(field?.value || '').split(/\r?\n/)[0]?.trim();
|
|
63668
|
+
return firstLine === 'VALAR HR' || firstLine === 'QUOTATION';
|
|
63669
|
+
}
|
|
63670
|
+
getDefaultTextHeadingColor(field) {
|
|
63671
|
+
return this.isQuotationHeadingText(field) ? '#3fa34d' : '';
|
|
63672
|
+
}
|
|
63673
|
+
getDefaultTextHeadingSize(field) {
|
|
63674
|
+
return this.isQuotationHeadingText(field) ? 24 : 0;
|
|
63675
|
+
}
|
|
63676
|
+
isRichTextBullet(line) {
|
|
63677
|
+
return /^[•*-]\s+/.test(line.trim());
|
|
63678
|
+
}
|
|
63679
|
+
getRichTextLineText(line) {
|
|
63680
|
+
return line.trim().replace(/^[•*-]\s+/, '');
|
|
63681
|
+
}
|
|
63682
|
+
isRichTextHeading(field, index, line) {
|
|
63683
|
+
return field?.headingFirstLine !== false && index === 0 && !this.isRichTextBullet(line);
|
|
63684
|
+
}
|
|
63685
|
+
getPdfMakePreview(field) {
|
|
63686
|
+
return field?.pdfMakeContent || field?.value || '';
|
|
63687
|
+
}
|
|
63688
|
+
getColumnWidth(column) {
|
|
63689
|
+
const width = column?.style?.width;
|
|
63690
|
+
return typeof width === 'number' ? `${width}px` : 'auto';
|
|
63691
|
+
}
|
|
63692
|
+
formatCurrency(value, field) {
|
|
63693
|
+
if (value === undefined || value === null || value === '')
|
|
63694
|
+
return '';
|
|
63695
|
+
if (field && Object.prototype.hasOwnProperty.call(field, 'currencySymbol')) {
|
|
63696
|
+
return `${field.currencySymbol ? field.currencySymbol + ' ' : ''}${value}`;
|
|
63697
|
+
}
|
|
63698
|
+
return `${this.currencySymbol || ''}${this.currencySymbol ? ' ' : ''}${value}`;
|
|
63699
|
+
}
|
|
63700
|
+
getPathValue(data, path) {
|
|
63701
|
+
if (!data || !path)
|
|
63702
|
+
return undefined;
|
|
63703
|
+
return path.split('.').reduce((obj, key) => obj?.[key], data);
|
|
63704
|
+
}
|
|
63705
|
+
normalizeMargin(margin) {
|
|
63706
|
+
if (!Array.isArray(margin))
|
|
63707
|
+
return [0, 0, 0, 0];
|
|
63708
|
+
return [0, 1, 2, 3].map(index => Number(margin[index]) || 0);
|
|
63709
|
+
}
|
|
63710
|
+
marginToCss(margin) {
|
|
63711
|
+
const normalized = this.normalizeMargin(margin);
|
|
63712
|
+
return `${normalized[1]}px ${normalized[2]}px ${normalized[3]}px ${normalized[0]}px`;
|
|
63713
|
+
}
|
|
63714
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BookletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
63715
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: BookletComponent, isStandalone: true, selector: "app-booklet", inputs: { referenceKey: "referenceKey", questions: "questions", isPreview: "isPreview", currencySymbol: "currencySymbol" }, outputs: { questionChange: "questionChange" }, ngImport: i0, template: "<div class=\"booklet-renderer\" [attr.data-reference]=\"referenceKey\">\n <ng-container *ngFor=\"let field of questions\">\n <div *ngIf=\"isVisible(field)\" class=\"booklet-field\" [ngStyle]=\"getElementStyle(field)\">\n <ng-container [ngSwitch]=\"field?.type\">\n <div *ngSwitchCase=\"'Line'\" class=\"booklet-line\"></div>\n\n <div *ngSwitchCase=\"'Space'\" class=\"booklet-space\"></div>\n\n <div *ngSwitchCase=\"'Section'\" class=\"booklet-section\">\n {{ getValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'Note'\" class=\"booklet-note\">\n {{ getValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'RichText'\" class=\"booklet-richtext\">\n <ng-container *ngFor=\"let line of getRichTextLines(field); let lineIndex = index\">\n <div *ngIf=\"isRichTextHeading(field, lineIndex, line)\" class=\"booklet-richtext-heading\">\n {{ getRichTextLineText(line) }}\n </div>\n <div *ngIf=\"!isRichTextHeading(field, lineIndex, line) && !isRichTextBullet(line)\" class=\"booklet-richtext-line\">\n {{ line }}\n </div>\n <div *ngIf=\"isRichTextBullet(line)\" class=\"booklet-richtext-bullet\">\n <span>\u2022</span>\n <span>{{ getRichTextLineText(line) }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngSwitchCase=\"'PageBreak'\" class=\"booklet-pagebreak\">\n Page break\n </div>\n\n <div *ngSwitchCase=\"'PdfMake'\" class=\"booklet-pdfmake\">\n <div>Advanced pdfmake content</div>\n <pre>{{ getPdfMakePreview(field) }}</pre>\n </div>\n\n <div *ngSwitchCase=\"'image'\" class=\"booklet-image\" [style.text-align]=\"field?.style?.alignment || 'left'\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <img *ngIf=\"field?.imageData\" [src]=\"field.imageData\" [style.width.px]=\"field?.imageSize?.width || 100\" [style.height.px]=\"field?.imageSize?.height || 100\" />\n </div>\n\n <div *ngSwitchCase=\"'signaturePad'\" class=\"booklet-image\" [style.text-align]=\"field?.style?.alignment || 'left'\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <img *ngIf=\"field?.value\" [src]=\"field.value\" [style.width.px]=\"field?.imageSize?.width || 250\" [style.height.px]=\"field?.imageSize?.height || 90\" />\n </div>\n\n <div *ngSwitchCase=\"'Table'\" class=\"booklet-table-wrap\">\n <table class=\"booklet-table\">\n <thead>\n <tr>\n <th *ngFor=\"let column of getMainColumns(field)\" [ngStyle]=\"getHeaderStyle(column)\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getRows(field); let rowIndex = index\">\n <td *ngFor=\"let column of getMainColumns(field)\" [ngStyle]=\"getCellStyle(column, rowIndex)\">\n {{ getCellValue(row, column) }}\n </td>\n </tr>\n <tr *ngFor=\"let summary of getSummaryColumns(field)\" class=\"booklet-summary-row\">\n <td [attr.colspan]=\"getSummaryColspan(field)\" class=\"booklet-summary-label\">\n {{ summary.label }}\n </td>\n <td class=\"booklet-summary-value\" [style.text-align]=\"summary?.style?.alignment || 'right'\">\n {{ getSummaryValue(field, summary) }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <app-booklet\n *ngSwitchCase=\"'Pdf'\"\n [referenceKey]=\"field?.pdfReference\"\n [questions]=\"field?.pdfReferenceQuestions?.[field?.pdfReference] || []\"\n [isPreview]=\"isPreview\"\n [currencySymbol]=\"currencySymbol\"\n (questionChange)=\"onQuestionChange($event.value, $event.field)\">\n </app-booklet>\n\n <div *ngSwitchDefault class=\"booklet-text\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <ng-container *ngIf=\"shouldRenderStyledTextLines(field); else plainBookletValue\">\n <div *ngFor=\"let line of getStyledTextLines(field); let lineIndex = index\"\n class=\"booklet-value\"\n [class.booklet-text-heading-line]=\"isTextHeadingLine(field, lineIndex, line)\"\n [class.booklet-text-empty-line]=\"!line\"\n [ngStyle]=\"getStyledTextLineStyle(field, lineIndex, line)\">\n {{ line || ' ' }}\n </div>\n </ng-container>\n <ng-template #plainBookletValue>\n <div class=\"booklet-value\">{{ getValue(field) }}</div>\n </ng-template>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n", styles: [".booklet-renderer{display:flex;flex-wrap:wrap;width:100%;align-items:flex-start}.booklet-field{box-sizing:border-box;min-width:0;white-space:pre-wrap}.booklet-label{margin-bottom:2px}.booklet-value{min-height:16px}.booklet-text-heading-line{line-height:1.05}.booklet-text-empty-line{font-size:0}.booklet-line{width:100%;border-top:1px solid currentColor;min-height:1px}.booklet-space{width:100%;min-height:24px}.booklet-section{width:100%;min-height:32px;box-sizing:border-box}.booklet-note{width:100%;min-height:34px;border:1px solid currentColor;box-sizing:border-box}.booklet-richtext{width:100%;white-space:normal}.booklet-richtext-heading{color:var(--booklet-heading-color, #2f9e44);font-weight:600;margin-bottom:8px}.booklet-richtext-line{margin-bottom:7px}.booklet-richtext-bullet{display:grid;grid-template-columns:14px minmax(0,1fr);gap:4px;margin-bottom:7px}.booklet-pagebreak{width:100%;min-height:42px;display:flex;align-items:center;justify-content:center;border:1px dashed #94a3b8;color:#64748b;background:#f8fafc;font-size:11px;text-transform:uppercase}.booklet-pdfmake{width:100%;border:1px dashed #94a3b8;background:#f8fafc;color:#334155;padding:10px;box-sizing:border-box}.booklet-pdfmake div{font-size:11px;font-weight:700;margin-bottom:6px}.booklet-pdfmake pre{margin:0;max-height:160px;overflow:auto;white-space:pre-wrap;font-size:11px}.booklet-image img{display:inline-block;object-fit:contain;max-width:100%}.booklet-table-wrap{width:100%;overflow-x:auto}.booklet-table{width:100%;border-collapse:collapse;table-layout:fixed;font-size:inherit}.booklet-table th,.booklet-table td{border:1px solid #cfd8d1;padding:6px;vertical-align:top;overflow-wrap:anywhere}.booklet-summary-row td{border-color:transparent;background:transparent}.booklet-summary-label{color:#555;text-align:right}.booklet-summary-value{color:#222;font-weight:600}\n"], dependencies: [{ kind: "component", type: BookletComponent, selector: "app-booklet", inputs: ["referenceKey", "questions", "isPreview", "currencySymbol"], outputs: ["questionChange"] }, { 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: "directive", type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i5.NgSwitchDefault, selector: "[ngSwitchDefault]" }] });
|
|
63716
|
+
}
|
|
63717
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BookletComponent, decorators: [{
|
|
63718
|
+
type: Component,
|
|
63719
|
+
args: [{ selector: 'app-booklet', standalone: true, imports: [CommonModule], template: "<div class=\"booklet-renderer\" [attr.data-reference]=\"referenceKey\">\n <ng-container *ngFor=\"let field of questions\">\n <div *ngIf=\"isVisible(field)\" class=\"booklet-field\" [ngStyle]=\"getElementStyle(field)\">\n <ng-container [ngSwitch]=\"field?.type\">\n <div *ngSwitchCase=\"'Line'\" class=\"booklet-line\"></div>\n\n <div *ngSwitchCase=\"'Space'\" class=\"booklet-space\"></div>\n\n <div *ngSwitchCase=\"'Section'\" class=\"booklet-section\">\n {{ getValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'Note'\" class=\"booklet-note\">\n {{ getValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'RichText'\" class=\"booklet-richtext\">\n <ng-container *ngFor=\"let line of getRichTextLines(field); let lineIndex = index\">\n <div *ngIf=\"isRichTextHeading(field, lineIndex, line)\" class=\"booklet-richtext-heading\">\n {{ getRichTextLineText(line) }}\n </div>\n <div *ngIf=\"!isRichTextHeading(field, lineIndex, line) && !isRichTextBullet(line)\" class=\"booklet-richtext-line\">\n {{ line }}\n </div>\n <div *ngIf=\"isRichTextBullet(line)\" class=\"booklet-richtext-bullet\">\n <span>\u2022</span>\n <span>{{ getRichTextLineText(line) }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngSwitchCase=\"'PageBreak'\" class=\"booklet-pagebreak\">\n Page break\n </div>\n\n <div *ngSwitchCase=\"'PdfMake'\" class=\"booklet-pdfmake\">\n <div>Advanced pdfmake content</div>\n <pre>{{ getPdfMakePreview(field) }}</pre>\n </div>\n\n <div *ngSwitchCase=\"'image'\" class=\"booklet-image\" [style.text-align]=\"field?.style?.alignment || 'left'\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <img *ngIf=\"field?.imageData\" [src]=\"field.imageData\" [style.width.px]=\"field?.imageSize?.width || 100\" [style.height.px]=\"field?.imageSize?.height || 100\" />\n </div>\n\n <div *ngSwitchCase=\"'signaturePad'\" class=\"booklet-image\" [style.text-align]=\"field?.style?.alignment || 'left'\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <img *ngIf=\"field?.value\" [src]=\"field.value\" [style.width.px]=\"field?.imageSize?.width || 250\" [style.height.px]=\"field?.imageSize?.height || 90\" />\n </div>\n\n <div *ngSwitchCase=\"'Table'\" class=\"booklet-table-wrap\">\n <table class=\"booklet-table\">\n <thead>\n <tr>\n <th *ngFor=\"let column of getMainColumns(field)\" [ngStyle]=\"getHeaderStyle(column)\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of getRows(field); let rowIndex = index\">\n <td *ngFor=\"let column of getMainColumns(field)\" [ngStyle]=\"getCellStyle(column, rowIndex)\">\n {{ getCellValue(row, column) }}\n </td>\n </tr>\n <tr *ngFor=\"let summary of getSummaryColumns(field)\" class=\"booklet-summary-row\">\n <td [attr.colspan]=\"getSummaryColspan(field)\" class=\"booklet-summary-label\">\n {{ summary.label }}\n </td>\n <td class=\"booklet-summary-value\" [style.text-align]=\"summary?.style?.alignment || 'right'\">\n {{ getSummaryValue(field, summary) }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <app-booklet\n *ngSwitchCase=\"'Pdf'\"\n [referenceKey]=\"field?.pdfReference\"\n [questions]=\"field?.pdfReferenceQuestions?.[field?.pdfReference] || []\"\n [isPreview]=\"isPreview\"\n [currencySymbol]=\"currencySymbol\"\n (questionChange)=\"onQuestionChange($event.value, $event.field)\">\n </app-booklet>\n\n <div *ngSwitchDefault class=\"booklet-text\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"booklet-label\" [ngStyle]=\"getLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <ng-container *ngIf=\"shouldRenderStyledTextLines(field); else plainBookletValue\">\n <div *ngFor=\"let line of getStyledTextLines(field); let lineIndex = index\"\n class=\"booklet-value\"\n [class.booklet-text-heading-line]=\"isTextHeadingLine(field, lineIndex, line)\"\n [class.booklet-text-empty-line]=\"!line\"\n [ngStyle]=\"getStyledTextLineStyle(field, lineIndex, line)\">\n {{ line || ' ' }}\n </div>\n </ng-container>\n <ng-template #plainBookletValue>\n <div class=\"booklet-value\">{{ getValue(field) }}</div>\n </ng-template>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n", styles: [".booklet-renderer{display:flex;flex-wrap:wrap;width:100%;align-items:flex-start}.booklet-field{box-sizing:border-box;min-width:0;white-space:pre-wrap}.booklet-label{margin-bottom:2px}.booklet-value{min-height:16px}.booklet-text-heading-line{line-height:1.05}.booklet-text-empty-line{font-size:0}.booklet-line{width:100%;border-top:1px solid currentColor;min-height:1px}.booklet-space{width:100%;min-height:24px}.booklet-section{width:100%;min-height:32px;box-sizing:border-box}.booklet-note{width:100%;min-height:34px;border:1px solid currentColor;box-sizing:border-box}.booklet-richtext{width:100%;white-space:normal}.booklet-richtext-heading{color:var(--booklet-heading-color, #2f9e44);font-weight:600;margin-bottom:8px}.booklet-richtext-line{margin-bottom:7px}.booklet-richtext-bullet{display:grid;grid-template-columns:14px minmax(0,1fr);gap:4px;margin-bottom:7px}.booklet-pagebreak{width:100%;min-height:42px;display:flex;align-items:center;justify-content:center;border:1px dashed #94a3b8;color:#64748b;background:#f8fafc;font-size:11px;text-transform:uppercase}.booklet-pdfmake{width:100%;border:1px dashed #94a3b8;background:#f8fafc;color:#334155;padding:10px;box-sizing:border-box}.booklet-pdfmake div{font-size:11px;font-weight:700;margin-bottom:6px}.booklet-pdfmake pre{margin:0;max-height:160px;overflow:auto;white-space:pre-wrap;font-size:11px}.booklet-image img{display:inline-block;object-fit:contain;max-width:100%}.booklet-table-wrap{width:100%;overflow-x:auto}.booklet-table{width:100%;border-collapse:collapse;table-layout:fixed;font-size:inherit}.booklet-table th,.booklet-table td{border:1px solid #cfd8d1;padding:6px;vertical-align:top;overflow-wrap:anywhere}.booklet-summary-row td{border-color:transparent;background:transparent}.booklet-summary-label{color:#555;text-align:right}.booklet-summary-value{color:#222;font-weight:600}\n"] }]
|
|
63720
|
+
}], propDecorators: { referenceKey: [{
|
|
63721
|
+
type: Input
|
|
63722
|
+
}], questions: [{
|
|
63723
|
+
type: Input
|
|
63724
|
+
}], isPreview: [{
|
|
63725
|
+
type: Input
|
|
63726
|
+
}], currencySymbol: [{
|
|
63727
|
+
type: Input
|
|
63728
|
+
}], questionChange: [{
|
|
63729
|
+
type: Output
|
|
63730
|
+
}] } });
|
|
63731
|
+
|
|
62414
63732
|
class PdfDesignerComponent {
|
|
62415
63733
|
dataService;
|
|
62416
63734
|
changeService;
|
|
@@ -62424,9 +63742,11 @@ class PdfDesignerComponent {
|
|
|
62424
63742
|
from;
|
|
62425
63743
|
dataBind;
|
|
62426
63744
|
isPropertyHide = false;
|
|
63745
|
+
pdfDefinitionOptions = {};
|
|
62427
63746
|
pdfSaveHandlerEmit = new EventEmitter();
|
|
62428
63747
|
templateMode = new EventEmitter();
|
|
62429
63748
|
pdfPreviewEmit = new EventEmitter();
|
|
63749
|
+
pdfOutputEmit = new EventEmitter();
|
|
62430
63750
|
field;
|
|
62431
63751
|
pdfElements = [];
|
|
62432
63752
|
elements = [];
|
|
@@ -62529,62 +63849,52 @@ class PdfDesignerComponent {
|
|
|
62529
63849
|
});
|
|
62530
63850
|
}
|
|
62531
63851
|
}
|
|
62532
|
-
|
|
62533
|
-
if (
|
|
62534
|
-
|
|
62535
|
-
|
|
62536
|
-
|
|
62537
|
-
|
|
62538
|
-
|
|
62539
|
-
|
|
63852
|
+
handleQues(ques, dataBind = this.dataBind) {
|
|
63853
|
+
if (dataBind && Object.keys(dataBind).length > 0) {
|
|
63854
|
+
const questionType = (ques.type || '').toString().toLowerCase();
|
|
63855
|
+
const value = this.getBoundTemplateValue(ques.referenceTemplate || ques.bindingTemplate, dataBind)
|
|
63856
|
+
?? this.getBoundReferencePartsValue(ques.referenceParts || ques.referenceFields, dataBind)
|
|
63857
|
+
?? this.getBoundReferenceValue(ques.referenceField, ques.referenceJoiner, dataBind);
|
|
63858
|
+
const hasValue = this.hasBindableValue(value);
|
|
63859
|
+
if (questionType === 'pdf' && ques.pdfReferenceQuestions) {
|
|
63860
|
+
// HA 24JAN24 Fetching from QB reference
|
|
63861
|
+
ques.pdfReferenceQuestions = typeof ques.pdfReferenceQuestions === 'object' ? ques.pdfReferenceQuestions : JSON.parse(ques.pdfReferenceQuestions);
|
|
63862
|
+
ques.pdfReferenceQuestions?.[ques.pdfReference]?.forEach(inQues => {
|
|
63863
|
+
this.handleQues(inQues, dataBind);
|
|
63864
|
+
});
|
|
62540
63865
|
}
|
|
62541
|
-
else {
|
|
62542
|
-
|
|
63866
|
+
else if (questionType === 'table') {
|
|
63867
|
+
const rows = hasValue ? this.getBoundTableRows(value) : this.getBoundTableRows(ques.value);
|
|
63868
|
+
const summaryValues = this.buildTableSummaryValues(ques, rows, dataBind);
|
|
63869
|
+
if (hasValue || Object.keys(summaryValues).length > 0) {
|
|
63870
|
+
ques.value = Object.keys(summaryValues).length > 0
|
|
63871
|
+
? { data: rows, summaryValues, summaryValue: summaryValues }
|
|
63872
|
+
: { data: rows };
|
|
63873
|
+
}
|
|
62543
63874
|
}
|
|
62544
|
-
if (
|
|
62545
|
-
if (
|
|
62546
|
-
ques.value = value
|
|
62547
|
-
ques.selectedValue = value
|
|
63875
|
+
else if (hasValue) {
|
|
63876
|
+
if (['dropdown', 'multiselect', 'radio'].includes(questionType)) {
|
|
63877
|
+
ques.value = value;
|
|
63878
|
+
ques.selectedValue = value;
|
|
62548
63879
|
}
|
|
62549
|
-
else if (
|
|
63880
|
+
else if (questionType === 'date' || questionType === 'datetime') {
|
|
62550
63881
|
ques.value = new Date(value?.toString()) || ques.value;
|
|
62551
63882
|
}
|
|
62552
|
-
else if (
|
|
62553
|
-
ques.value = value['address'] ? value['address'] : value
|
|
63883
|
+
else if (questionType === 'location') {
|
|
63884
|
+
ques.value = value?.['address'] ? value['address'] : value;
|
|
62554
63885
|
}
|
|
62555
|
-
else if (
|
|
62556
|
-
ques.value =
|
|
63886
|
+
else if (questionType === 'boolean') {
|
|
63887
|
+
ques.value = value === true || value === 'true';
|
|
62557
63888
|
}
|
|
62558
|
-
else if (
|
|
63889
|
+
else if (questionType === 'image') {
|
|
62559
63890
|
ques.imageData = value || ques.imageData;
|
|
62560
63891
|
}
|
|
62561
|
-
else if (ques.type === "Table") {
|
|
62562
|
-
let summaryValue = {};
|
|
62563
|
-
if (ques.summaryValuesReferenceField) {
|
|
62564
|
-
if (Array.isArray(ques.summaryValuesReferenceField)) {
|
|
62565
|
-
for (const smrf of ques.summaryValuesReferenceField) {
|
|
62566
|
-
summaryValue[smrf] = this.dataService.getValue(this.dataBind, smrf);
|
|
62567
|
-
}
|
|
62568
|
-
}
|
|
62569
|
-
else {
|
|
62570
|
-
summaryValue = { [ques.summaryValuesReferenceField]: this.dataService.getValue(this.dataBind, ques.summaryValuesReferenceField) };
|
|
62571
|
-
}
|
|
62572
|
-
}
|
|
62573
|
-
ques.value = value && Object.keys(summaryValue).length > 0 ? { data: value, summaryValue: summaryValue } : value ? { data: value } : ques.value;
|
|
62574
|
-
}
|
|
62575
63892
|
else {
|
|
62576
|
-
ques.value = value
|
|
63893
|
+
ques.value = value;
|
|
62577
63894
|
}
|
|
62578
63895
|
}
|
|
62579
|
-
else if (ques.type === 'Pdf' && ques.pdfReferenceQuestions) {
|
|
62580
|
-
// HA 24JAN24 Fetching from QB reference
|
|
62581
|
-
ques.pdfReferenceQuestions = typeof ques.pdfReferenceQuestions === 'object' ? ques.pdfReferenceQuestions : JSON.parse(ques.pdfReferenceQuestions);
|
|
62582
|
-
ques.pdfReferenceQuestions?.[ques.pdfReference]?.forEach(inQues => {
|
|
62583
|
-
this.handleQues(inQues);
|
|
62584
|
-
});
|
|
62585
|
-
}
|
|
62586
63896
|
else {
|
|
62587
|
-
if (
|
|
63897
|
+
if (questionType === 'boolean') {
|
|
62588
63898
|
ques.value = typeof ques.value !== 'undefined' ? ques.value === true || ques.value === 'true' : false;
|
|
62589
63899
|
}
|
|
62590
63900
|
else {
|
|
@@ -62613,6 +63923,151 @@ class PdfDesignerComponent {
|
|
|
62613
63923
|
question['selectedValue'] = ques?.selectedValue;
|
|
62614
63924
|
}
|
|
62615
63925
|
}
|
|
63926
|
+
// SKS26MAY26 databind
|
|
63927
|
+
getBoundReferenceValue(referenceField, referenceJoiner = ' ', dataBind = this.dataBind) {
|
|
63928
|
+
if (!referenceField)
|
|
63929
|
+
return undefined;
|
|
63930
|
+
if (Array.isArray(referenceField)) {
|
|
63931
|
+
return referenceField
|
|
63932
|
+
.map((fieldPath) => this.dataService.getValue(dataBind, fieldPath))
|
|
63933
|
+
.filter(value => this.hasBindableValue(value))
|
|
63934
|
+
.join(referenceJoiner || ' ');
|
|
63935
|
+
}
|
|
63936
|
+
return this.dataService.getValue(dataBind, referenceField);
|
|
63937
|
+
}
|
|
63938
|
+
getBoundReferencePartsValue(referenceParts, dataBind = this.dataBind) {
|
|
63939
|
+
if (!Array.isArray(referenceParts) || referenceParts.length === 0)
|
|
63940
|
+
return undefined;
|
|
63941
|
+
let output = '';
|
|
63942
|
+
referenceParts.forEach((part) => {
|
|
63943
|
+
if (typeof part === 'string') {
|
|
63944
|
+
const value = this.dataService.getValue(dataBind, part);
|
|
63945
|
+
if (this.hasBindableValue(value)) {
|
|
63946
|
+
output += String(value);
|
|
63947
|
+
}
|
|
63948
|
+
return;
|
|
63949
|
+
}
|
|
63950
|
+
if (part?.text !== undefined) {
|
|
63951
|
+
output += String(part.text);
|
|
63952
|
+
return;
|
|
63953
|
+
}
|
|
63954
|
+
const fieldPath = part?.field || part?.referenceField || part?.path;
|
|
63955
|
+
const value = this.getBoundReferenceValue(fieldPath, part?.referenceJoiner, dataBind);
|
|
63956
|
+
if (!this.hasBindableValue(value)) {
|
|
63957
|
+
if (part?.fallback !== undefined) {
|
|
63958
|
+
output += `${part.prefix || ''}${part.fallback}${part.suffix || part.after || ''}`;
|
|
63959
|
+
}
|
|
63960
|
+
return;
|
|
63961
|
+
}
|
|
63962
|
+
output += `${part.prefix || ''}${value}${part.suffix || part.after || ''}`;
|
|
63963
|
+
});
|
|
63964
|
+
return output
|
|
63965
|
+
.replace(/[ \t]+\n/g, '\n')
|
|
63966
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
63967
|
+
.trim();
|
|
63968
|
+
}
|
|
63969
|
+
// SKS26MAY26 databind template
|
|
63970
|
+
getBoundTemplateValue(template, dataBind = this.dataBind) {
|
|
63971
|
+
if (!template || typeof template !== 'string')
|
|
63972
|
+
return undefined;
|
|
63973
|
+
return template.replace(/\{\{\s*([^}|]+?)(?:\s*\|\s*([^}]+?))?\s*\}\}/g, (_match, fieldPath, pipeName) => {
|
|
63974
|
+
const value = this.dataService.getValue(dataBind, fieldPath.trim());
|
|
63975
|
+
if (!this.hasBindableValue(value))
|
|
63976
|
+
return '';
|
|
63977
|
+
if ((pipeName || '').trim().toLowerCase() === 'date') {
|
|
63978
|
+
return this.formatBoundDateValue(value);
|
|
63979
|
+
}
|
|
63980
|
+
return String(value);
|
|
63981
|
+
});
|
|
63982
|
+
}
|
|
63983
|
+
formatBoundDateValue(value) {
|
|
63984
|
+
const dateValue = new Date(value);
|
|
63985
|
+
if (Number.isNaN(dateValue.getTime()))
|
|
63986
|
+
return String(value);
|
|
63987
|
+
return dateValue.toLocaleDateString('en-GB');
|
|
63988
|
+
}
|
|
63989
|
+
hasBindableValue(value) {
|
|
63990
|
+
if (value === undefined || value === null)
|
|
63991
|
+
return false;
|
|
63992
|
+
if (typeof value === 'string')
|
|
63993
|
+
return value.length > 0;
|
|
63994
|
+
if (Array.isArray(value))
|
|
63995
|
+
return value.length > 0;
|
|
63996
|
+
return true;
|
|
63997
|
+
}
|
|
63998
|
+
getBoundTableRows(value) {
|
|
63999
|
+
if (Array.isArray(value))
|
|
64000
|
+
return value;
|
|
64001
|
+
if (Array.isArray(value?.data))
|
|
64002
|
+
return value.data;
|
|
64003
|
+
return [];
|
|
64004
|
+
}
|
|
64005
|
+
// SKS26MAY26 table summary data bind
|
|
64006
|
+
buildTableSummaryValues(ques, rows, dataBind = this.dataBind) {
|
|
64007
|
+
const summaryValues = {};
|
|
64008
|
+
const refs = ques.summaryValuesReferenceField;
|
|
64009
|
+
const setSummaryValue = (apiName, referenceField) => {
|
|
64010
|
+
if (!apiName || !referenceField)
|
|
64011
|
+
return;
|
|
64012
|
+
const value = this.dataService.getValue(dataBind, referenceField);
|
|
64013
|
+
if (this.hasBindableValue(value)) {
|
|
64014
|
+
summaryValues[apiName] = value;
|
|
64015
|
+
}
|
|
64016
|
+
};
|
|
64017
|
+
if (Array.isArray(refs)) {
|
|
64018
|
+
refs.forEach((ref) => {
|
|
64019
|
+
if (typeof ref === 'string') {
|
|
64020
|
+
setSummaryValue(ref, ref);
|
|
64021
|
+
}
|
|
64022
|
+
else if (ref && typeof ref === 'object') {
|
|
64023
|
+
setSummaryValue(ref.apiName || ref.name || ref.key, ref.referenceField || ref.field || ref.path);
|
|
64024
|
+
}
|
|
64025
|
+
});
|
|
64026
|
+
}
|
|
64027
|
+
else if (typeof refs === 'string') {
|
|
64028
|
+
setSummaryValue(refs, refs);
|
|
64029
|
+
}
|
|
64030
|
+
else if (refs && typeof refs === 'object') {
|
|
64031
|
+
Object.keys(refs).forEach(apiName => setSummaryValue(apiName, refs[apiName]));
|
|
64032
|
+
}
|
|
64033
|
+
(ques.fieldsMeta || [])
|
|
64034
|
+
.filter((column) => column?.summaryRow && column?.apiName && !this.hasBindableValue(summaryValues[column.apiName]))
|
|
64035
|
+
.forEach((column) => {
|
|
64036
|
+
const computedValue = this.computeTableSummaryValue(column, rows, summaryValues, dataBind);
|
|
64037
|
+
if (this.hasBindableValue(computedValue)) {
|
|
64038
|
+
summaryValues[column.apiName] = computedValue;
|
|
64039
|
+
}
|
|
64040
|
+
});
|
|
64041
|
+
return summaryValues;
|
|
64042
|
+
}
|
|
64043
|
+
// SKS26MAY26 table summary column data bind
|
|
64044
|
+
computeTableSummaryValue(column, rows, summaryValues, dataBind = this.dataBind) {
|
|
64045
|
+
const operation = (column?.operation || '').toString().toLowerCase();
|
|
64046
|
+
if (operation === 'sum' && column?.column) {
|
|
64047
|
+
return rows.reduce((total, row) => total + this.toNumericValue(this.dataService.getValue(row, column.column)), 0);
|
|
64048
|
+
}
|
|
64049
|
+
if (operation === 'subtract' && Array.isArray(column?.operands) && column.operands.length > 0) {
|
|
64050
|
+
const [first, ...rest] = column.operands.map((operand) => this.resolveSummaryOperand(operand, rows, summaryValues, dataBind));
|
|
64051
|
+
return rest.reduce((total, value) => total - value, first);
|
|
64052
|
+
}
|
|
64053
|
+
return undefined;
|
|
64054
|
+
}
|
|
64055
|
+
resolveSummaryOperand(operand, rows, summaryValues, dataBind = this.dataBind) {
|
|
64056
|
+
if (this.hasBindableValue(summaryValues?.[operand])) {
|
|
64057
|
+
return this.toNumericValue(summaryValues[operand]);
|
|
64058
|
+
}
|
|
64059
|
+
const rootValue = this.dataService.getValue(dataBind, operand);
|
|
64060
|
+
if (this.hasBindableValue(rootValue)) {
|
|
64061
|
+
return this.toNumericValue(rootValue);
|
|
64062
|
+
}
|
|
64063
|
+
return rows.reduce((total, row) => total + this.toNumericValue(this.dataService.getValue(row, operand)), 0);
|
|
64064
|
+
}
|
|
64065
|
+
toNumericValue(value) {
|
|
64066
|
+
if (typeof value === 'number')
|
|
64067
|
+
return Number.isFinite(value) ? value : 0;
|
|
64068
|
+
const numericValue = Number(String(value ?? '').replace(/[^0-9.-]/g, ''));
|
|
64069
|
+
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
64070
|
+
}
|
|
62616
64071
|
//AP-14JUN25 - Calculates contrast text color (black or white) based on background color
|
|
62617
64072
|
getContrastColor(bgColor = '#000000') {
|
|
62618
64073
|
// Convert hex to RGB
|
|
@@ -62640,15 +64095,21 @@ class PdfDesignerComponent {
|
|
|
62640
64095
|
{ "type": "image", "img": "Image", "label": "Image" },
|
|
62641
64096
|
{ "type": "Line", "img": "line", "label": "Line" },
|
|
62642
64097
|
{ "type": "Space", "img": "space", "label": "Space" },
|
|
64098
|
+
{ "type": "Section", "img": "TextArea", "label": "Section Bar" },
|
|
64099
|
+
{ "type": "RichText", "img": "TextArea", "label": "Rich Text" },
|
|
64100
|
+
{ "type": "Note", "img": "Text", "label": "Note Box" },
|
|
64101
|
+
{ "type": "PageBreak", "img": "space", "label": "Page Break" },
|
|
62643
64102
|
{ "type": "Table", "img": "Table", "label": "Table" },
|
|
62644
64103
|
{ "type": "Pdf", "img": "Search", "label": "Pdf" },
|
|
64104
|
+
{ "type": "PdfMake", "img": "Search", "label": "PdfMake JSON" },
|
|
62645
64105
|
{ "type": "signaturePad", "img": "space", "label": "Signature Pad" },
|
|
62646
64106
|
];
|
|
62647
64107
|
this.elementDisabledArray = {
|
|
62648
64108
|
Table: [
|
|
62649
64109
|
'Pdf', 'Calendar', "Boolean", 'List', 'Table', 'Checkbox', 'Radio',
|
|
62650
64110
|
'Dropdown', 'MultiSelect', 'RichTextArea', 'Number', 'Label', 'image',
|
|
62651
|
-
'Email', 'Date', 'Time', 'DateTime', 'Line', 'Space'
|
|
64111
|
+
'Email', 'Date', 'Time', 'DateTime', 'Line', 'Space', 'Section',
|
|
64112
|
+
'RichText', 'Note', 'PageBreak', 'PdfMake'
|
|
62652
64113
|
]
|
|
62653
64114
|
};
|
|
62654
64115
|
if (!this.isPreview) {
|
|
@@ -62766,11 +64227,66 @@ class PdfDesignerComponent {
|
|
|
62766
64227
|
width: 100,
|
|
62767
64228
|
styleClass: unique_id,
|
|
62768
64229
|
};
|
|
64230
|
+
this.applyAdvancedElementDefaults(newElement);
|
|
62769
64231
|
this.pdfDesignerService.addElement(newElement);
|
|
62770
64232
|
this.pdfElements = this.pdfDesignerService.getElements();
|
|
62771
64233
|
this.addTable = true;
|
|
62772
64234
|
}
|
|
62773
64235
|
}
|
|
64236
|
+
// SKS26MAY26 direct pdf content insert
|
|
64237
|
+
applyAdvancedElementDefaults(element) {
|
|
64238
|
+
if (element.type === 'Section') {
|
|
64239
|
+
element.value = element.value || 'Section Title';
|
|
64240
|
+
element.style = {
|
|
64241
|
+
...element.style,
|
|
64242
|
+
bold: true,
|
|
64243
|
+
color: '#ffffff',
|
|
64244
|
+
fillColor: '#2f9e44',
|
|
64245
|
+
fontSize: 12,
|
|
64246
|
+
margin: [0, 8, 0, 0]
|
|
64247
|
+
};
|
|
64248
|
+
element.innerMargin = [8, 6, 8, 6];
|
|
64249
|
+
}
|
|
64250
|
+
if (element.type === 'RichText') {
|
|
64251
|
+
element.value = element.value || 'Scope of Work\n• First bullet point\n• Second bullet point';
|
|
64252
|
+
element.headingFirstLine = true;
|
|
64253
|
+
element.style = {
|
|
64254
|
+
...element.style,
|
|
64255
|
+
color: '#555555',
|
|
64256
|
+
headingColor: '#2f9e44',
|
|
64257
|
+
fontSize: 11,
|
|
64258
|
+
lineHeight: 1.35,
|
|
64259
|
+
margin: [0, 8, 0, 8]
|
|
64260
|
+
};
|
|
64261
|
+
}
|
|
64262
|
+
if (element.type === 'Note') {
|
|
64263
|
+
element.value = element.value || 'Modules: CRM, ESS, Projects';
|
|
64264
|
+
element.style = {
|
|
64265
|
+
...element.style,
|
|
64266
|
+
color: '#555555',
|
|
64267
|
+
fillColor: '#e7f2e8',
|
|
64268
|
+
borderColor: '#2f9e44',
|
|
64269
|
+
fontSize: 10,
|
|
64270
|
+
margin: [0, 8, 0, 8]
|
|
64271
|
+
};
|
|
64272
|
+
element.innerMargin = [8, 6, 8, 6];
|
|
64273
|
+
}
|
|
64274
|
+
if (element.type === 'PageBreak') {
|
|
64275
|
+
element.value = element.value || 'Page break';
|
|
64276
|
+
element.pageBreak = 'after';
|
|
64277
|
+
element.style = {
|
|
64278
|
+
...element.style,
|
|
64279
|
+
color: '#64748b',
|
|
64280
|
+
fontSize: 10,
|
|
64281
|
+
margin: [0, 12, 0, 12]
|
|
64282
|
+
};
|
|
64283
|
+
}
|
|
64284
|
+
if (element.type === 'PdfMake') {
|
|
64285
|
+
element.value = element.value || 'Advanced pdfmake block';
|
|
64286
|
+
element.pdfMakeContent = element.pdfMakeContent || JSON.stringify({ text: 'Advanced pdfmake content', margin: [0, 8, 0, 8] }, null, 2);
|
|
64287
|
+
element.pdfMakeStyles = element.pdfMakeStyles || '{}';
|
|
64288
|
+
}
|
|
64289
|
+
}
|
|
62774
64290
|
//AP-14JUN25 - Handles textarea input: auto-resizes and updates the field content
|
|
62775
64291
|
onTextAreaInput(event, field) {
|
|
62776
64292
|
const textarea = event.target;
|
|
@@ -62889,9 +64405,15 @@ class PdfDesignerComponent {
|
|
|
62889
64405
|
addTableData(fieldId, fieldName) {
|
|
62890
64406
|
// this.pdfDesignerService.addTablefieldData(tableElement);
|
|
62891
64407
|
}
|
|
62892
|
-
columnSelected(event) {
|
|
64408
|
+
columnSelected(tableIndexOrEvent, event, mouseEvent) {
|
|
64409
|
+
mouseEvent?.stopPropagation();
|
|
64410
|
+
if (typeof tableIndexOrEvent === 'number') {
|
|
64411
|
+
this.selectedFieldIndex = tableIndexOrEvent;
|
|
64412
|
+
this.pdfDesignerService.setSelectedTableElement(tableIndexOrEvent, event);
|
|
64413
|
+
return;
|
|
64414
|
+
}
|
|
62893
64415
|
// SKS19MAR25 table column update
|
|
62894
|
-
this.pdfDesignerService.setSelectedTableElement(this.selectedFieldIndex,
|
|
64416
|
+
this.pdfDesignerService.setSelectedTableElement(this.selectedFieldIndex, tableIndexOrEvent);
|
|
62895
64417
|
}
|
|
62896
64418
|
removeColumn(event) {
|
|
62897
64419
|
this.pdfDesignerService.removeSelectedTableElement(this.selectedFieldIndex, event);
|
|
@@ -63009,15 +64531,19 @@ class PdfDesignerComponent {
|
|
|
63009
64531
|
};
|
|
63010
64532
|
}
|
|
63011
64533
|
zoomOut() {
|
|
64534
|
+
// SKS26MAY26 Decrease scale, ensure it doesn't go below a minimum (e.g., 0.1)
|
|
64535
|
+
const newScale = Math.max((this.transform.scale || 1) - 0.1, 0.1);
|
|
63012
64536
|
this.transform = {
|
|
63013
64537
|
...this.transform,
|
|
63014
|
-
scale:
|
|
64538
|
+
scale: newScale
|
|
63015
64539
|
};
|
|
63016
64540
|
}
|
|
63017
64541
|
zoomIn() {
|
|
64542
|
+
// SKS26MAY26 Increase scale
|
|
64543
|
+
const newScale = (this.transform.scale || 1) + 0.1;
|
|
63018
64544
|
this.transform = {
|
|
63019
64545
|
...this.transform,
|
|
63020
|
-
scale:
|
|
64546
|
+
scale: newScale
|
|
63021
64547
|
};
|
|
63022
64548
|
}
|
|
63023
64549
|
rotateLeft() {
|
|
@@ -63135,15 +64661,22 @@ class PdfDesignerComponent {
|
|
|
63135
64661
|
}
|
|
63136
64662
|
pdfSaveHandler(event) {
|
|
63137
64663
|
if (event === 'preview') {
|
|
63138
|
-
this.pdfSaveHandlerEmit.emit(
|
|
64664
|
+
this.pdfSaveHandlerEmit.emit(this.exportPdf('preview'));
|
|
63139
64665
|
}
|
|
63140
64666
|
else if (event === 'download') {
|
|
63141
|
-
this.pdfSaveHandlerEmit.emit(
|
|
64667
|
+
this.pdfSaveHandlerEmit.emit(this.exportPdf('download'));
|
|
63142
64668
|
}
|
|
63143
64669
|
else {
|
|
63144
64670
|
this.pdfSaveHandlerEmit.emit(event);
|
|
63145
64671
|
}
|
|
63146
64672
|
}
|
|
64673
|
+
// SKS26MAY26 export pdf
|
|
64674
|
+
exportPdf(action = 'definition', dataBind = this.dataBind) {
|
|
64675
|
+
const sourceElements = this.pdfDesignerService.getElements()?.length ? this.pdfDesignerService.getElements() : this.pdfElements;
|
|
64676
|
+
const payload = this.pdfDesignerService.buildPdfOutput(this.pdfDesignerService.getBook(), dataBind, this.pdfDefinitionOptions, action, sourceElements);
|
|
64677
|
+
this.pdfOutputEmit.emit(payload);
|
|
64678
|
+
return payload;
|
|
64679
|
+
}
|
|
63147
64680
|
// SKS12SEP25 color selection
|
|
63148
64681
|
selectColor(color) {
|
|
63149
64682
|
this.selectedColor = color;
|
|
@@ -63269,12 +64802,297 @@ class PdfDesignerComponent {
|
|
|
63269
64802
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
63270
64803
|
field.value = '';
|
|
63271
64804
|
}
|
|
64805
|
+
// SKS26MAY26 pdf setting
|
|
64806
|
+
getPdfSettings() {
|
|
64807
|
+
if (!this.pdf) {
|
|
64808
|
+
this.pdf = this.pdfDesignerService.getBook();
|
|
64809
|
+
}
|
|
64810
|
+
if (!this.pdf)
|
|
64811
|
+
return {};
|
|
64812
|
+
if (!this.pdf.pdfSettings) {
|
|
64813
|
+
this.pdf.pdfSettings = this.pdfDesignerService.getDefaultPdfSettings();
|
|
64814
|
+
}
|
|
64815
|
+
return this.pdf.pdfSettings;
|
|
64816
|
+
}
|
|
64817
|
+
getPageBackgroundColor() {
|
|
64818
|
+
return this.getPdfSettings()?.backgroundColor || '#ffffff';
|
|
64819
|
+
}
|
|
64820
|
+
getPageContentStyle() {
|
|
64821
|
+
const margin = this.normalizeMargin(this.getPdfSettings()?.pageMargins || [40, 40, 40, 72]);
|
|
64822
|
+
return {
|
|
64823
|
+
'padding-left': `${margin[0]}px`,
|
|
64824
|
+
'padding-top': `${margin[1]}px`,
|
|
64825
|
+
'padding-right': `${margin[2]}px`,
|
|
64826
|
+
'padding-bottom': `${margin[3]}px`
|
|
64827
|
+
};
|
|
64828
|
+
}
|
|
64829
|
+
getWatermarkText() {
|
|
64830
|
+
const watermark = this.getPdfSettings()?.watermark;
|
|
64831
|
+
return watermark?.enabled ? (watermark?.text || '') : '';
|
|
64832
|
+
}
|
|
64833
|
+
getWatermarkStyle() {
|
|
64834
|
+
const watermark = this.getPdfSettings()?.watermark || {};
|
|
64835
|
+
return {
|
|
64836
|
+
color: watermark.color || '#9ca3af',
|
|
64837
|
+
opacity: watermark.opacity ?? 0.16,
|
|
64838
|
+
'font-size': `${watermark.fontSize || 64}px`,
|
|
64839
|
+
transform: `translate(-50%, -50%) rotate(${watermark.angle ?? -32}deg)`
|
|
64840
|
+
};
|
|
64841
|
+
}
|
|
64842
|
+
shouldShowFooterOnCanvas() {
|
|
64843
|
+
const footer = this.getPdfSettings()?.footer;
|
|
64844
|
+
return !!footer?.enabled && !!(footer?.text || footer?.content || footer?.leftText || footer?.centerText || footer?.rightText);
|
|
64845
|
+
}
|
|
64846
|
+
shouldShowHeaderOnCanvas() {
|
|
64847
|
+
const header = this.getPdfSettings()?.header;
|
|
64848
|
+
return !!header?.enabled && !!(header?.text || header?.content || header?.leftText || header?.centerText || header?.rightText);
|
|
64849
|
+
}
|
|
64850
|
+
getHeaderStyle() {
|
|
64851
|
+
const header = this.getPdfSettings()?.header || {};
|
|
64852
|
+
const margin = this.normalizeMargin(header.margin || [40, 20, 40, 0]);
|
|
64853
|
+
return {
|
|
64854
|
+
left: `${margin[0]}px`,
|
|
64855
|
+
right: `${margin[2]}px`,
|
|
64856
|
+
top: `${margin[1]}px`,
|
|
64857
|
+
color: header.color || '#666666',
|
|
64858
|
+
'font-size': `${header.fontSize || 9}px`
|
|
64859
|
+
};
|
|
64860
|
+
}
|
|
64861
|
+
getFooterStyle() {
|
|
64862
|
+
const footer = this.getPdfSettings()?.footer || {};
|
|
64863
|
+
const margin = this.normalizeMargin(footer.margin || [40, 12, 40, 0]);
|
|
64864
|
+
return {
|
|
64865
|
+
left: `${margin[0]}px`,
|
|
64866
|
+
right: `${margin[2]}px`,
|
|
64867
|
+
bottom: `${margin[3]}px`,
|
|
64868
|
+
color: footer.color || '#666666',
|
|
64869
|
+
'font-size': `${footer.fontSize || 9}px`,
|
|
64870
|
+
'text-align': footer.alignment || 'center'
|
|
64871
|
+
};
|
|
64872
|
+
}
|
|
64873
|
+
getRunningBandColumns(type) {
|
|
64874
|
+
const settings = this.getPdfSettings()?.[type] || {};
|
|
64875
|
+
if (settings.leftText || settings.centerText || settings.rightText) {
|
|
64876
|
+
return [settings.leftText || '', settings.centerText || '', settings.rightText || ''];
|
|
64877
|
+
}
|
|
64878
|
+
return [settings.text || ''];
|
|
64879
|
+
}
|
|
64880
|
+
hasRunningBandBorder(type) {
|
|
64881
|
+
const settings = this.getPdfSettings()?.[type] || {};
|
|
64882
|
+
return type === 'header' ? !!settings.bottomBorder : !!settings.topBorder;
|
|
64883
|
+
}
|
|
64884
|
+
getRunningBandBorderStyle(type) {
|
|
64885
|
+
const settings = this.getPdfSettings()?.[type] || {};
|
|
64886
|
+
return {
|
|
64887
|
+
'border-top': type === 'footer' && settings.topBorder ? `${settings.borderWidth || 1}px solid ${settings.borderColor || '#2f9e44'}` : null,
|
|
64888
|
+
'border-bottom': type === 'header' && settings.bottomBorder ? `${settings.borderWidth || 1}px solid ${settings.borderColor || '#2f9e44'}` : null
|
|
64889
|
+
};
|
|
64890
|
+
}
|
|
64891
|
+
getElementTextStyle(field) {
|
|
64892
|
+
const style = field?.style || {};
|
|
64893
|
+
return {
|
|
64894
|
+
'font-family': style.font || 'Helvetica Neue',
|
|
64895
|
+
'font-size': `${Number(style.fontSize) || Number(field?.fontSize) || 12}px`,
|
|
64896
|
+
'font-weight': style.bold ? '700' : (style.fontWeight || field?.fontWeight || '400'),
|
|
64897
|
+
'font-style': style.italic ? 'italic' : 'normal',
|
|
64898
|
+
color: style.color || '#000000',
|
|
64899
|
+
'text-align': style.alignment || 'left',
|
|
64900
|
+
'background-color': style.fillColor || style.backgroundColor || 'transparent',
|
|
64901
|
+
padding: this.marginToCss(style.margin || field?.margin || [0, 0, 0, 0]),
|
|
64902
|
+
'line-height': style.lineHeight || 1.25,
|
|
64903
|
+
'letter-spacing': `${Number(style.characterSpacing) || 0}px`,
|
|
64904
|
+
'text-decoration': style.decoration === 'lineThrough' ? 'line-through' : (style.decoration || 'none'),
|
|
64905
|
+
opacity: style.opacity ?? 1,
|
|
64906
|
+
border: style.borderColor ? `1px solid ${style.borderColor}` : 'none',
|
|
64907
|
+
'--pdf-heading-color': style.headingColor || style.color || '#2f9e44'
|
|
64908
|
+
};
|
|
64909
|
+
}
|
|
64910
|
+
getElementLabelStyle(field) {
|
|
64911
|
+
const style = field?.style || {};
|
|
64912
|
+
return {
|
|
64913
|
+
color: style.labelColor || style.color || '#222222',
|
|
64914
|
+
'font-size': `${Number(style.labelFontSize) || Number(style.fontSize) || 12}px`,
|
|
64915
|
+
'font-weight': style.labelBold === false ? '400' : '700',
|
|
64916
|
+
'text-align': style.alignment || 'left'
|
|
64917
|
+
};
|
|
64918
|
+
}
|
|
64919
|
+
displayFieldValue(field) {
|
|
64920
|
+
if (!field)
|
|
64921
|
+
return '';
|
|
64922
|
+
if (field.type === 'currency') {
|
|
64923
|
+
return this.formatCurrencyValue(field.value, field);
|
|
64924
|
+
}
|
|
64925
|
+
if (field.type === 'boolean') {
|
|
64926
|
+
return field.value === true || field.value === 'true' ? 'Yes' : 'No';
|
|
64927
|
+
}
|
|
64928
|
+
return field.value ?? '';
|
|
64929
|
+
}
|
|
64930
|
+
shouldRenderStyledTextLines(field) {
|
|
64931
|
+
return field?.type === 'text' && (field?.headingFirstLine === true || this.isQuotationHeadingText(field));
|
|
64932
|
+
}
|
|
64933
|
+
getStyledTextLines(field) {
|
|
64934
|
+
return String(this.displayFieldValue(field) || '').split(/\r?\n/);
|
|
64935
|
+
}
|
|
64936
|
+
isTextHeadingLine(field, index, line) {
|
|
64937
|
+
return (field?.headingFirstLine === true || this.isQuotationHeadingText(field)) && index === 0 && String(line || '').trim().length > 0;
|
|
64938
|
+
}
|
|
64939
|
+
getStyledTextLineStyle(field, index, line) {
|
|
64940
|
+
const style = field?.style || {};
|
|
64941
|
+
if (this.isTextHeadingLine(field, index, line)) {
|
|
64942
|
+
return {
|
|
64943
|
+
color: style.headingColor || this.getDefaultTextHeadingColor(field) || style.color || '#2f9e44',
|
|
64944
|
+
'font-size': `${Number(style.headingFontSize) || this.getDefaultTextHeadingSize(field) || Number(style.fontSize) || 12}px`,
|
|
64945
|
+
'font-weight': style.headingBold === false || (style.headingBold === undefined && this.isQuotationHeadingText(field)) ? '400' : '700',
|
|
64946
|
+
margin: this.marginToCss(style.headingMargin || [0, 0, 0, 2])
|
|
64947
|
+
};
|
|
64948
|
+
}
|
|
64949
|
+
if (!line) {
|
|
64950
|
+
return {
|
|
64951
|
+
height: `${Number(style.blankLineHeight) || 10}px`,
|
|
64952
|
+
'min-height': `${Number(style.blankLineHeight) || 10}px`
|
|
64953
|
+
};
|
|
64954
|
+
}
|
|
64955
|
+
return {};
|
|
64956
|
+
}
|
|
64957
|
+
isQuotationHeadingText(field) {
|
|
64958
|
+
const firstLine = String(field?.value || '').split(/\r?\n/)[0]?.trim();
|
|
64959
|
+
return firstLine === 'VALAR HR' || firstLine === 'QUOTATION';
|
|
64960
|
+
}
|
|
64961
|
+
getDefaultTextHeadingColor(field) {
|
|
64962
|
+
return this.isQuotationHeadingText(field) ? '#3fa34d' : '';
|
|
64963
|
+
}
|
|
64964
|
+
getDefaultTextHeadingSize(field) {
|
|
64965
|
+
return this.isQuotationHeadingText(field) ? 24 : 0;
|
|
64966
|
+
}
|
|
64967
|
+
getRichTextLines(field) {
|
|
64968
|
+
return String(field?.value || '').split(/\r?\n/).filter(line => line.trim().length > 0);
|
|
64969
|
+
}
|
|
64970
|
+
isRichTextBullet(line) {
|
|
64971
|
+
return /^[•*-]\s+/.test(line.trim());
|
|
64972
|
+
}
|
|
64973
|
+
getRichTextLineText(line) {
|
|
64974
|
+
return line.trim().replace(/^[•*-]\s+/, '');
|
|
64975
|
+
}
|
|
64976
|
+
isRichTextHeading(field, index, line) {
|
|
64977
|
+
return field?.headingFirstLine !== false && index === 0 && !this.isRichTextBullet(line);
|
|
64978
|
+
}
|
|
64979
|
+
getPdfMakePreview(field) {
|
|
64980
|
+
return field?.pdfMakeContent || field?.value || '';
|
|
64981
|
+
}
|
|
64982
|
+
getMainTableColumns(field) {
|
|
64983
|
+
const columns = Array.isArray(field?.fieldsMeta) ? field.fieldsMeta : [];
|
|
64984
|
+
return columns.filter(column => column?.hideInPdf !== true && column?.isHidden !== true && column?.summaryRow !== true);
|
|
64985
|
+
}
|
|
64986
|
+
getSummaryTableColumns(field) {
|
|
64987
|
+
const columns = Array.isArray(field?.fieldsMeta) ? field.fieldsMeta : [];
|
|
64988
|
+
return columns.filter(column => column?.hideInPdf !== true && column?.isHidden !== true && column?.summaryRow === true);
|
|
64989
|
+
}
|
|
64990
|
+
getTableRows(field) {
|
|
64991
|
+
return field?.value?.data || [];
|
|
64992
|
+
}
|
|
64993
|
+
getTableHeaderStyle(column) {
|
|
64994
|
+
const style = column?.style || {};
|
|
64995
|
+
return {
|
|
64996
|
+
'background-color': style.fillColor || '#f1f5f9',
|
|
64997
|
+
color: style.color || '#111827',
|
|
64998
|
+
'text-align': style.alignment || 'left',
|
|
64999
|
+
width: this.getColumnCssWidth(column)
|
|
65000
|
+
};
|
|
65001
|
+
}
|
|
65002
|
+
getTableCellStyle(column, rowIndex) {
|
|
65003
|
+
const style = column?.style || {};
|
|
65004
|
+
return {
|
|
65005
|
+
'text-align': style.alignment || (column?.fldType === 'currency' ? 'right' : 'left'),
|
|
65006
|
+
width: this.getColumnCssWidth(column),
|
|
65007
|
+
'background-color': rowIndex % 2 === 1 ? '#f8fafc' : '#ffffff',
|
|
65008
|
+
color: style.cellColor || '#374151'
|
|
65009
|
+
};
|
|
65010
|
+
}
|
|
65011
|
+
getTableSummaryLabelColspan(field) {
|
|
65012
|
+
return Math.max(this.getMainTableColumns(field).length - 1, 1);
|
|
65013
|
+
}
|
|
65014
|
+
getColumnCssWidth(column) {
|
|
65015
|
+
const width = column?.style?.width;
|
|
65016
|
+
return typeof width === 'number' ? `${width}px` : 'auto';
|
|
65017
|
+
}
|
|
65018
|
+
getTableCellValue(row, column) {
|
|
65019
|
+
const value = this.dataService.getValue(row, column?.apiName);
|
|
65020
|
+
if (column?.fldType === 'currency') {
|
|
65021
|
+
return this.formatCurrencyValue(value, column);
|
|
65022
|
+
}
|
|
65023
|
+
return value ?? '';
|
|
65024
|
+
}
|
|
65025
|
+
getTableSummaryValue(field, column) {
|
|
65026
|
+
const summaryValues = field?.value?.summaryValues || field?.value?.summaryValue || {};
|
|
65027
|
+
const value = this.dataService.getValue(summaryValues, column?.apiName);
|
|
65028
|
+
if (column?.fldType === 'currency') {
|
|
65029
|
+
return this.formatCurrencyValue(value, column);
|
|
65030
|
+
}
|
|
65031
|
+
return value ?? '';
|
|
65032
|
+
}
|
|
65033
|
+
isSelectedTableColumn(column) {
|
|
65034
|
+
return !this.isPreview && !!column?.uniqueIdentifier && this.pdfDesignerService.getSelectTableColumn() === column.uniqueIdentifier;
|
|
65035
|
+
}
|
|
65036
|
+
formatCurrencyValue(value, field) {
|
|
65037
|
+
value = this.normalizeCurrencyValue(value);
|
|
65038
|
+
if (value === undefined || value === null || value === '')
|
|
65039
|
+
return '';
|
|
65040
|
+
if (field && Object.prototype.hasOwnProperty.call(field, 'currencySymbol')) {
|
|
65041
|
+
return `${field.currencySymbol ? field.currencySymbol + ' ' : ''}${value}`;
|
|
65042
|
+
}
|
|
65043
|
+
const currency = this.resolveCurrencyOption();
|
|
65044
|
+
return `${currency?.symbol || 'INR'} ${value}`;
|
|
65045
|
+
}
|
|
65046
|
+
getCurrencySymbol() {
|
|
65047
|
+
return this.resolveCurrencyOption()?.symbol || '';
|
|
65048
|
+
}
|
|
65049
|
+
normalizeCurrencyValue(value) {
|
|
65050
|
+
if (!value || typeof value !== 'object')
|
|
65051
|
+
return value;
|
|
65052
|
+
const scalarValue = value.value ?? value.amount ?? value.total ?? value.totalAmount ?? value.taxAmount;
|
|
65053
|
+
if (scalarValue !== undefined && scalarValue !== null && typeof scalarValue !== 'object') {
|
|
65054
|
+
return scalarValue;
|
|
65055
|
+
}
|
|
65056
|
+
if (Array.isArray(value.group)) {
|
|
65057
|
+
return value.group.reduce((total, entry) => {
|
|
65058
|
+
return total + this.toNumericValue(entry?.value ?? entry?.amount ?? entry?.taxAmount ?? entry?.total);
|
|
65059
|
+
}, 0);
|
|
65060
|
+
}
|
|
65061
|
+
return '';
|
|
65062
|
+
}
|
|
65063
|
+
resolveCurrencyOption() {
|
|
65064
|
+
const configuredCurrency = this.pdf?.currency || this.pdf?.pdfSettings?.currency;
|
|
65065
|
+
if (configuredCurrency?.symbol || configuredCurrency?.currencySymbol) {
|
|
65066
|
+
return {
|
|
65067
|
+
code: configuredCurrency.code || configuredCurrency.currencyCode,
|
|
65068
|
+
name: configuredCurrency.name || configuredCurrency.currencyName,
|
|
65069
|
+
symbol: configuredCurrency.symbol || configuredCurrency.currencySymbol
|
|
65070
|
+
};
|
|
65071
|
+
}
|
|
65072
|
+
const currencyCode = this.dataBind?.currencyCode || this.dataBind?.customer?.currencyCode || this.pdf?.currencyCode || this.pdf?.pdfSettings?.currencyCode;
|
|
65073
|
+
if (currencyCode) {
|
|
65074
|
+
const currencyOption = this.countryService.getCountryData(['currencies'])?.find((option) => option.code === currencyCode);
|
|
65075
|
+
if (currencyOption)
|
|
65076
|
+
return currencyOption;
|
|
65077
|
+
}
|
|
65078
|
+
return this.countryService.getCurrentCurrency();
|
|
65079
|
+
}
|
|
65080
|
+
normalizeMargin(margin) {
|
|
65081
|
+
const fallback = [0, 0, 0, 0];
|
|
65082
|
+
if (!Array.isArray(margin))
|
|
65083
|
+
return fallback;
|
|
65084
|
+
return [0, 1, 2, 3].map(index => Number(margin[index]) || 0);
|
|
65085
|
+
}
|
|
65086
|
+
marginToCss(margin) {
|
|
65087
|
+
const normalized = this.normalizeMargin(margin);
|
|
65088
|
+
return `${normalized[1]}px ${normalized[2]}px ${normalized[3]}px ${normalized[0]}px`;
|
|
65089
|
+
}
|
|
63272
65090
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfDesignerComponent, deps: [{ token: DataService }, { token: ChangeService }, { token: CountryService }, { token: PdfDesignerService }], target: i0.ɵɵFactoryTarget.Component });
|
|
63273
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: PdfDesignerComponent, isStandalone: true, selector: "app-pdf-designer", inputs: { pdfJSON: "pdfJSON", bookletId: "bookletId", isPreview: "isPreview", from: "from", dataBind: "dataBind", isPropertyHide: "isPropertyHide" }, outputs: { pdfSaveHandlerEmit: "pdfSaveHandlerEmit", templateMode: "templateMode", pdfPreviewEmit: "pdfPreviewEmit" }, viewQueries: [{ propertyName: "textareas", predicate: ["autoTextarea"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"form-container\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"center-frame\" [ngClass]=\"{'isPreview': isPreview}\">\n <!-- Form Builder Section All Elements -->\n <div *ngIf=\"!isPreview\" class=\"form-builder\">\n <ng-container *ngFor=\"let element of elementsList\">\n <div\n class=\"element\"\n [class.disabled]=\"selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\"\n (click)=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)) && addElement(element.type)\"\n [draggable]=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type))\"\n [matTooltip]=\"\n selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\n ? ('THIS_ELEMENT_NOT_SUPPORTED' | nxtCustomTranslate : 'This element is not supported when a ') +\n (selectedElement?.type || ('CERTAIN_ELEMENT' | nxtCustomTranslate : 'certain element')) +\n (' IS_PRESENT' | nxtCustomTranslate : ' is present')\n : null\n \"\n >\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div> \n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div> \n <div [ngStyle]=\"!isPreview ? { 'display': 'flex', 'width': '75%' } : { 'display': 'flex', 'width': '100%' }\">\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div *ngIf=\"!isPreview\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;margin-bottom:10px\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"display: flex;justify-content: space-between;\">\n <div *ngIf=\"pdf\" style=\"padding-left: 10px;\">\n <div *ngIf=\"pdf.title == ''\" style=\"color:#3f4a525c\">{{ 'HEADING' | nxtCustomTranslate : 'Heading' }}</div>\n <div *ngIf=\"pdf.title !== ''\">{{pdf.title}}</div>\n </div>\n <div class=\"action-buttons\">\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let field of pdfElements; let i = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i)\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div *ngIf=\"!isPreview \" class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (field.lineStyle?.toLowerCase() || 'solid'),\n 'color': field?.style?.color || '#000000',\n 'margin-top': (field?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (field?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n \n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i && !isPreview \" draggable=\"true && !isPreview \"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': field?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(field)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(field)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"field.imageData\" [style.width.px]=\"field.imageSize?.width || 100\" [style.height.px]=\"field.imageSize?.height || 100\" />\n </div>\n \n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(field, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Space Element -->\n <div *ngIf=\"field?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SKS21NOV25 signaturePad -->\n <div *ngIf=\"field?.type === 'signaturePad'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- SKS21NOV25 Signature Pad Field -->\n <div class=\"signature-pad-container\">\n <!-- SKS21NOV25 Builder mode (editable) -->\n <canvas *ngIf=\"!isPreview\"\n #sigCanvas\n [id]=\"field.id\"\n class=\"signature-pad\"\n (pointerdown)=\"pointerDown($event, field)\"\n (pointermove)=\"pointerMove($event, field)\"\n (pointerup)=\"pointerUp($event, field)\"\n (pointercancel)=\"pointerUp($event, field)\"\n (lostpointercapture)=\"pointerUp($event, field)\">\n </canvas>\n\n <!-- SKS21NOV25 Preview mode (static image) -->\n <img *ngIf=\"isPreview && field.value\"\n [src]=\"field.value\"\n class=\"signature-preview\" />\n <!-- SKS21NOV25 Empty state in preview -->\n <div *ngIf=\"isPreview && !field.value\"\n class=\"signature-placeholder\">\n Signature\n </div>\n <!-- SKS21NOV25 Builder buttons -->\n <div *ngIf=\"!isPreview\" class=\"signature-actions\">\n <button type=\"button\" (click)=\"onQuestionChange($event.value, field)\">Save</button>\n <button type=\"button\" (click)=\"clearSignature(field)\">Clear</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- SKS16SEP25 Date, currency, boolean, text -->\n <div *ngIf=\"field?.type === 'date' || field?.type === 'currency' || field?.type === 'boolean' || field?.type === 'text'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- AP-04JUN25 - replace custom date picker -->\n <nxt-input [type]=\"field.type === 'boolean' ? 'checkbox' : field?.type === 'text' ? 'textarea' : field.type\" [mode]=\"'edit'\" [value]=\"field.value\" [question]=\"field\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"field.isReadOnly\"\n [currency] = 'selectedCurrency' [label]=\"field?.questionText\" (click)=\"field?.type === 'text' ? openTextSettings(field, $event) : ''\"\n [inputWeight]=\"\" [showLabel]=\"field?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"field.question ? field.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"field?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, field)\">\n </nxt-input>\n </div>\n </div>\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === field\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n \n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n \n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n \n \n \n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div>\n </div>\n \n <!-- Pdf -->\n <div *ngIf=\"field?.type === 'Pdf'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg> \n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <!-- <lib-booklet [bookletJSON]=\"field.pdfReferenceQuestions\"></lib-booklet> -->\n <div *ngIf=\"field?.pdfReferenceQuestions\" class=\"form-preview\" style=\"padding: unset !important;\">\n <ng-container *ngFor=\"let pdfField of field?.pdfReferenceQuestions[field?.pdfReference]; let j = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"pdfField?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: pdfField.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i,j); $event.stopPropagation();\" [class.highlight]=\"selectedFieldIndex === j && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, j)\" (dragover)=\"onDragOver($event, j)\"\n (drop)=\"onDrop($event, j)\">\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (pdfField.lineStyle?.toLowerCase() || 'solid'),\n 'color': pdfField?.style?.color || '#000000',\n 'margin-top': (pdfField?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (pdfField?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"pdfField?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [class.highlight]=\"selectedFieldIndex === j && !isPreview \"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px',\n \n \n display: pdfField.isHidden ? 'none' : 'block' \n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': pdfField?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"pdfField.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(pdfField)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(pdfField)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"pdfField.imageData\" [style.width.px]=\"pdfField.imageSize?.width || 100\" [style.height.px]=\"pdfField.imageSize?.height || 100\" />\n </div>\n\n <div *ngIf=\"!pdfField.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{j}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>{{ 'UPLOAD_IMAGE' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{j}}\" accept=\"image/*\" (change)=\"fileChangeEvent(pdfField, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"pdfField?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px',\n \n \n display: pdfField.isHidden ? 'none' : 'block' \n }\" [class.highlight]=\"selectedFieldIndex === j && !isPreview \">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(pdfField, j)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Date -->\n <!-- display: pdfField.isHidden ? 'none' : 'block' -->\n <div *ngIf=\"pdfField?.type === 'date' || pdfField?.type === 'currency' || pdfField?.type === 'boolean' || pdfField?.type === 'text'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px ' ,\n }\"[class.highlight]=\"selectedFieldIndex === j && !isPreview \">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <!-- AP-04JUN25 - replace custom date picker -->\n <nxt-input [type]=\"pdfField.type === 'boolean' ? 'checkbox' : pdfField?.type === 'text' ? 'textarea' : pdfField.type\" [mode]=\"'edit'\" [value]=\"pdfField.value\" [question]=\"pdfField\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"pdfField.isReadOnly\"\n [currency] = 'selectedCurrency' [label]=\"pdfField?.questionText\" (click)=\"pdfField?.type === 'text' ? openTextSettings(pdfField, $event) : ''\"\n [inputWeight]=\"\" [showLabel]=\"pdfField?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"pdfField.question ? pdfField.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"pdfField?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, pdfField)\">\n </nxt-input>\n </div>\n </div>\n <!--AP-05JUN25 Text Settings Toolbar: Allows editing font size, bold/italic styles, alignment, and closing the toolbar for the selected column -->\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === pdfField\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <!-- Font Size -->\n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n\n <!-- Text Color -->\n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n\n <!-- Bold -->\n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <!-- Italic -->\n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n\n <!-- Underline -->\n <!-- <button (click)=\"toggleStyle('underline')\" [class.active]=\"selectedColumn?.style?.underline\" class=\"toolbar-btn\"><u>U</u></button> -->\n <!-- Align Left -->\n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <!-- Align Center -->\n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <!-- Align Right -->\n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <!-- Close -->\n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Table -->\n <div *ngIf=\"field?.type === 'Table'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\"\n [apiMeta]=\"field?.subText\" [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\"\n tableWidth=\"auto\" isEditable=true isPreview=isPreview (columnSelected)=\"selectElement(i);columnSelected($event)\"\n [data]=\"field.value?.data\"\n [summaryValues]=\"field.value?.summaryValue\"\n (valueChange)=\"onQuestionChange($event, field)\"\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"!isPropertyHide && isPreview\" style=\"width: 25%; margin-bottom:10px\">\n <div style=\"padding-top: 0px; padding-bottom: 8px; padding-left: 8px;padding-right: 8px\">\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff;\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n <div class=\"color-picker\">\n <label>Change Color</label>\n <div class=\"colors\">\n <!-- Default colors -->\n <div class=\"color-swatch\" *ngFor=\"let color of defaultColors\" \n [style.background]=\"color\"\n (click)=\"selectColor(color)\">\n </div>\n \n <!-- Last box: custom color picker with eyedropper -->\n <label class=\"color-swatch custom-picker\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"geometricPrecision\" text-rendering=\"geometricPrecision\" image-rendering=\"optimizeQuality\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" viewBox=\"0 0 512 512\"><path fill=\"#FC3E81\" d=\"M171.11 171.836L74.204 75.761c.258-.26.517-.521.777-.78C124.688 25.274 189.751.292 254.899.013l.587 136.448c-32.992.139-62.827 13.641-84.376 35.375z\"/><path fill=\"#FD6096\" d=\"M255.486 136.461L254.899.003 256 0c70.296 0 133.967 28.342 180.232 74.212l-96.068 96.898c-21.605-21.421-51.337-34.655-84.164-34.655-.172 0-.343.005-.514.006z\"/><path fill=\"#F9B200\" d=\"M340.164 171.11l96.075-96.906c.26.258.521.517.78.777 49.707 49.707 74.689 114.77 74.968 179.918l-136.448.587c-.139-32.992-13.641-62.827-35.375-84.376z\"/><path fill=\"#C0FF66\" d=\"M375.539 255.486l136.458-.587L512 256c0 70.296-28.342 133.967-74.212 180.232l-96.898-96.068c21.421-21.605 34.655-51.337 34.655-84.164 0-.172-.005-.343-.006-.514z\"/><path fill=\"#1DD1D9\" d=\"M340.89 340.164l96.906 96.075c-.258.26-.517.521-.777.78-49.707 49.707-114.77 74.689-179.918 74.968l-.587-136.448c32.992-.139 62.827-13.641 84.376-35.375z\"/><path fill=\"#64BDFF\" d=\"M256.514 375.539l.587 136.458L256 512c-70.296 0-133.967-28.342-180.232-74.212l96.068-96.898c21.605 21.421 51.337 34.655 84.164 34.655.172 0 .343-.005.514-.006z\"/><path fill=\"#43A3F9\" d=\"M171.836 340.89l-96.075 96.906c-.26-.258-.521-.517-.78-.777C25.274 387.312.292 322.249.013 257.101l136.448-.587c.139 32.992 13.641 62.827 35.375 84.376z\"/><path fill=\"#7884EA\" d=\"M136.461 256.514l-136.458.587L0 256c0-70.296 28.342-133.967 74.212-180.232l96.898 96.068c-21.421 21.605-34.655 51.337-34.655 84.164 0 .172.005.343.006.514z\"/></svg>\n <input type=\"color\" (change)=\"selectColor($event.target.value)\">\n </label>\n </div>\n </div> \n <!-- SKS22JUL25 Dropdown -->\n <nxt-dropdown \n [options]=\"currencyOptions\"\n [id]=\"bookletId\" \n [selectedValue]=\"selectedCurrency\"\n [labelColor]=\"'#ffff'\"\n [inputTextColor]=\"'#ffff'\"\n [inputBgColor]=\"'#585653'\"\n placeholder=\"\" [from]=\"'normalDropDown'\"\n [apiMeta] = \"{'field': 'name','isObject': true}\"\n (valueChange)=\"currencyChange($event.value.valueObj)\">\n </nxt-dropdown> \n </div>\n </div>\n </div>\n </div>\n <!-- SKS13MAR25 popup conformation box -->\n <div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n </div>\n <app-pdf-properties *ngIf=\"!isPreview \" (formButtonHandler)=\"pdfSaveHandler($event)\"></app-pdf-properties>\n</div>\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 <!-- 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' | nxtCustomTranslate : '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 <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\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()\" [class.enabled]=\"transform.flipH\"\n title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n 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 </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:25%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .element:hover img{filter:invert(1)}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .element:hover .hover-label{color:#fff}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.form-builder .element:hover .dot{background-color:#ffffffb3}.field-wrapper{border-radius:5px}.field-wrapper.isPreview{background-color:transparent;border:none;border-radius:0;padding:0}.required:after{content:\"*\";color:red;margin-left:5px}.custom-input{width:100%;padding:8px;border:1px solid #DDDBDA;background-color:#fff;border-radius:5px;outline:none}.delete-icon{width:15px;height:15px}.field-container{border:1px solid #d5d5d5;background-color:#f8f8f8;transition:background .2s}.field-container.isPreview{border:none;background-color:#fff}.field-container:hover .top-right,.field-container.highlight .top-right,.label-container:hover .delete-icon{opacity:1;visibility:visible}.form-preview{width:100%;height:calc(100vh - 20px);min-height:250px;overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px;height:fit-content;max-height:calc(100vh - 20px)}.field-content{display:flex;flex-direction:column}.label-container{display:flex;justify-content:flex-end;align-items:center}.label2-container{display:flex;justify-content:space-between;align-items:center}.top-right{display:flex;align-items:center;gap:3px;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.drag-dot{height:10px;cursor:grab}.custom-input,.custom-textarea,.dropdown,.checkbox-options-container,.radio-options-container{width:100%}.form-builder .element .drag-dots:active{cursor:grabbing}.dropdown{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;background-color:#fff;font-size:14px;color:#333;outline:none;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.line-field{width:100%;margin:10px 0;background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:3px}.line-field{background-color:transparent;border:none;border-radius:0;padding:3px}.checkbox-field-container:hover{box-shadow:0 2px 8px #0000001a}.checkbox-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.label-container label{font-size:15px;font-weight:400}.required:after{content:\" *\";color:red}.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.custom-textarea{width:100%;min-height:100px;border:1px solid #ccc;border-radius:4px;padding:8px;resize:vertical}.highlight{border:1px solid #5592FD!important;background-color:#eff8ff}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer;inline-size:auto}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.element.disabled{opacity:.5;cursor:not-allowed}.form-container{display:flex;flex-wrap:wrap;border:10px solid #86A8CD}.form-container.isPreview{border:none}.center-frame{width:74%}.center-frame.isPreview{width:100%}app-pdf-properties{border-left:10px solid #86A8CD;width:25%}:host ::ng-deep .questiondiv1{padding-left:0!important;padding-right:0!important}:host ::ng-deep .form-group.content-box{padding-bottom:0!important}:host ::ng-deep .custom-textarea{min-height:40px!important}.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;height:300px;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}.text-settings-toolbar{position:absolute;display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:#fff;border:1px solid #d1d5db;padding:8px 10px;border-radius:8px;box-shadow:0 4px 12px #0000001a;z-index:65535;max-width:100%;width:auto;min-width:200px;box-sizing:border-box}.toolbar-select{padding:4px 6px;font-size:13px;border:1px solid #d1d5db;border-radius:6px;background:#fff;cursor:pointer;min-width:60px;width:auto}.toolbar-btn{background:#f3f4f6;border:1px solid #d1d5db;padding:6px 8px;border-radius:6px;cursor:pointer;font-size:13px;min-width:30px;height:30px;display:flex;align-items:center;justify-content:center}.toolbar-btn:hover{background:#e5e7eb;border-color:#9ca3af}.toolbar-btn.active{background:#005aaa;color:#fff;border-color:#005aaa}.color-label{display:flex;align-items:center}.color-box{font-weight:700;width:22px;height:22px;font-size:13px;border:1px solid #ccc;border-radius:4px;text-align:center;line-height:22px;cursor:pointer;padding:0}.color-picker-hidden{position:absolute;opacity:0;pointer-events:none;width:0;height:0}@media(max-width:600px){.text-settings-toolbar{flex-direction:row;flex-wrap:wrap;gap:6px;padding:6px;justify-content:flex-start}.toolbar-btn,.toolbar-select{font-size:12px;padding:5px}.color-box{width:20px;height:20px;font-size:12px;line-height:20px}}.action-buttons{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.action-btn{display:flex;gap:16px;padding:10px 15px;border-radius:8px;border:none}.priview-action-div{padding:10px 15px;border-radius:8px;border:none;width:100%;margin-bottom:10px}.colors{display:flex;gap:8px}.color-swatch{width:28px;height:28px;border-radius:6px;cursor:pointer;border:2px solid transparent;display:flex;align-items:center;justify-content:center}.color-swatch:hover{border:2px solid #999}.custom-picker{position:relative;overflow:hidden;padding:2px;border:1px solid gray}.custom-picker input[type=color]{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer}.picker-icon{width:16px;height:16px;pointer-events:none}.signature-pad-container{width:100%;position:relative}.signature-pad{width:100%;height:90px;border:1px dashed #aaa;border-radius:6px;touch-action:none}.signature-preview{width:100%;height:90px;object-fit:contain;border:1px solid #ccc;border-radius:6px}.signature-placeholder{width:100%;height:90px;border:1px dashed #ccc;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:12px;color:#aaa}.signature-actions{margin-top:5px;display:flex;justify-content:space-between}\n"], dependencies: [{ 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: "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: "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: PdfPropertiesComponent, selector: "app-pdf-properties", inputs: ["selectedElementType", "templateSelected"], outputs: ["formButtonHandler", "templateSaveHandler"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "summaryValues", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "hideSaveButton", "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: 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }] });
|
|
65091
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: PdfDesignerComponent, isStandalone: true, selector: "app-pdf-designer", inputs: { pdfJSON: "pdfJSON", bookletId: "bookletId", isPreview: "isPreview", from: "from", dataBind: "dataBind", isPropertyHide: "isPropertyHide", pdfDefinitionOptions: "pdfDefinitionOptions" }, outputs: { pdfSaveHandlerEmit: "pdfSaveHandlerEmit", templateMode: "templateMode", pdfPreviewEmit: "pdfPreviewEmit", pdfOutputEmit: "pdfOutputEmit" }, viewQueries: [{ propertyName: "textareas", predicate: ["autoTextarea"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"form-container\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"center-frame\" [ngClass]=\"{'isPreview': isPreview}\">\n <!-- Form Builder Section All Elements -->\n <div *ngIf=\"!isPreview\" class=\"form-builder\">\n <ng-container *ngFor=\"let element of elementsList\">\n <div\n class=\"element\"\n [class.disabled]=\"selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\"\n (click)=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)) && addElement(element.type)\"\n [draggable]=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type))\"\n [matTooltip]=\"\n selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\n ? ('THIS_ELEMENT_NOT_SUPPORTED' | nxtCustomTranslate : 'This element is not supported when a ') +\n (selectedElement?.type || ('CERTAIN_ELEMENT' | nxtCustomTranslate : 'certain element')) +\n (' IS_PRESENT' | nxtCustomTranslate : ' is present')\n : null\n \"\n >\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div> \n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div> \n <div [ngStyle]=\"!isPreview ? { 'display': 'flex', 'width': '75%' } : { 'display': 'flex', 'width': '100%' }\">\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div *ngIf=\"!isPreview\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;margin-bottom:10px\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"display: flex;justify-content: space-between;\">\n <div *ngIf=\"pdf\" style=\"padding-left: 10px;\">\n <div *ngIf=\"pdf.title == ''\" style=\"color:#3f4a525c\">{{ 'HEADING' | nxtCustomTranslate : 'Heading' }}</div>\n <div *ngIf=\"pdf.title !== ''\">{{pdf.title}}</div>\n </div>\n <div class=\"action-buttons\">\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n </div>\n </div>\n </div>\n <!-- SKS26MAY26 pdf page -->\n <div class=\"pdf-page\" [style.background-color]=\"getPageBackgroundColor()\">\n <div *ngIf=\"getWatermarkText()\" class=\"pdf-watermark\" [ngStyle]=\"getWatermarkStyle()\">\n {{ getWatermarkText() }}\n </div>\n <div *ngIf=\"shouldShowHeaderOnCanvas()\" class=\"pdf-page-header\" [ngStyle]=\"getHeaderStyle()\">\n <div class=\"pdf-running-band\" [ngStyle]=\"getRunningBandBorderStyle('header')\">\n <ng-container *ngIf=\"getRunningBandColumns('header').length === 3; else singleHeader\">\n <span>{{ getRunningBandColumns('header')[0] }}</span>\n <span>{{ getRunningBandColumns('header')[1] }}</span>\n <span>{{ getRunningBandColumns('header')[2] }}</span>\n </ng-container>\n <ng-template #singleHeader>\n <span class=\"pdf-running-single\">{{ getRunningBandColumns('header')[0] }}</span>\n </ng-template>\n </div>\n </div>\n <div class=\"pdf-page-content\" [ngStyle]=\"getPageContentStyle()\">\n <ng-container *ngFor=\"let field of pdfElements; let i = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i)\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div *ngIf=\"!isPreview \" class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (field.lineStyle?.toLowerCase() || 'solid'),\n 'border-color': field.lineColor || field?.style?.color || '#000000',\n 'border-width': (field.lineWidth || 1) + 'px 0 0 0',\n 'color': field?.style?.color || '#000000',\n 'margin-top': (field?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (field?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n \n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i && !isPreview \" draggable=\"true && !isPreview \"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': field?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(field)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(field)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"field.imageData\" [style.width.px]=\"field.imageSize?.width || 100\" [style.height.px]=\"field.imageSize?.height || 100\" />\n </div>\n \n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(field, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Space Element -->\n <div *ngIf=\"field?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SKS21NOV25 signaturePad -->\n <div *ngIf=\"field?.type === 'signaturePad'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- SKS21NOV25 Signature Pad Field -->\n <div class=\"signature-pad-container\">\n <!-- SKS21NOV25 Builder mode (editable) -->\n <canvas *ngIf=\"!isPreview\"\n #sigCanvas\n [id]=\"field.id\"\n class=\"signature-pad\"\n (pointerdown)=\"pointerDown($event, field)\"\n (pointermove)=\"pointerMove($event, field)\"\n (pointerup)=\"pointerUp($event, field)\"\n (pointercancel)=\"pointerUp($event, field)\"\n (lostpointercapture)=\"pointerUp($event, field)\">\n </canvas>\n\n <!-- SKS21NOV25 Preview mode (static image) -->\n <img *ngIf=\"isPreview && field.value\"\n [src]=\"field.value\"\n class=\"signature-preview\" />\n <!-- SKS21NOV25 Empty state in preview -->\n <div *ngIf=\"isPreview && !field.value\"\n class=\"signature-placeholder\">\n Signature\n </div>\n <!-- SKS21NOV25 Builder buttons -->\n <div *ngIf=\"!isPreview\" class=\"signature-actions\">\n <button type=\"button\" (click)=\"onQuestionChange($event.value, field)\">Save</button>\n <button type=\"button\" (click)=\"clearSignature(field)\">Clear</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- SKS16SEP25 Date, currency, boolean, text -->\n <div *ngIf=\"field?.type === 'date' || field?.type === 'currency' || field?.type === 'boolean' || field?.type === 'text' || field?.type === 'Section' || field?.type === 'RichText' || field?.type === 'Note' || field?.type === 'PageBreak' || field?.type === 'PdfMake'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <ng-container [ngSwitch]=\"field?.type\">\n <div *ngSwitchCase=\"'Section'\" class=\"pdf-section-render\" [ngStyle]=\"getElementTextStyle(field)\">\n {{ displayFieldValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'Note'\" class=\"pdf-note-render\" [ngStyle]=\"getElementTextStyle(field)\">\n {{ displayFieldValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'RichText'\" class=\"pdf-richtext-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <ng-container *ngFor=\"let line of getRichTextLines(field); let lineIndex = index\">\n <div *ngIf=\"isRichTextHeading(field, lineIndex, line)\" class=\"pdf-richtext-heading\">\n {{ getRichTextLineText(line) }}\n </div>\n <div *ngIf=\"!isRichTextHeading(field, lineIndex, line) && !isRichTextBullet(line)\" class=\"pdf-richtext-line\">\n {{ line }}\n </div>\n <div *ngIf=\"isRichTextBullet(line)\" class=\"pdf-richtext-bullet\">\n <span>\u2022</span>\n <span>{{ getRichTextLineText(line) }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngSwitchCase=\"'PageBreak'\" class=\"pdf-pagebreak-render\">\n <span>Page break</span>\n </div>\n\n <div *ngSwitchCase=\"'PdfMake'\" class=\"pdfmake-render\">\n <div class=\"pdfmake-title\">Advanced pdfmake content</div>\n <pre>{{ getPdfMakePreview(field) }}</pre>\n </div>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <nxt-input *ngIf=\"!isPreview\" [type]=\"'checkbox'\" [mode]=\"'edit'\" [value]=\"field.value\" [question]=\"field\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"field.isReadOnly\"\n [currency]=\"selectedCurrency\" [label]=\"field?.questionText\" [inputWeight]=\"\"\n [showLabel]=\"field?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"field.question ? field.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"false\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"field?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, field)\">\n </nxt-input>\n\n <div *ngIf=\"isPreview\" class=\"pdf-text-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"pdf-field-label\" [ngStyle]=\"getElementLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <div class=\"pdf-field-value\">{{ displayFieldValue(field) }}</div>\n </div>\n </ng-container>\n\n <div *ngSwitchDefault class=\"pdf-text-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"pdf-field-label\" [ngStyle]=\"getElementLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <ng-container *ngIf=\"shouldRenderStyledTextLines(field); else plainTextValue\">\n <div *ngFor=\"let line of getStyledTextLines(field); let lineIndex = index\"\n class=\"pdf-field-value\"\n [class.pdf-text-heading-line]=\"isTextHeadingLine(field, lineIndex, line)\"\n [class.pdf-text-empty-line]=\"!line\"\n [ngStyle]=\"getStyledTextLineStyle(field, lineIndex, line)\">\n {{ line || ' ' }}\n </div>\n </ng-container>\n <ng-template #plainTextValue>\n <div class=\"pdf-field-value\">{{ displayFieldValue(field) }}</div>\n </ng-template>\n </div>\n </ng-container>\n </div>\n </div>\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === field\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n \n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n \n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n \n \n \n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div>\n </div>\n \n <!-- Pdf -->\n <div *ngIf=\"field?.type === 'Pdf'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg> \n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <!-- <lib-booklet [bookletJSON]=\"field.pdfReferenceQuestions\"></lib-booklet> -->\n <div *ngIf=\"field?.pdfReferenceQuestions\" class=\"pdf-nested-render\">\n <app-booklet [referenceKey]=\"field?.pdfReference\" [questions]=\"field?.pdfReferenceQuestions[field?.pdfReference]\" [isPreview]=\"isPreview\" [currencySymbol]=\"getCurrencySymbol()\" (questionChange)=\"onQuestionChange($event.value, $event.field)\"></app-booklet>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Table -->\n <div *ngIf=\"field?.type === 'Table'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper table-field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\"\n [apiMeta]=\"field?.subText\" [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\"\n tableWidth=\"auto\" isEditable=true isPreview=isPreview (columnSelected)=\"selectElement(i);columnSelected($event)\"\n [data]=\"field.value?.data\" [serialNumberColumn]=\"false\"\n [summaryValues]=\"field.value?.summaryValues || field.value?.summaryValue\"\n (valueChange)=\"onQuestionChange($event, field)\"\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- SKS26MAY26 pdf footer -->\n <div *ngIf=\"shouldShowFooterOnCanvas()\" class=\"pdf-page-footer\" [ngStyle]=\"getFooterStyle()\">\n <div class=\"pdf-running-band\" [ngStyle]=\"getRunningBandBorderStyle('footer')\">\n <ng-container *ngIf=\"getRunningBandColumns('footer').length === 3; else singleFooter\">\n <span>{{ getRunningBandColumns('footer')[0] }}</span>\n <span>{{ getRunningBandColumns('footer')[1] }}</span>\n <span>{{ getRunningBandColumns('footer')[2] }}</span>\n </ng-container>\n <ng-template #singleFooter>\n <span class=\"pdf-running-single\">{{ getRunningBandColumns('footer')[0] }}</span>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"!isPropertyHide && isPreview\" style=\"width: 25%; margin-bottom:10px\">\n <div style=\"padding-top: 0px; padding-bottom: 8px; padding-left: 8px;padding-right: 8px\">\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff;\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n <div class=\"color-picker\">\n <label>Change Color</label>\n <div class=\"colors\">\n <!-- Default colors -->\n <div class=\"color-swatch\" *ngFor=\"let color of defaultColors\" \n [style.background]=\"color\"\n (click)=\"selectColor(color)\">\n </div>\n \n <!-- Last box: custom color picker with eyedropper -->\n <label class=\"color-swatch custom-picker\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"geometricPrecision\" text-rendering=\"geometricPrecision\" image-rendering=\"optimizeQuality\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" viewBox=\"0 0 512 512\"><path fill=\"#FC3E81\" d=\"M171.11 171.836L74.204 75.761c.258-.26.517-.521.777-.78C124.688 25.274 189.751.292 254.899.013l.587 136.448c-32.992.139-62.827 13.641-84.376 35.375z\"/><path fill=\"#FD6096\" d=\"M255.486 136.461L254.899.003 256 0c70.296 0 133.967 28.342 180.232 74.212l-96.068 96.898c-21.605-21.421-51.337-34.655-84.164-34.655-.172 0-.343.005-.514.006z\"/><path fill=\"#F9B200\" d=\"M340.164 171.11l96.075-96.906c.26.258.521.517.78.777 49.707 49.707 74.689 114.77 74.968 179.918l-136.448.587c-.139-32.992-13.641-62.827-35.375-84.376z\"/><path fill=\"#C0FF66\" d=\"M375.539 255.486l136.458-.587L512 256c0 70.296-28.342 133.967-74.212 180.232l-96.898-96.068c21.421-21.605 34.655-51.337 34.655-84.164 0-.172-.005-.343-.006-.514z\"/><path fill=\"#1DD1D9\" d=\"M340.89 340.164l96.906 96.075c-.258.26-.517.521-.777.78-49.707 49.707-114.77 74.689-179.918 74.968l-.587-136.448c32.992-.139 62.827-13.641 84.376-35.375z\"/><path fill=\"#64BDFF\" d=\"M256.514 375.539l.587 136.458L256 512c-70.296 0-133.967-28.342-180.232-74.212l96.068-96.898c21.605 21.421 51.337 34.655 84.164 34.655.172 0 .343-.005.514-.006z\"/><path fill=\"#43A3F9\" d=\"M171.836 340.89l-96.075 96.906c-.26-.258-.521-.517-.78-.777C25.274 387.312.292 322.249.013 257.101l136.448-.587c.139 32.992 13.641 62.827 35.375 84.376z\"/><path fill=\"#7884EA\" d=\"M136.461 256.514l-136.458.587L0 256c0-70.296 28.342-133.967 74.212-180.232l96.898 96.068c-21.421 21.605-34.655 51.337-34.655 84.164 0 .172.005.343.006.514z\"/></svg>\n <input type=\"color\" (change)=\"selectColor($event.target.value)\">\n </label>\n </div>\n </div> \n <!-- SKS22JUL25 Dropdown -->\n <nxt-dropdown \n [options]=\"currencyOptions\"\n [id]=\"bookletId\" \n [selectedValue]=\"selectedCurrency\"\n [labelColor]=\"'#ffff'\"\n [inputTextColor]=\"'#ffff'\"\n [inputBgColor]=\"'#585653'\"\n placeholder=\"\" [from]=\"'normalDropDown'\"\n [apiMeta] = \"{'field': 'name','isObject': true}\"\n (valueChange)=\"currencyChange($event.value.valueObj)\">\n </nxt-dropdown> \n </div>\n </div>\n </div>\n </div>\n <!-- SKS13MAR25 popup conformation box -->\n <div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n </div>\n <app-pdf-properties *ngIf=\"!isPreview \" (formButtonHandler)=\"pdfSaveHandler($event)\"></app-pdf-properties>\n</div>\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 <!-- 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' | nxtCustomTranslate : '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 <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\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()\" [class.enabled]=\"transform.flipH\"\n title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n 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 </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:25%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .element:hover img{filter:invert(1)}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .element:hover .hover-label{color:#fff}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.form-builder .element:hover .dot{background-color:#ffffffb3}.field-wrapper{border-radius:5px}.field-wrapper.isPreview{background-color:transparent;border:none;border-radius:0;padding:0}.required:after{content:\"*\";color:red;margin-left:5px}.custom-input{width:100%;padding:8px;border:1px solid #DDDBDA;background-color:#fff;border-radius:5px;outline:none}.delete-icon{width:15px;height:15px}.field-container{border:1px solid #d5d5d5;background-color:#f8f8f8;transition:background .2s}.field-container.isPreview{border:none;background-color:#fff}.field-container:hover .top-right,.field-container.highlight .top-right,.label-container:hover .delete-icon{opacity:1;visibility:visible}.form-preview{width:100%;height:calc(100vh - 20px);min-height:250px;overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px;height:fit-content;max-height:calc(100vh - 20px)}.pdf-page{position:relative;width:794px;min-height:1123px;margin:12px auto 28px;box-shadow:0 18px 45px #0f172a29;overflow:hidden}.pdf-page-content{position:relative;z-index:1;display:flex;flex-wrap:wrap;align-items:flex-start;min-height:100%;box-sizing:border-box}.pdf-watermark{position:absolute;top:50%;left:50%;z-index:0;width:900px;text-align:center;font-weight:700;letter-spacing:0;pointer-events:none;-webkit-user-select:none;user-select:none}.pdf-page-footer,.pdf-page-header{position:absolute;z-index:2;min-height:24px;white-space:pre-wrap}.pdf-running-band{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;width:100%;padding:8px 0}.pdf-running-band span{overflow-wrap:anywhere}.pdf-running-band span:nth-child(2){text-align:center}.pdf-running-band span:nth-child(3){text-align:right}.pdf-running-single{grid-column:1 / -1;text-align:inherit!important}.pdf-text-render{min-height:16px;white-space:pre-wrap;overflow-wrap:anywhere;box-sizing:border-box}.pdf-field-label{margin-bottom:2px}.pdf-field-value{min-height:16px}.pdf-text-heading-line{line-height:1.05}.pdf-text-empty-line{font-size:0}.pdf-section-render{width:100%;min-height:32px;box-sizing:border-box;overflow-wrap:anywhere}.pdf-note-render{width:100%;min-height:34px;border:1px solid currentColor;box-sizing:border-box;overflow-wrap:anywhere;white-space:pre-wrap}.pdf-richtext-render{width:100%;white-space:normal;overflow-wrap:anywhere}.pdf-richtext-heading{color:var(--pdf-heading-color, #2f9e44);font-weight:600;margin-bottom:8px}.pdf-richtext-line{margin-bottom:7px}.pdf-richtext-bullet{display:grid;grid-template-columns:14px minmax(0,1fr);gap:4px;margin-bottom:7px}.pdf-pagebreak-render{display:flex;align-items:center;justify-content:center;width:100%;min-height:42px;color:#64748b;font-size:11px;border:1px dashed #94a3b8;background:#f8fafc;text-transform:uppercase;letter-spacing:0}.pdfmake-render{width:100%;border:1px dashed #94a3b8;background:#f8fafc;color:#334155;padding:10px;box-sizing:border-box}.pdfmake-title{font-size:11px;font-weight:700;margin-bottom:6px}.pdfmake-render pre{margin:0;max-height:160px;overflow:auto;white-space:pre-wrap;font-size:11px}.pdf-table-render{width:100%;overflow-x:auto}.pdf-nested-render{width:100%;padding:0}.pdf-table-render table{width:100%;border-collapse:collapse;table-layout:fixed;font-size:inherit}.pdf-table-render th,.pdf-table-render td{border:1px solid #cfd8d1;padding:6px;vertical-align:top;overflow-wrap:anywhere}.pdf-table-render th{cursor:pointer;position:relative}.pdf-table-render th:hover{outline:2px solid rgba(85,146,253,.45);outline-offset:-2px}.pdf-table-render .pdf-table-column-selected{box-shadow:inset 0 0 0 2px #5592fd}.pdf-summary-row td{border-color:transparent;background:transparent}.pdf-summary-label{color:#555;text-align:right}.pdf-summary-value{color:#222;font-weight:600}.pdf-page .field-container,.pdf-page .line-field{background:transparent;border:1px solid transparent;box-sizing:border-box}.pdf-page .field-container.highlight,.pdf-page .line-field.highlight{border-color:#5592fd!important;background:#eff8ff8c}.field-content{display:flex;flex-direction:column}.label-container{display:flex;justify-content:flex-end;align-items:center}.label2-container{display:flex;justify-content:space-between;align-items:center}.top-right{display:flex;align-items:center;gap:3px;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.drag-dot{height:10px;cursor:grab}.custom-input,.custom-textarea,.dropdown,.checkbox-options-container,.radio-options-container{width:100%}.form-builder .element .drag-dots:active{cursor:grabbing}.dropdown{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;background-color:#fff;font-size:14px;color:#333;outline:none;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.line-field{width:100%;margin:10px 0;background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:3px}.line-field{background-color:transparent;border:none;border-radius:0;padding:3px}.checkbox-field-container:hover{box-shadow:0 2px 8px #0000001a}.checkbox-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.label-container label{font-size:15px;font-weight:400}.required:after{content:\" *\";color:red}.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.custom-textarea{width:100%;min-height:100px;border:1px solid #ccc;border-radius:4px;padding:8px;resize:vertical}.highlight{border:1px solid #5592FD!important;background-color:#eff8ff}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.nxt-table-container{display:flex;justify-content:flex-start;align-items:center;width:100%;overflow-x:auto;overflow-y:hidden}nxt-datatable{width:max-content!important;min-width:100%;max-width:none}.table-field-wrapper{overflow-x:auto;overflow-y:hidden}:host ::ng-deep .nxt-table-container .table-layout,:host ::ng-deep .nxt-table-container .custom-table,:host ::ng-deep .nxt-table-container .table-row{min-width:800px}:host ::ng-deep .nxt-table-container .table-cell:not(.sticky-column):not(.actionCol){flex:0 0 92px;width:92px!important;min-width:92px;max-width:92px}:host ::ng-deep .nxt-table-container .nxtTableHeader{min-width:92px}:host ::ng-deep .nxt-table-container .nxtTableHeader[data-column-id=ngnxtTM0xwMZqrrr]{flex-basis:130px;width:130px!important;min-width:130px;max-width:130px}.dialog-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer;inline-size:auto}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.element.disabled{opacity:.5;cursor:not-allowed}.form-container{display:flex;flex-wrap:wrap;border:10px solid #86A8CD}.form-container.isPreview{border:none}.center-frame{width:74%}.center-frame.isPreview{width:100%}app-pdf-properties{border-left:10px solid #86A8CD;width:25%}:host ::ng-deep .questiondiv1{padding-left:0!important;padding-right:0!important}:host ::ng-deep .form-group.content-box{padding-bottom:0!important}:host ::ng-deep .custom-textarea{min-height:40px!important}.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;height:300px;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}.text-settings-toolbar{position:absolute;display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:#fff;border:1px solid #d1d5db;padding:8px 10px;border-radius:8px;box-shadow:0 4px 12px #0000001a;z-index:65535;max-width:100%;width:auto;min-width:200px;box-sizing:border-box}.toolbar-select{padding:4px 6px;font-size:13px;border:1px solid #d1d5db;border-radius:6px;background:#fff;cursor:pointer;min-width:60px;width:auto}.toolbar-btn{background:#f3f4f6;border:1px solid #d1d5db;padding:6px 8px;border-radius:6px;cursor:pointer;font-size:13px;min-width:30px;height:30px;display:flex;align-items:center;justify-content:center}.toolbar-btn:hover{background:#e5e7eb;border-color:#9ca3af}.toolbar-btn.active{background:#005aaa;color:#fff;border-color:#005aaa}.color-label{display:flex;align-items:center}.color-box{font-weight:700;width:22px;height:22px;font-size:13px;border:1px solid #ccc;border-radius:4px;text-align:center;line-height:22px;cursor:pointer;padding:0}.color-picker-hidden{position:absolute;opacity:0;pointer-events:none;width:0;height:0}@media(max-width:600px){.text-settings-toolbar{flex-direction:row;flex-wrap:wrap;gap:6px;padding:6px;justify-content:flex-start}.toolbar-btn,.toolbar-select{font-size:12px;padding:5px}.color-box{width:20px;height:20px;font-size:12px;line-height:20px}}.action-buttons{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.action-btn{display:flex;gap:16px;padding:10px 15px;border-radius:8px;border:none}.priview-action-div{padding:10px 15px;border-radius:8px;border:none;width:100%;margin-bottom:10px}.colors{display:flex;gap:8px}.color-swatch{width:28px;height:28px;border-radius:6px;cursor:pointer;border:2px solid transparent;display:flex;align-items:center;justify-content:center}.color-swatch:hover{border:2px solid #999}.custom-picker{position:relative;overflow:hidden;padding:2px;border:1px solid gray}.custom-picker input[type=color]{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer}.picker-icon{width:16px;height:16px;pointer-events:none}.signature-pad-container{width:100%;position:relative}.signature-pad{width:100%;height:90px;border:1px dashed #aaa;border-radius:6px;touch-action:none}.signature-preview{width:100%;height:90px;object-fit:contain;border:1px solid #ccc;border-radius:6px}.signature-placeholder{width:100%;height:90px;border:1px dashed #ccc;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:12px;color:#aaa}.signature-actions{margin-top:5px;display:flex;justify-content:space-between}\n"], dependencies: [{ 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: "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: "directive", type: i5.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i5.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i5.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { 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: PdfPropertiesComponent, selector: "app-pdf-properties", inputs: ["selectedElementType", "templateSelected"], outputs: ["formButtonHandler", "templateSaveHandler"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "summaryValues", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "hideSaveButton", "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: 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }, { kind: "component", type: BookletComponent, selector: "app-booklet", inputs: ["referenceKey", "questions", "isPreview", "currencySymbol"], outputs: ["questionChange"] }] });
|
|
63274
65092
|
}
|
|
63275
65093
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PdfDesignerComponent, decorators: [{
|
|
63276
65094
|
type: Component,
|
|
63277
|
-
args: [{ selector: 'app-pdf-designer', standalone: true, imports: [nxtDropdown, CommonModule, ImageCropperComponent, PdfPropertiesComponent, MatTooltipModule, FormsModule, NxtDatatable, NxtInput, NxtCustomTranslatePipe], template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"form-container\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"center-frame\" [ngClass]=\"{'isPreview': isPreview}\">\n <!-- Form Builder Section All Elements -->\n <div *ngIf=\"!isPreview\" class=\"form-builder\">\n <ng-container *ngFor=\"let element of elementsList\">\n <div\n class=\"element\"\n [class.disabled]=\"selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\"\n (click)=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)) && addElement(element.type)\"\n [draggable]=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type))\"\n [matTooltip]=\"\n selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\n ? ('THIS_ELEMENT_NOT_SUPPORTED' | nxtCustomTranslate : 'This element is not supported when a ') +\n (selectedElement?.type || ('CERTAIN_ELEMENT' | nxtCustomTranslate : 'certain element')) +\n (' IS_PRESENT' | nxtCustomTranslate : ' is present')\n : null\n \"\n >\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div> \n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div> \n <div [ngStyle]=\"!isPreview ? { 'display': 'flex', 'width': '75%' } : { 'display': 'flex', 'width': '100%' }\">\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div *ngIf=\"!isPreview\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;margin-bottom:10px\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"display: flex;justify-content: space-between;\">\n <div *ngIf=\"pdf\" style=\"padding-left: 10px;\">\n <div *ngIf=\"pdf.title == ''\" style=\"color:#3f4a525c\">{{ 'HEADING' | nxtCustomTranslate : 'Heading' }}</div>\n <div *ngIf=\"pdf.title !== ''\">{{pdf.title}}</div>\n </div>\n <div class=\"action-buttons\">\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let field of pdfElements; let i = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i)\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div *ngIf=\"!isPreview \" class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (field.lineStyle?.toLowerCase() || 'solid'),\n 'color': field?.style?.color || '#000000',\n 'margin-top': (field?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (field?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n \n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i && !isPreview \" draggable=\"true && !isPreview \"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': field?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(field)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(field)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"field.imageData\" [style.width.px]=\"field.imageSize?.width || 100\" [style.height.px]=\"field.imageSize?.height || 100\" />\n </div>\n \n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(field, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Space Element -->\n <div *ngIf=\"field?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SKS21NOV25 signaturePad -->\n <div *ngIf=\"field?.type === 'signaturePad'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- SKS21NOV25 Signature Pad Field -->\n <div class=\"signature-pad-container\">\n <!-- SKS21NOV25 Builder mode (editable) -->\n <canvas *ngIf=\"!isPreview\"\n #sigCanvas\n [id]=\"field.id\"\n class=\"signature-pad\"\n (pointerdown)=\"pointerDown($event, field)\"\n (pointermove)=\"pointerMove($event, field)\"\n (pointerup)=\"pointerUp($event, field)\"\n (pointercancel)=\"pointerUp($event, field)\"\n (lostpointercapture)=\"pointerUp($event, field)\">\n </canvas>\n\n <!-- SKS21NOV25 Preview mode (static image) -->\n <img *ngIf=\"isPreview && field.value\"\n [src]=\"field.value\"\n class=\"signature-preview\" />\n <!-- SKS21NOV25 Empty state in preview -->\n <div *ngIf=\"isPreview && !field.value\"\n class=\"signature-placeholder\">\n Signature\n </div>\n <!-- SKS21NOV25 Builder buttons -->\n <div *ngIf=\"!isPreview\" class=\"signature-actions\">\n <button type=\"button\" (click)=\"onQuestionChange($event.value, field)\">Save</button>\n <button type=\"button\" (click)=\"clearSignature(field)\">Clear</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- SKS16SEP25 Date, currency, boolean, text -->\n <div *ngIf=\"field?.type === 'date' || field?.type === 'currency' || field?.type === 'boolean' || field?.type === 'text'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- AP-04JUN25 - replace custom date picker -->\n <nxt-input [type]=\"field.type === 'boolean' ? 'checkbox' : field?.type === 'text' ? 'textarea' : field.type\" [mode]=\"'edit'\" [value]=\"field.value\" [question]=\"field\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"field.isReadOnly\"\n [currency] = 'selectedCurrency' [label]=\"field?.questionText\" (click)=\"field?.type === 'text' ? openTextSettings(field, $event) : ''\"\n [inputWeight]=\"\" [showLabel]=\"field?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"field.question ? field.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"field?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, field)\">\n </nxt-input>\n </div>\n </div>\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === field\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n \n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n \n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n \n \n \n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div>\n </div>\n \n <!-- Pdf -->\n <div *ngIf=\"field?.type === 'Pdf'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg> \n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <!-- <lib-booklet [bookletJSON]=\"field.pdfReferenceQuestions\"></lib-booklet> -->\n <div *ngIf=\"field?.pdfReferenceQuestions\" class=\"form-preview\" style=\"padding: unset !important;\">\n <ng-container *ngFor=\"let pdfField of field?.pdfReferenceQuestions[field?.pdfReference]; let j = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"pdfField?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: pdfField.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i,j); $event.stopPropagation();\" [class.highlight]=\"selectedFieldIndex === j && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, j)\" (dragover)=\"onDragOver($event, j)\"\n (drop)=\"onDrop($event, j)\">\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (pdfField.lineStyle?.toLowerCase() || 'solid'),\n 'color': pdfField?.style?.color || '#000000',\n 'margin-top': (pdfField?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (pdfField?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"pdfField?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [class.highlight]=\"selectedFieldIndex === j && !isPreview \"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px',\n \n \n display: pdfField.isHidden ? 'none' : 'block' \n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': pdfField?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"pdfField.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(pdfField)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(pdfField)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"pdfField.imageData\" [style.width.px]=\"pdfField.imageSize?.width || 100\" [style.height.px]=\"pdfField.imageSize?.height || 100\" />\n </div>\n\n <div *ngIf=\"!pdfField.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{j}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>{{ 'UPLOAD_IMAGE' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{j}}\" accept=\"image/*\" (change)=\"fileChangeEvent(pdfField, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"pdfField?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'text-align': pdfField?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px',\n \n \n display: pdfField.isHidden ? 'none' : 'block' \n }\" [class.highlight]=\"selectedFieldIndex === j && !isPreview \">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(pdfField, j)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Date -->\n <!-- display: pdfField.isHidden ? 'none' : 'block' -->\n <div *ngIf=\"pdfField?.type === 'date' || pdfField?.type === 'currency' || pdfField?.type === 'boolean' || pdfField?.type === 'text'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" (click)=\"selectElement(i,j); $event.stopPropagation();\"\n [ngStyle]=\"{\n 'font-family': pdfField?.style?.font || 'Helvetica Neue',\n 'font-size': (pdfField?.style?.fontSize || 12) + 'px',\n 'width': (pdfField?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': pdfField?.style?.color || '#000000',\n 'font-style': pdfField?.style?.italic ? 'italic' : 'normal',\n 'font-weight': pdfField?.style?.bold ? '700' : '400',\n 'padding': \n (pdfField?.style?.margin?.[1] || 0) + 'px ' +\n (pdfField?.style?.margin?.[2] || 0) + 'px ' +\n (pdfField?.style?.margin?.[3] || 0) + 'px ' +\n (pdfField?.style?.margin?.[0] || 0) + 'px ' ,\n }\"[class.highlight]=\"selectedFieldIndex === j && !isPreview \">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <!-- AP-04JUN25 - replace custom date picker -->\n <nxt-input [type]=\"pdfField.type === 'boolean' ? 'checkbox' : pdfField?.type === 'text' ? 'textarea' : pdfField.type\" [mode]=\"'edit'\" [value]=\"pdfField.value\" [question]=\"pdfField\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"pdfField.isReadOnly\"\n [currency] = 'selectedCurrency' [label]=\"pdfField?.questionText\" (click)=\"pdfField?.type === 'text' ? openTextSettings(pdfField, $event) : ''\"\n [inputWeight]=\"\" [showLabel]=\"pdfField?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"pdfField.question ? pdfField.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"pdfField?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, pdfField)\">\n </nxt-input>\n </div>\n </div>\n <!--AP-05JUN25 Text Settings Toolbar: Allows editing font size, bold/italic styles, alignment, and closing the toolbar for the selected column -->\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === pdfField\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <!-- Font Size -->\n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n\n <!-- Text Color -->\n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n\n <!-- Bold -->\n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <!-- Italic -->\n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n\n <!-- Underline -->\n <!-- <button (click)=\"toggleStyle('underline')\" [class.active]=\"selectedColumn?.style?.underline\" class=\"toolbar-btn\"><u>U</u></button> -->\n <!-- Align Left -->\n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <!-- Align Center -->\n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <!-- Align Right -->\n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <!-- Close -->\n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div> \n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Table -->\n <div *ngIf=\"field?.type === 'Table'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\"\n [apiMeta]=\"field?.subText\" [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\"\n tableWidth=\"auto\" isEditable=true isPreview=isPreview (columnSelected)=\"selectElement(i);columnSelected($event)\"\n [data]=\"field.value?.data\"\n [summaryValues]=\"field.value?.summaryValue\"\n (valueChange)=\"onQuestionChange($event, field)\"\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"!isPropertyHide && isPreview\" style=\"width: 25%; margin-bottom:10px\">\n <div style=\"padding-top: 0px; padding-bottom: 8px; padding-left: 8px;padding-right: 8px\">\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff;\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n <div class=\"color-picker\">\n <label>Change Color</label>\n <div class=\"colors\">\n <!-- Default colors -->\n <div class=\"color-swatch\" *ngFor=\"let color of defaultColors\" \n [style.background]=\"color\"\n (click)=\"selectColor(color)\">\n </div>\n \n <!-- Last box: custom color picker with eyedropper -->\n <label class=\"color-swatch custom-picker\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"geometricPrecision\" text-rendering=\"geometricPrecision\" image-rendering=\"optimizeQuality\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" viewBox=\"0 0 512 512\"><path fill=\"#FC3E81\" d=\"M171.11 171.836L74.204 75.761c.258-.26.517-.521.777-.78C124.688 25.274 189.751.292 254.899.013l.587 136.448c-32.992.139-62.827 13.641-84.376 35.375z\"/><path fill=\"#FD6096\" d=\"M255.486 136.461L254.899.003 256 0c70.296 0 133.967 28.342 180.232 74.212l-96.068 96.898c-21.605-21.421-51.337-34.655-84.164-34.655-.172 0-.343.005-.514.006z\"/><path fill=\"#F9B200\" d=\"M340.164 171.11l96.075-96.906c.26.258.521.517.78.777 49.707 49.707 74.689 114.77 74.968 179.918l-136.448.587c-.139-32.992-13.641-62.827-35.375-84.376z\"/><path fill=\"#C0FF66\" d=\"M375.539 255.486l136.458-.587L512 256c0 70.296-28.342 133.967-74.212 180.232l-96.898-96.068c21.421-21.605 34.655-51.337 34.655-84.164 0-.172-.005-.343-.006-.514z\"/><path fill=\"#1DD1D9\" d=\"M340.89 340.164l96.906 96.075c-.258.26-.517.521-.777.78-49.707 49.707-114.77 74.689-179.918 74.968l-.587-136.448c32.992-.139 62.827-13.641 84.376-35.375z\"/><path fill=\"#64BDFF\" d=\"M256.514 375.539l.587 136.458L256 512c-70.296 0-133.967-28.342-180.232-74.212l96.068-96.898c21.605 21.421 51.337 34.655 84.164 34.655.172 0 .343-.005.514-.006z\"/><path fill=\"#43A3F9\" d=\"M171.836 340.89l-96.075 96.906c-.26-.258-.521-.517-.78-.777C25.274 387.312.292 322.249.013 257.101l136.448-.587c.139 32.992 13.641 62.827 35.375 84.376z\"/><path fill=\"#7884EA\" d=\"M136.461 256.514l-136.458.587L0 256c0-70.296 28.342-133.967 74.212-180.232l96.898 96.068c-21.421 21.605-34.655 51.337-34.655 84.164 0 .172.005.343.006.514z\"/></svg>\n <input type=\"color\" (change)=\"selectColor($event.target.value)\">\n </label>\n </div>\n </div> \n <!-- SKS22JUL25 Dropdown -->\n <nxt-dropdown \n [options]=\"currencyOptions\"\n [id]=\"bookletId\" \n [selectedValue]=\"selectedCurrency\"\n [labelColor]=\"'#ffff'\"\n [inputTextColor]=\"'#ffff'\"\n [inputBgColor]=\"'#585653'\"\n placeholder=\"\" [from]=\"'normalDropDown'\"\n [apiMeta] = \"{'field': 'name','isObject': true}\"\n (valueChange)=\"currencyChange($event.value.valueObj)\">\n </nxt-dropdown> \n </div>\n </div>\n </div>\n </div>\n <!-- SKS13MAR25 popup conformation box -->\n <div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n </div>\n <app-pdf-properties *ngIf=\"!isPreview \" (formButtonHandler)=\"pdfSaveHandler($event)\"></app-pdf-properties>\n</div>\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 <!-- 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' | nxtCustomTranslate : '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 <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\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()\" [class.enabled]=\"transform.flipH\"\n title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n 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 </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:25%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .element:hover img{filter:invert(1)}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .element:hover .hover-label{color:#fff}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.form-builder .element:hover .dot{background-color:#ffffffb3}.field-wrapper{border-radius:5px}.field-wrapper.isPreview{background-color:transparent;border:none;border-radius:0;padding:0}.required:after{content:\"*\";color:red;margin-left:5px}.custom-input{width:100%;padding:8px;border:1px solid #DDDBDA;background-color:#fff;border-radius:5px;outline:none}.delete-icon{width:15px;height:15px}.field-container{border:1px solid #d5d5d5;background-color:#f8f8f8;transition:background .2s}.field-container.isPreview{border:none;background-color:#fff}.field-container:hover .top-right,.field-container.highlight .top-right,.label-container:hover .delete-icon{opacity:1;visibility:visible}.form-preview{width:100%;height:calc(100vh - 20px);min-height:250px;overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px;height:fit-content;max-height:calc(100vh - 20px)}.field-content{display:flex;flex-direction:column}.label-container{display:flex;justify-content:flex-end;align-items:center}.label2-container{display:flex;justify-content:space-between;align-items:center}.top-right{display:flex;align-items:center;gap:3px;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.drag-dot{height:10px;cursor:grab}.custom-input,.custom-textarea,.dropdown,.checkbox-options-container,.radio-options-container{width:100%}.form-builder .element .drag-dots:active{cursor:grabbing}.dropdown{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;background-color:#fff;font-size:14px;color:#333;outline:none;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.line-field{width:100%;margin:10px 0;background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:3px}.line-field{background-color:transparent;border:none;border-radius:0;padding:3px}.checkbox-field-container:hover{box-shadow:0 2px 8px #0000001a}.checkbox-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.label-container label{font-size:15px;font-weight:400}.required:after{content:\" *\";color:red}.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.custom-textarea{width:100%;min-height:100px;border:1px solid #ccc;border-radius:4px;padding:8px;resize:vertical}.highlight{border:1px solid #5592FD!important;background-color:#eff8ff}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer;inline-size:auto}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.element.disabled{opacity:.5;cursor:not-allowed}.form-container{display:flex;flex-wrap:wrap;border:10px solid #86A8CD}.form-container.isPreview{border:none}.center-frame{width:74%}.center-frame.isPreview{width:100%}app-pdf-properties{border-left:10px solid #86A8CD;width:25%}:host ::ng-deep .questiondiv1{padding-left:0!important;padding-right:0!important}:host ::ng-deep .form-group.content-box{padding-bottom:0!important}:host ::ng-deep .custom-textarea{min-height:40px!important}.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;height:300px;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}.text-settings-toolbar{position:absolute;display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:#fff;border:1px solid #d1d5db;padding:8px 10px;border-radius:8px;box-shadow:0 4px 12px #0000001a;z-index:65535;max-width:100%;width:auto;min-width:200px;box-sizing:border-box}.toolbar-select{padding:4px 6px;font-size:13px;border:1px solid #d1d5db;border-radius:6px;background:#fff;cursor:pointer;min-width:60px;width:auto}.toolbar-btn{background:#f3f4f6;border:1px solid #d1d5db;padding:6px 8px;border-radius:6px;cursor:pointer;font-size:13px;min-width:30px;height:30px;display:flex;align-items:center;justify-content:center}.toolbar-btn:hover{background:#e5e7eb;border-color:#9ca3af}.toolbar-btn.active{background:#005aaa;color:#fff;border-color:#005aaa}.color-label{display:flex;align-items:center}.color-box{font-weight:700;width:22px;height:22px;font-size:13px;border:1px solid #ccc;border-radius:4px;text-align:center;line-height:22px;cursor:pointer;padding:0}.color-picker-hidden{position:absolute;opacity:0;pointer-events:none;width:0;height:0}@media(max-width:600px){.text-settings-toolbar{flex-direction:row;flex-wrap:wrap;gap:6px;padding:6px;justify-content:flex-start}.toolbar-btn,.toolbar-select{font-size:12px;padding:5px}.color-box{width:20px;height:20px;font-size:12px;line-height:20px}}.action-buttons{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.action-btn{display:flex;gap:16px;padding:10px 15px;border-radius:8px;border:none}.priview-action-div{padding:10px 15px;border-radius:8px;border:none;width:100%;margin-bottom:10px}.colors{display:flex;gap:8px}.color-swatch{width:28px;height:28px;border-radius:6px;cursor:pointer;border:2px solid transparent;display:flex;align-items:center;justify-content:center}.color-swatch:hover{border:2px solid #999}.custom-picker{position:relative;overflow:hidden;padding:2px;border:1px solid gray}.custom-picker input[type=color]{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer}.picker-icon{width:16px;height:16px;pointer-events:none}.signature-pad-container{width:100%;position:relative}.signature-pad{width:100%;height:90px;border:1px dashed #aaa;border-radius:6px;touch-action:none}.signature-preview{width:100%;height:90px;object-fit:contain;border:1px solid #ccc;border-radius:6px}.signature-placeholder{width:100%;height:90px;border:1px dashed #ccc;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:12px;color:#aaa}.signature-actions{margin-top:5px;display:flex;justify-content:space-between}\n"] }]
|
|
65095
|
+
args: [{ selector: 'app-pdf-designer', standalone: true, imports: [nxtDropdown, CommonModule, ImageCropperComponent, PdfPropertiesComponent, MatTooltipModule, FormsModule, NxtDatatable, NxtInput, NxtCustomTranslatePipe, BookletComponent], template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"form-container\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"center-frame\" [ngClass]=\"{'isPreview': isPreview}\">\n <!-- Form Builder Section All Elements -->\n <div *ngIf=\"!isPreview\" class=\"form-builder\">\n <ng-container *ngFor=\"let element of elementsList\">\n <div\n class=\"element\"\n [class.disabled]=\"selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\"\n (click)=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)) && addElement(element.type)\"\n [draggable]=\"!(selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type))\"\n [matTooltip]=\"\n selectedElement?.type && elementDisabledArray[selectedElement.type]?.includes(element.type)\n ? ('THIS_ELEMENT_NOT_SUPPORTED' | nxtCustomTranslate : 'This element is not supported when a ') +\n (selectedElement?.type || ('CERTAIN_ELEMENT' | nxtCustomTranslate : 'certain element')) +\n (' IS_PRESENT' | nxtCustomTranslate : ' is present')\n : null\n \"\n >\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div> \n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div> \n <div [ngStyle]=\"!isPreview ? { 'display': 'flex', 'width': '75%' } : { 'display': 'flex', 'width': '100%' }\">\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div *ngIf=\"!isPreview\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;margin-bottom:10px\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"display: flex;justify-content: space-between;\">\n <div *ngIf=\"pdf\" style=\"padding-left: 10px;\">\n <div *ngIf=\"pdf.title == ''\" style=\"color:#3f4a525c\">{{ 'HEADING' | nxtCustomTranslate : 'Heading' }}</div>\n <div *ngIf=\"pdf.title !== ''\">{{pdf.title}}</div>\n </div>\n <div class=\"action-buttons\">\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"action-btn\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n </div>\n </div>\n </div>\n <!-- SKS26MAY26 pdf page -->\n <div class=\"pdf-page\" [style.background-color]=\"getPageBackgroundColor()\">\n <div *ngIf=\"getWatermarkText()\" class=\"pdf-watermark\" [ngStyle]=\"getWatermarkStyle()\">\n {{ getWatermarkText() }}\n </div>\n <div *ngIf=\"shouldShowHeaderOnCanvas()\" class=\"pdf-page-header\" [ngStyle]=\"getHeaderStyle()\">\n <div class=\"pdf-running-band\" [ngStyle]=\"getRunningBandBorderStyle('header')\">\n <ng-container *ngIf=\"getRunningBandColumns('header').length === 3; else singleHeader\">\n <span>{{ getRunningBandColumns('header')[0] }}</span>\n <span>{{ getRunningBandColumns('header')[1] }}</span>\n <span>{{ getRunningBandColumns('header')[2] }}</span>\n </ng-container>\n <ng-template #singleHeader>\n <span class=\"pdf-running-single\">{{ getRunningBandColumns('header')[0] }}</span>\n </ng-template>\n </div>\n </div>\n <div class=\"pdf-page-content\" [ngStyle]=\"getPageContentStyle()\">\n <ng-container *ngFor=\"let field of pdfElements; let i = index\">\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field?.type === 'Line'\" class=\"line-field\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" [ngClass]=\"{'isPreview': isPreview}\"\n (click)=\"selectElement(i)\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div *ngIf=\"!isPreview \" class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field.textAlign || 'left',\n 'border-radius': '5px',\n 'border-style': (field.lineStyle?.toLowerCase() || 'solid'),\n 'border-color': field.lineColor || field?.style?.color || '#000000',\n 'border-width': (field.lineWidth || 1) + 'px 0 0 0',\n 'color': field?.style?.color || '#000000',\n 'margin-top': (field?.style?.paddingTop || 0) + 'px',\n 'margin-bottom': (field?.style?.paddingBottom ?? 10) + 'px'\n }\" />\n </div>\n \n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field?.type === 'image'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i && !isPreview \" draggable=\"true && !isPreview \"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" \n (mouseenter)=\"isImageHover = true;\"\n (mouseleave)=\"isImageHover = false;\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\" [ngStyle]=\"{ 'justify-content': field?.style?.alignment || '' }\">\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <div style=\"display: flex; justify-content: end;\">\n <i (click)=\"onImageEdit(field)\" class=\"fusion-icon nav-icon fusion-icon-edit_pencil\" style=\"margin: 0px !important; font-size: 16px !important; color: #787486;\"></i>\n <svg (click)=\"onImageDelete(field)\" 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\" stroke-linecap=\"round\"\n 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 [src]=\"field.imageData\" [style.width.px]=\"field.imageSize?.width || 100\" [style.height.px]=\"field.imageSize?.height || 100\" />\n </div>\n \n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(field, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Space Element -->\n <div *ngIf=\"field?.type === 'Space'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div *ngIf=\"!isPreview \" class=\"field-content\">\n <div class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SKS21NOV25 signaturePad -->\n <div *ngIf=\"field?.type === 'signaturePad'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n \n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n \n \n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <!-- SKS21NOV25 Signature Pad Field -->\n <div class=\"signature-pad-container\">\n <!-- SKS21NOV25 Builder mode (editable) -->\n <canvas *ngIf=\"!isPreview\"\n #sigCanvas\n [id]=\"field.id\"\n class=\"signature-pad\"\n (pointerdown)=\"pointerDown($event, field)\"\n (pointermove)=\"pointerMove($event, field)\"\n (pointerup)=\"pointerUp($event, field)\"\n (pointercancel)=\"pointerUp($event, field)\"\n (lostpointercapture)=\"pointerUp($event, field)\">\n </canvas>\n\n <!-- SKS21NOV25 Preview mode (static image) -->\n <img *ngIf=\"isPreview && field.value\"\n [src]=\"field.value\"\n class=\"signature-preview\" />\n <!-- SKS21NOV25 Empty state in preview -->\n <div *ngIf=\"isPreview && !field.value\"\n class=\"signature-placeholder\">\n Signature\n </div>\n <!-- SKS21NOV25 Builder buttons -->\n <div *ngIf=\"!isPreview\" class=\"signature-actions\">\n <button type=\"button\" (click)=\"onQuestionChange($event.value, field)\">Save</button>\n <button type=\"button\" (click)=\"clearSignature(field)\">Clear</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n \n <!-- SKS16SEP25 Date, currency, boolean, text -->\n <div *ngIf=\"field?.type === 'date' || field?.type === 'currency' || field?.type === 'boolean' || field?.type === 'text' || field?.type === 'Section' || field?.type === 'RichText' || field?.type === 'Note' || field?.type === 'PageBreak' || field?.type === 'PdfMake'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label-container\">\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <ng-container [ngSwitch]=\"field?.type\">\n <div *ngSwitchCase=\"'Section'\" class=\"pdf-section-render\" [ngStyle]=\"getElementTextStyle(field)\">\n {{ displayFieldValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'Note'\" class=\"pdf-note-render\" [ngStyle]=\"getElementTextStyle(field)\">\n {{ displayFieldValue(field) }}\n </div>\n\n <div *ngSwitchCase=\"'RichText'\" class=\"pdf-richtext-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <ng-container *ngFor=\"let line of getRichTextLines(field); let lineIndex = index\">\n <div *ngIf=\"isRichTextHeading(field, lineIndex, line)\" class=\"pdf-richtext-heading\">\n {{ getRichTextLineText(line) }}\n </div>\n <div *ngIf=\"!isRichTextHeading(field, lineIndex, line) && !isRichTextBullet(line)\" class=\"pdf-richtext-line\">\n {{ line }}\n </div>\n <div *ngIf=\"isRichTextBullet(line)\" class=\"pdf-richtext-bullet\">\n <span>\u2022</span>\n <span>{{ getRichTextLineText(line) }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngSwitchCase=\"'PageBreak'\" class=\"pdf-pagebreak-render\">\n <span>Page break</span>\n </div>\n\n <div *ngSwitchCase=\"'PdfMake'\" class=\"pdfmake-render\">\n <div class=\"pdfmake-title\">Advanced pdfmake content</div>\n <pre>{{ getPdfMakePreview(field) }}</pre>\n </div>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <nxt-input *ngIf=\"!isPreview\" [type]=\"'checkbox'\" [mode]=\"'edit'\" [value]=\"field.value\" [question]=\"field\" [labelFont]=\"\"\n [labelColor]=\"\" [labelSize]=\"\" [inputValueSize]=\"\" [labelWeight]=\"\" [readOnly]=\"field.isReadOnly\"\n [currency]=\"selectedCurrency\" [label]=\"field?.questionText\" [inputWeight]=\"\"\n [showLabel]=\"field?.questionText ? true : false\" inputBorder=\"none\" svgHeight=\"20px\" svgWidth=\"20px\"\n [placeholder]=\"field.question ? field.question : 'ENTER_YOUR_INPUT' | nxtCustomTranslate : 'Enter your input'\" [required]=\"false\"\n inputBgColor=\"#ffffff\" [inputId]=\"\" [errorMessages]=\"{ required: 'This field is required' }\" [textAlign]=\"field?.style?.alignment || ''\"\n [inputIconLeftSrc]=\"''\" (inputValue)=\"onQuestionChange($event.value, field)\">\n </nxt-input>\n\n <div *ngIf=\"isPreview\" class=\"pdf-text-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"pdf-field-label\" [ngStyle]=\"getElementLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <div class=\"pdf-field-value\">{{ displayFieldValue(field) }}</div>\n </div>\n </ng-container>\n\n <div *ngSwitchDefault class=\"pdf-text-render\" [ngStyle]=\"getElementTextStyle(field)\">\n <div *ngIf=\"field?.questionText && field?.showLabelInPdf\" class=\"pdf-field-label\" [ngStyle]=\"getElementLabelStyle(field)\">\n {{ field.questionText }}\n </div>\n <ng-container *ngIf=\"shouldRenderStyledTextLines(field); else plainTextValue\">\n <div *ngFor=\"let line of getStyledTextLines(field); let lineIndex = index\"\n class=\"pdf-field-value\"\n [class.pdf-text-heading-line]=\"isTextHeadingLine(field, lineIndex, line)\"\n [class.pdf-text-empty-line]=\"!line\"\n [ngStyle]=\"getStyledTextLineStyle(field, lineIndex, line)\">\n {{ line || ' ' }}\n </div>\n </ng-container>\n <ng-template #plainTextValue>\n <div class=\"pdf-field-value\">{{ displayFieldValue(field) }}</div>\n </ng-template>\n </div>\n </ng-container>\n </div>\n </div>\n <div *ngIf=\"showTextSettings && isPreview && selectedColumn === field\" class=\"text-settings-toolbar\"\n [ngStyle]=\"{\n position: 'absolute',\n background: '#fff',\n border: '1px solid #ccc',\n padding: '6px 10px',\n 'border-radius': '4px',\n 'box-shadow': '0 2px 6px rgba(0, 0, 0, 0.1)',\n 'z-index': '65535',\n display: 'flex',\n 'text-align': 'center',\n gap: '8px'\n }\">\n \n <select [(ngModel)]=\"selectedColumn.style.fontSize\" class=\"toolbar-select\">\n <option [value]=\"12\">12pt</option>\n <option [value]=\"14\">14pt</option>\n <option [value]=\"16\">16pt</option>\n <option [value]=\"18\">18pt</option>\n <option [value]=\"24\">24pt</option>\n </select>\n \n <label title=\"Text Color\" class=\"color-label\">\n <span class=\"color-box\" [style.color]=\"selectedColumn.style.color || '#000'\" (click)=\"textColorInput.click()\">A</span>\n <input #textColorInput type=\"color\" [(ngModel)]=\"selectedColumn.style.color\" (change)=\"updateContent()\" class=\"color-picker-hidden\"/>\n </label>\n \n <button (click)=\"toggleStyle('bold')\" [class.active]=\"selectedColumn?.style?.bold\" class=\"toolbar-btn\">{{ 'BOLD' | nxtCustomTranslate : 'B' }}</button>\n \n <button (click)=\"toggleStyle('italic')\" [class.active]=\"selectedColumn?.style?.italics\" class=\"toolbar-btn\"><i>{{ 'ITALIC' | nxtCustomTranslate : 'I' }}</i></button>\n \n \n \n <button (click)=\"setAlignment('left')\" [class.active]=\"selectedColumn?.style?.alignment === 'left'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_LEFT' | nxtCustomTranslate : 'format_align_left' }}</span>\n </button>\n \n <button (click)=\"setAlignment('center')\" [class.active]=\"selectedColumn?.style?.alignment === 'center'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_CENTER' | nxtCustomTranslate : 'format_align_center' }}</span>\n </button>\n \n <button (click)=\"setAlignment('right')\" [class.active]=\"selectedColumn?.style?.alignment === 'right'\" class=\"toolbar-btn\">\n <span class=\"material-icons\">{{ 'FORMAT_ALIGN_RIGHT' | nxtCustomTranslate : 'format_align_right' }}</span>\n </button>\n \n <button (click)=\"closeTextSettings()\" class=\"toolbar-btn\" style=\"margin-left: auto;\">\u2715</button>\n </div>\n </div>\n \n <!-- Pdf -->\n <div *ngIf=\"field?.type === 'Pdf'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'text-align': field?.style?.alignment || '',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg> \n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <!-- <lib-booklet [bookletJSON]=\"field.pdfReferenceQuestions\"></lib-booklet> -->\n <div *ngIf=\"field?.pdfReferenceQuestions\" class=\"pdf-nested-render\">\n <app-booklet [referenceKey]=\"field?.pdfReference\" [questions]=\"field?.pdfReferenceQuestions[field?.pdfReference]\" [isPreview]=\"isPreview\" [currencySymbol]=\"getCurrencySymbol()\" (questionChange)=\"onQuestionChange($event.value, $event.field)\"></app-booklet>\n </div>\n </div>\n </div>\n </div>\n \n <!-- Table -->\n <div *ngIf=\"field?.type === 'Table'\" class=\"field-container\" [ngClass]=\"{'isPreview': isPreview}\" [ngStyle]=\"{ display: field.isHidden ? 'none' : 'block' }\" (click)=\"selectElement(i)\"\n [ngStyle]=\"{\n 'font-family': field?.style?.font || 'Helvetica Neue',\n 'font-size': (field?.style?.fontSize || 12) + 'px',\n 'width': (field?.width || 100) + '%',\n 'border-radius': '5px',\n 'color': field?.style?.color || '#000000',\n 'font-style': field?.style?.italic ? 'italic' : 'normal',\n 'font-weight': field?.style?.bold ? '700' : '400',\n 'padding': \n (field?.style?.margin?.[1] || 0) + 'px ' +\n (field?.style?.margin?.[2] || 0) + 'px ' +\n (field?.style?.margin?.[3] || 0) + 'px ' +\n (field?.style?.margin?.[0] || 0) + 'px ' ,\n }\" [class.highlight]=\"selectedFieldIndex === i && !isPreview \"\n draggable=\"true && !isPreview \" (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper table-field-wrapper\" [ngClass]=\"{'isPreview': isPreview}\">\n <div class=\"field-content\">\n <div *ngIf=\"!isPreview \" class=\"label2-container\">\n <div>\n <div *ngIf=\"field.questionText && field.type != 'checkbox'\" \n [ngStyle]=\"{\n 'padding-top': field.type === 'label' ? '10px' : '',\n \n }\" [style.font-weight]=\"field.labelWeight || field.type === 'label' ? 'bold' : 'normal'\" [style.font-size]=\"field.labelSize || field.type === 'label' ? '16px' : '14px'\"\n style=\"display: flex; gap: 5px;\"> \n {{ field.questionText }}\n <div *ngIf=\"field.questionText && field.type != 'checkbox' && field.required && field.showLabel \" style=\"color: red;\">*</div>\n <div *ngIf=\"field.questionText && field?.helpText\" [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div *ngIf=\"!field.questionText && field?.helpText\" style=\"display: flex; justify-content: flex-end;\">\n <svg [matTooltip]=\"field?.helpText\" matTooltipClass=\"white-tooltip label-container\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.00009 0.615356C3.90779 0.615356 0.615479 3.90766 0.615479 7.99997C0.615479 12.0923 3.90779 15.3846 8.00009 15.3846C12.0924 15.3846 15.3847 12.0923 15.3847 7.99997C15.3847 3.90766 12.0924 0.615356 8.00009 0.615356ZM8.00012 13.5385C4.92319 13.5385 2.46165 11.0769 2.46165 8C2.46165 4.92307 4.92319 2.46153 8.00012 2.46153C11.077 2.46153 13.5386 4.92307 13.5386 8C13.5386 11.0769 11.077 13.5385 8.00012 13.5385ZM8.00027 4.33846C8.52335 4.33846 8.92335 4.73846 8.92335 5.26153C8.92335 5.78461 8.52335 6.18461 8.00027 6.18461C7.47719 6.18461 7.07719 5.78461 7.07719 5.26153C7.07719 4.73846 7.47719 4.33846 8.00027 4.33846ZM9.53859 10.8C9.53859 10.9538 9.41552 11.0769 9.2309 11.0769H6.76936C6.61552 11.0769 6.46167 10.9846 6.46167 10.8V10.1846C6.46167 10.0308 6.58475 9.84614 6.76936 9.84614C6.92321 9.84614 7.07706 9.75383 7.07706 9.56921V8.33844C7.07706 8.1846 6.95398 7.99998 6.76936 7.99998C6.61552 7.99998 6.46167 7.90767 6.46167 7.72306V7.10767C6.46167 6.95383 6.58475 6.76921 6.76936 6.76921H8.61552C8.76936 6.76921 8.92321 6.92306 8.92321 7.10767V9.56921C8.92321 9.72306 9.04629 9.84614 9.2309 9.84614C9.38475 9.84614 9.53859 9.99998 9.53859 10.1846V10.8Z\" fill=\"#747474\"/>\n </svg>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\"\n [apiMeta]=\"field?.subText\" [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\"\n tableWidth=\"auto\" isEditable=true isPreview=isPreview (columnSelected)=\"selectElement(i);columnSelected($event)\"\n [data]=\"field.value?.data\" [serialNumberColumn]=\"false\"\n [summaryValues]=\"field.value?.summaryValues || field.value?.summaryValue\"\n (valueChange)=\"onQuestionChange($event, field)\"\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- SKS26MAY26 pdf footer -->\n <div *ngIf=\"shouldShowFooterOnCanvas()\" class=\"pdf-page-footer\" [ngStyle]=\"getFooterStyle()\">\n <div class=\"pdf-running-band\" [ngStyle]=\"getRunningBandBorderStyle('footer')\">\n <ng-container *ngIf=\"getRunningBandColumns('footer').length === 3; else singleFooter\">\n <span>{{ getRunningBandColumns('footer')[0] }}</span>\n <span>{{ getRunningBandColumns('footer')[1] }}</span>\n <span>{{ getRunningBandColumns('footer')[2] }}</span>\n </ng-container>\n <ng-template #singleFooter>\n <span class=\"pdf-running-single\">{{ getRunningBandColumns('footer')[0] }}</span>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"!isPropertyHide && isPreview\" style=\"width: 25%; margin-bottom:10px\">\n <div style=\"padding-top: 0px; padding-bottom: 8px; padding-left: 8px;padding-right: 8px\">\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff;\" (click)=\"pdfSaveHandler('preview')\">{{ 'PREVIEW' | nxtCustomTranslate : 'Preview' }}</button>\n <button class=\"priview-action-div\" style=\"background-color: #585653; color: #ffff\" (click)=\"pdfSaveHandler('download')\">{{ 'DOWNLOAD' | nxtCustomTranslate : 'Download' }}</button>\n <div class=\"color-picker\">\n <label>Change Color</label>\n <div class=\"colors\">\n <!-- Default colors -->\n <div class=\"color-swatch\" *ngFor=\"let color of defaultColors\" \n [style.background]=\"color\"\n (click)=\"selectColor(color)\">\n </div>\n \n <!-- Last box: custom color picker with eyedropper -->\n <label class=\"color-swatch custom-picker\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"geometricPrecision\" text-rendering=\"geometricPrecision\" image-rendering=\"optimizeQuality\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" viewBox=\"0 0 512 512\"><path fill=\"#FC3E81\" d=\"M171.11 171.836L74.204 75.761c.258-.26.517-.521.777-.78C124.688 25.274 189.751.292 254.899.013l.587 136.448c-32.992.139-62.827 13.641-84.376 35.375z\"/><path fill=\"#FD6096\" d=\"M255.486 136.461L254.899.003 256 0c70.296 0 133.967 28.342 180.232 74.212l-96.068 96.898c-21.605-21.421-51.337-34.655-84.164-34.655-.172 0-.343.005-.514.006z\"/><path fill=\"#F9B200\" d=\"M340.164 171.11l96.075-96.906c.26.258.521.517.78.777 49.707 49.707 74.689 114.77 74.968 179.918l-136.448.587c-.139-32.992-13.641-62.827-35.375-84.376z\"/><path fill=\"#C0FF66\" d=\"M375.539 255.486l136.458-.587L512 256c0 70.296-28.342 133.967-74.212 180.232l-96.898-96.068c21.421-21.605 34.655-51.337 34.655-84.164 0-.172-.005-.343-.006-.514z\"/><path fill=\"#1DD1D9\" d=\"M340.89 340.164l96.906 96.075c-.258.26-.517.521-.777.78-49.707 49.707-114.77 74.689-179.918 74.968l-.587-136.448c32.992-.139 62.827-13.641 84.376-35.375z\"/><path fill=\"#64BDFF\" d=\"M256.514 375.539l.587 136.458L256 512c-70.296 0-133.967-28.342-180.232-74.212l96.068-96.898c21.605 21.421 51.337 34.655 84.164 34.655.172 0 .343-.005.514-.006z\"/><path fill=\"#43A3F9\" d=\"M171.836 340.89l-96.075 96.906c-.26-.258-.521-.517-.78-.777C25.274 387.312.292 322.249.013 257.101l136.448-.587c.139 32.992 13.641 62.827 35.375 84.376z\"/><path fill=\"#7884EA\" d=\"M136.461 256.514l-136.458.587L0 256c0-70.296 28.342-133.967 74.212-180.232l96.898 96.068c-21.421 21.605-34.655 51.337-34.655 84.164 0 .172.005.343.006.514z\"/></svg>\n <input type=\"color\" (change)=\"selectColor($event.target.value)\">\n </label>\n </div>\n </div> \n <!-- SKS22JUL25 Dropdown -->\n <nxt-dropdown \n [options]=\"currencyOptions\"\n [id]=\"bookletId\" \n [selectedValue]=\"selectedCurrency\"\n [labelColor]=\"'#ffff'\"\n [inputTextColor]=\"'#ffff'\"\n [inputBgColor]=\"'#585653'\"\n placeholder=\"\" [from]=\"'normalDropDown'\"\n [apiMeta] = \"{'field': 'name','isObject': true}\"\n (valueChange)=\"currencyChange($event.value.valueObj)\">\n </nxt-dropdown> \n </div>\n </div>\n </div>\n </div>\n <!-- SKS13MAR25 popup conformation box -->\n <div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n </div>\n <app-pdf-properties *ngIf=\"!isPreview \" (formButtonHandler)=\"pdfSaveHandler($event)\"></app-pdf-properties>\n</div>\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 <!-- 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' | nxtCustomTranslate : '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 <!-- Controls -->\n <div *ngIf=\"selectedImageElement.imageData\" class=\"controls\">\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()\" [class.enabled]=\"transform.flipH\"\n title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n 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 </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:25%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .element:hover img{filter:invert(1)}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .element:hover .hover-label{color:#fff}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.form-builder .element:hover .dot{background-color:#ffffffb3}.field-wrapper{border-radius:5px}.field-wrapper.isPreview{background-color:transparent;border:none;border-radius:0;padding:0}.required:after{content:\"*\";color:red;margin-left:5px}.custom-input{width:100%;padding:8px;border:1px solid #DDDBDA;background-color:#fff;border-radius:5px;outline:none}.delete-icon{width:15px;height:15px}.field-container{border:1px solid #d5d5d5;background-color:#f8f8f8;transition:background .2s}.field-container.isPreview{border:none;background-color:#fff}.field-container:hover .top-right,.field-container.highlight .top-right,.label-container:hover .delete-icon{opacity:1;visibility:visible}.form-preview{width:100%;height:calc(100vh - 20px);min-height:250px;overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px;height:fit-content;max-height:calc(100vh - 20px)}.pdf-page{position:relative;width:794px;min-height:1123px;margin:12px auto 28px;box-shadow:0 18px 45px #0f172a29;overflow:hidden}.pdf-page-content{position:relative;z-index:1;display:flex;flex-wrap:wrap;align-items:flex-start;min-height:100%;box-sizing:border-box}.pdf-watermark{position:absolute;top:50%;left:50%;z-index:0;width:900px;text-align:center;font-weight:700;letter-spacing:0;pointer-events:none;-webkit-user-select:none;user-select:none}.pdf-page-footer,.pdf-page-header{position:absolute;z-index:2;min-height:24px;white-space:pre-wrap}.pdf-running-band{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;width:100%;padding:8px 0}.pdf-running-band span{overflow-wrap:anywhere}.pdf-running-band span:nth-child(2){text-align:center}.pdf-running-band span:nth-child(3){text-align:right}.pdf-running-single{grid-column:1 / -1;text-align:inherit!important}.pdf-text-render{min-height:16px;white-space:pre-wrap;overflow-wrap:anywhere;box-sizing:border-box}.pdf-field-label{margin-bottom:2px}.pdf-field-value{min-height:16px}.pdf-text-heading-line{line-height:1.05}.pdf-text-empty-line{font-size:0}.pdf-section-render{width:100%;min-height:32px;box-sizing:border-box;overflow-wrap:anywhere}.pdf-note-render{width:100%;min-height:34px;border:1px solid currentColor;box-sizing:border-box;overflow-wrap:anywhere;white-space:pre-wrap}.pdf-richtext-render{width:100%;white-space:normal;overflow-wrap:anywhere}.pdf-richtext-heading{color:var(--pdf-heading-color, #2f9e44);font-weight:600;margin-bottom:8px}.pdf-richtext-line{margin-bottom:7px}.pdf-richtext-bullet{display:grid;grid-template-columns:14px minmax(0,1fr);gap:4px;margin-bottom:7px}.pdf-pagebreak-render{display:flex;align-items:center;justify-content:center;width:100%;min-height:42px;color:#64748b;font-size:11px;border:1px dashed #94a3b8;background:#f8fafc;text-transform:uppercase;letter-spacing:0}.pdfmake-render{width:100%;border:1px dashed #94a3b8;background:#f8fafc;color:#334155;padding:10px;box-sizing:border-box}.pdfmake-title{font-size:11px;font-weight:700;margin-bottom:6px}.pdfmake-render pre{margin:0;max-height:160px;overflow:auto;white-space:pre-wrap;font-size:11px}.pdf-table-render{width:100%;overflow-x:auto}.pdf-nested-render{width:100%;padding:0}.pdf-table-render table{width:100%;border-collapse:collapse;table-layout:fixed;font-size:inherit}.pdf-table-render th,.pdf-table-render td{border:1px solid #cfd8d1;padding:6px;vertical-align:top;overflow-wrap:anywhere}.pdf-table-render th{cursor:pointer;position:relative}.pdf-table-render th:hover{outline:2px solid rgba(85,146,253,.45);outline-offset:-2px}.pdf-table-render .pdf-table-column-selected{box-shadow:inset 0 0 0 2px #5592fd}.pdf-summary-row td{border-color:transparent;background:transparent}.pdf-summary-label{color:#555;text-align:right}.pdf-summary-value{color:#222;font-weight:600}.pdf-page .field-container,.pdf-page .line-field{background:transparent;border:1px solid transparent;box-sizing:border-box}.pdf-page .field-container.highlight,.pdf-page .line-field.highlight{border-color:#5592fd!important;background:#eff8ff8c}.field-content{display:flex;flex-direction:column}.label-container{display:flex;justify-content:flex-end;align-items:center}.label2-container{display:flex;justify-content:space-between;align-items:center}.top-right{display:flex;align-items:center;gap:3px;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.drag-dot{height:10px;cursor:grab}.custom-input,.custom-textarea,.dropdown,.checkbox-options-container,.radio-options-container{width:100%}.form-builder .element .drag-dots:active{cursor:grabbing}.dropdown{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;background-color:#fff;font-size:14px;color:#333;outline:none;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.line-field{width:100%;margin:10px 0;background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:3px}.line-field{background-color:transparent;border:none;border-radius:0;padding:3px}.checkbox-field-container:hover{box-shadow:0 2px 8px #0000001a}.checkbox-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.label-container label{font-size:15px;font-weight:400}.required:after{content:\" *\";color:red}.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;outline:none;border-radius:6px}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.custom-textarea{width:100%;min-height:100px;border:1px solid #ccc;border-radius:4px;padding:8px;resize:vertical}.highlight{border:1px solid #5592FD!important;background-color:#eff8ff}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.nxt-table-container{display:flex;justify-content:flex-start;align-items:center;width:100%;overflow-x:auto;overflow-y:hidden}nxt-datatable{width:max-content!important;min-width:100%;max-width:none}.table-field-wrapper{overflow-x:auto;overflow-y:hidden}:host ::ng-deep .nxt-table-container .table-layout,:host ::ng-deep .nxt-table-container .custom-table,:host ::ng-deep .nxt-table-container .table-row{min-width:800px}:host ::ng-deep .nxt-table-container .table-cell:not(.sticky-column):not(.actionCol){flex:0 0 92px;width:92px!important;min-width:92px;max-width:92px}:host ::ng-deep .nxt-table-container .nxtTableHeader{min-width:92px}:host ::ng-deep .nxt-table-container .nxtTableHeader[data-column-id=ngnxtTM0xwMZqrrr]{flex-basis:130px;width:130px!important;min-width:130px;max-width:130px}.dialog-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer;inline-size:auto}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.element.disabled{opacity:.5;cursor:not-allowed}.form-container{display:flex;flex-wrap:wrap;border:10px solid #86A8CD}.form-container.isPreview{border:none}.center-frame{width:74%}.center-frame.isPreview{width:100%}app-pdf-properties{border-left:10px solid #86A8CD;width:25%}:host ::ng-deep .questiondiv1{padding-left:0!important;padding-right:0!important}:host ::ng-deep .form-group.content-box{padding-bottom:0!important}:host ::ng-deep .custom-textarea{min-height:40px!important}.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;height:300px;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}.text-settings-toolbar{position:absolute;display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:#fff;border:1px solid #d1d5db;padding:8px 10px;border-radius:8px;box-shadow:0 4px 12px #0000001a;z-index:65535;max-width:100%;width:auto;min-width:200px;box-sizing:border-box}.toolbar-select{padding:4px 6px;font-size:13px;border:1px solid #d1d5db;border-radius:6px;background:#fff;cursor:pointer;min-width:60px;width:auto}.toolbar-btn{background:#f3f4f6;border:1px solid #d1d5db;padding:6px 8px;border-radius:6px;cursor:pointer;font-size:13px;min-width:30px;height:30px;display:flex;align-items:center;justify-content:center}.toolbar-btn:hover{background:#e5e7eb;border-color:#9ca3af}.toolbar-btn.active{background:#005aaa;color:#fff;border-color:#005aaa}.color-label{display:flex;align-items:center}.color-box{font-weight:700;width:22px;height:22px;font-size:13px;border:1px solid #ccc;border-radius:4px;text-align:center;line-height:22px;cursor:pointer;padding:0}.color-picker-hidden{position:absolute;opacity:0;pointer-events:none;width:0;height:0}@media(max-width:600px){.text-settings-toolbar{flex-direction:row;flex-wrap:wrap;gap:6px;padding:6px;justify-content:flex-start}.toolbar-btn,.toolbar-select{font-size:12px;padding:5px}.color-box{width:20px;height:20px;font-size:12px;line-height:20px}}.action-buttons{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.action-btn{display:flex;gap:16px;padding:10px 15px;border-radius:8px;border:none}.priview-action-div{padding:10px 15px;border-radius:8px;border:none;width:100%;margin-bottom:10px}.colors{display:flex;gap:8px}.color-swatch{width:28px;height:28px;border-radius:6px;cursor:pointer;border:2px solid transparent;display:flex;align-items:center;justify-content:center}.color-swatch:hover{border:2px solid #999}.custom-picker{position:relative;overflow:hidden;padding:2px;border:1px solid gray}.custom-picker input[type=color]{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer}.picker-icon{width:16px;height:16px;pointer-events:none}.signature-pad-container{width:100%;position:relative}.signature-pad{width:100%;height:90px;border:1px dashed #aaa;border-radius:6px;touch-action:none}.signature-preview{width:100%;height:90px;object-fit:contain;border:1px solid #ccc;border-radius:6px}.signature-placeholder{width:100%;height:90px;border:1px dashed #ccc;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:12px;color:#aaa}.signature-actions{margin-top:5px;display:flex;justify-content:space-between}\n"] }]
|
|
63278
65096
|
}], ctorParameters: () => [{ type: DataService }, { type: ChangeService }, { type: CountryService }, { type: PdfDesignerService }], propDecorators: { textareas: [{
|
|
63279
65097
|
type: ViewChildren,
|
|
63280
65098
|
args: ['autoTextarea']
|
|
@@ -63290,12 +65108,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
63290
65108
|
type: Input
|
|
63291
65109
|
}], isPropertyHide: [{
|
|
63292
65110
|
type: Input
|
|
65111
|
+
}], pdfDefinitionOptions: [{
|
|
65112
|
+
type: Input
|
|
63293
65113
|
}], pdfSaveHandlerEmit: [{
|
|
63294
65114
|
type: Output
|
|
63295
65115
|
}], templateMode: [{
|
|
63296
65116
|
type: Output
|
|
63297
65117
|
}], pdfPreviewEmit: [{
|
|
63298
65118
|
type: Output
|
|
65119
|
+
}], pdfOutputEmit: [{
|
|
65120
|
+
type: Output
|
|
63299
65121
|
}] } });
|
|
63300
65122
|
|
|
63301
65123
|
//AP-25JUN25- common-fields.constants.ts
|
|
@@ -65466,14 +67288,14 @@ class ElementComponent {
|
|
|
65466
67288
|
this.translationService.setFormBuilderLanguage(this.languageCode);
|
|
65467
67289
|
}
|
|
65468
67290
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ElementComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: FormBuilderService }, { token: TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
65469
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: ElementComponent, isStandalone: true, selector: "app-element", inputs: { bookletJSON: "bookletJSON", langOption: "langOption", languageCode: "languageCode" }, outputs: { templateMode: "templateMode" }, usesOnChanges: true, ngImport: i0, template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"center-frame\">\n <!-- Form Builder Section All Elements -->\n <div class=\"form-builder\">\n <!-- Basic Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('basic')\">\n <div class=\"head-elements\">{{ 'BASIC_ELEMENTS' | nxtCustomTranslate : 'Basic Elements' }}</div>\n <img [src]=\"sections.basic ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.basic\">\n <ng-container *ngFor=\"let element of basicElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Advanced Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('advanced')\">\n <div class=\"head-elements\">{{ 'ADVANCED_ELEMENTS' | nxtCustomTranslate : 'Advanced Elements' }}</div>\n <img [src]=\"sections.advanced ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.advanced\">\n <ng-container *ngFor=\"let element of advancedElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- AP-08APR25 Add Templates Component -->\n <!-- <app-templates (templateSelected)=\"onTemplateSelected($event)\"></app-templates> -->\n\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div>\n <!-- AP-27MAR25 Remove CDK drag and drop replace draggable function -->\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div style=\" display: flex; justify-content: space-between; width: 100%; gap: 10px;\">\n <div class=\"label-container field-container\"\n style=\"padding: 10px; width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;display: flex;justify-content: center;margin-bottom:10px; border-radius: 5px;\"\n [class.highlight]=\"isHeaderSelect\" (click)=\"selectHeading('Header')\">\n <div *ngIf=\"book?.records\">\n <div *ngIf=\"book.records[0].title == ''\" style=\"color:#3f4a525c\">Heading</div>\n <div *ngIf=\"book.records[0].title !== ''\">{{book.records[0].title}}</div>\n </div>\n </div>\n <nxt-dropdown \n [options]=\"langOption\" \n [selectedValue]=\"languageCode\" \n [from]=\"'normalDropDown'\"\n [mode]=\"'edit'\" (valueChange)=\"langChangeEmit($event.value)\"\n style=\"margin-bottom: 10px; background: #eff8ff; border-radius: 5px;\">\n </nxt-dropdown>\n </div>\n <ng-container *ngFor=\"let field of formElements; let i = index\" getProperties().elementProps>\n <!-- SKS12FEB26 TextBox and default element -->\n <div *ngIf=\"field.type === 'Text' || field.type === 'currency' || !statictype.includes(field.type)\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_TEXT' | nxtCustomTranslate : 'Enter text')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : '' \" />\n </div>\n </div>\n </div>\n\n <!-- MSM-09JUL25 Icon-selectir Element -->\n <div *ngIf=\"field.type === 'Icon'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isRequired\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('CHOOSE_ICON' | nxtCustomTranslate : 'Choose Icon')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"choose-icon-placeholder\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field.type === 'Line'\" class=\"line-field\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF',\n 'border-style': field?.lineStyle?.toLowerCase() || 'solid'\n }\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field.type === 'Image'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('UPLOAD_IMAGE' | nxtCustomTranslate : 'Upload Image')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <img [src]=\"field.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(i, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"field.type === 'Space'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\"></label>\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Boolean Element -->\n <div *ngIf=\"field.type === 'Boolean'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{ field.questionText\n ? field.questionText : ('BOOLEAN' | nxtCustomTranslate : 'Boolean')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"checkbox\" [checked]=\"field.boolean\" (change)=\"toggleBoolean(field)\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n\n <!-- Calendar -->\n <div *ngIf=\"field.type === 'Calendar'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE' | nxtCustomTranslate : 'Select Date')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP -12MAR25 Date -->\n <div *ngIf=\"field.type === 'Date'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE' | nxtCustomTranslate : 'Select Date')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-21MAR25 Add Time element -->\n <!-- Time Field -->\n <div *ngIf=\"field.type === 'Time'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\">{{ field.questionText ? field.questionText : ('TIME' |\n nxtCustomTranslate : 'Time') }}</label>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"time\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-28MAR25 DateTime -->\n <div *ngIf=\"field.type === 'DateTime'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE_TIME' | nxtCustomTranslate : 'Select Date & Time')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"datetime-local\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n <!-- SKS7AUG25 month -->\n <div *ngIf=\"field.type === 'month'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" \n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{field.questionText ? field.questionText : ('SELECT_MONTH' | nxtCustomTranslate : 'Select Month')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"month\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- Email -->\n <div *ngIf=\"field.type === 'Email'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\"> {{ field.questionText ? field.questionText : ('LABEL' |\n nxtCustomTranslate : 'Label') }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"email\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_EMAIL' | nxtCustomTranslate : 'Enter email')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- Numbers -->\n <div *ngIf=\"field.type === 'Number'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"number\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_NUMBER' | nxtCustomTranslate : 'Enter number')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- TextArea -->\n <div *ngIf=\"field.type === 'TextArea'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('ENTER_YOUR_TEXT' | nxtCustomTranslate : 'Enter your text')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\"\n [placeholder]=\"field.question || ('ENTER_DETAILED_TEXT' | nxtCustomTranslate : 'Enter detailed text here...')\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- RichText -->\n <div *ngIf=\"field.type === 'RichTextArea'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('ENTER_YOUR_TEXT' | nxtCustomTranslate : 'Enter your text')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\"\n [placeholder]=\"field.question ||('ENTER_DETAILED_TEXT' | nxtCustomTranslate : 'Enter detailed text here...')\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- Label -->\n <div *ngIf=\"field.type === 'Label'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Book -->\n <div *ngIf=\"field.type === 'Book'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <lib-booklet [bookletJSON]=\"field.qbReferenceQuestions\" from=\"formBuilder\"></lib-booklet>\n </div>\n </div>\n </div>\n\n <!-- File -->\n <div *ngIf=\"field.type === 'File'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('UPLOAD_FILE' | nxtCustomTranslate : 'Upload File')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"file\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- CheckBox -->\n <div *ngIf=\"field.type === 'Checkbox'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">\n {{ field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n\n <div class=\"checkbox-options-container\">\n <div *ngFor=\"let option of field.options\" class=\"checkbox-option\">\n <input type=\"checkbox\" [id]=\"option.value + i\" [name]=\"field.id\"\n [value]=\"option.value || field.defaultValue\" class=\"checkbox-input\" [disabled]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\">\n <label [for]=\"option.value + i\" class=\"checkbox-label\">{{ option.label }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Radio -->\n <div *ngIf=\"field.type === 'Radio'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"radio-options-container\">\n <div *ngFor=\"let option of field.options; let j = index\" class=\"radio-option\">\n <input type=\"radio\" [id]=\"'radio-' + field.id + '-' + j\" [name]=\"'radio-group-' + field.id\"\n [value]=\"option.value || field.defaultValue\" [(ngModel)]=\"field.selectedValue\" class=\"radio-input\"\n [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <label [for]=\"'radio-' + field.id + '-' + j\" class=\"radio-label\"> {{ option.label }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Dropdown -->\n <div *ngIf=\"field.type === 'Dropdown' || field.type === 'MultiSelect'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <select id=\"options\" class=\"dropdown\" [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <option *ngFor=\"let option of field.options\" [value]=\"option.value || field.defaultValue\"> {{ option.label }} </option>\n </select>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <!-- AP-06MAR25 -->\n <div *ngIf=\"field.type === 'Table'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\" [apiMeta]=\"field.subText\"\n [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\" tableWidth=\"auto\" isEditable=true\n [selectedColumn]=\"selectedColumn\" (columnSelected)=columnSelected($event)\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n\n <!-- List -->\n <!-- AP-06MAR25 - List data show-->\n <div *ngIf=\"field.type === 'List'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" [placeholder]=\"('SEARCH' | nxtCustomTranslate : 'Search...')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n </ng-container>\n </div>\n</div>\n<!-- SKS13MAR25 popup conformation box -->\n<div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:33.33%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element:hover img{filter:invert(1)}.form-builder .element:hover .hover-label{color:#fff}.form-builder .element:hover .dot{background-color:#ffffffb3}.form-builder .element .drag-dots:active{cursor:grabbing}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.drag-dot{height:10px;cursor:grab}.field-wrapper,.line-field{background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:10px}.line-field{width:100%;margin:10px 0;padding:3px}.field-container{padding:0 5px;transition:background .2s}.field-container:hover .top-right,.field-container.highlight .top-right{opacity:1;visibility:visible}.field-content{display:flex;flex-direction:column;gap:5px}.label-container{display:flex;justify-content:space-between;align-items:center}.label-container:hover .delete-icon{opacity:1;visibility:visible}.label-container label{font-size:15px;font-weight:400}.top-right{display:flex;align-items:center;gap:3px;padding:3px;border-radius:3px;position:relative;top:-5px;margin:-10px -10px 0 0;background-color:#d7edff;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.custom-input,.custom-textarea,.dropdown{width:100%;padding:8px;border:1px solid #ccc;background-color:#fff;border-radius:5px;outline:none}.custom-input{border-color:#dddbda}.custom-input:focus{border-color:#00008b;box-shadow:0 0 5px #0000ff80}.custom-textarea{min-height:100px;resize:vertical}.dropdown{font-size:14px;color:#333;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.checkbox-options-container,.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;border-radius:6px;outline:none;width:100%}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.form-preview{width:100%;height:fit-content;min-height:250px;max-height:calc(100vh - 20px);overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px}.required:after{content:\" *\";color:red;margin-left:5px}.highlight{border:2px solid #5592FD!important;background-color:#eff8ff}.delete-icon{width:15px;height:15px}.element.disabled{opacity:.5;cursor:not-allowed}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-container{display:flex;flex-direction:column;padding:10px;border:1px dashed #ccc;border-radius:5px;background-color:#f9f9f9}.logo-preview{position:relative;border:1px solid #e0e0e0;background-color:#fff;overflow:hidden}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.choose-icon-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:48px;height:150px;border:2px dashed #ccc;cursor:pointer}\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: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BookletComponent, selector: "lib-booklet", inputs: ["bookletId", "serv", "tkn", "bookletJSON", "allIcons", "themeColor", "cdnIconURL", "dropdownDependentData", "labelValue", "token", "languageCode", "fieldRestrictions", "from", "apiUrl", "isEdit", "direction", "isLoading", "onlyView", "dataBind"], outputs: ["handleBookletActionEvent", "handlePage", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent", "formEditEvent"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "summaryValues", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "hideSaveButton", "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: 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }] });
|
|
67291
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: ElementComponent, isStandalone: true, selector: "app-element", inputs: { bookletJSON: "bookletJSON", langOption: "langOption", languageCode: "languageCode" }, outputs: { templateMode: "templateMode" }, usesOnChanges: true, ngImport: i0, template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"center-frame\">\n <!-- Form Builder Section All Elements -->\n <div class=\"form-builder\">\n <!-- Basic Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('basic')\">\n <div class=\"head-elements\">{{ 'BASIC_ELEMENTS' | nxtCustomTranslate : 'Basic Elements' }}</div>\n <img [src]=\"sections.basic ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.basic\">\n <ng-container *ngFor=\"let element of basicElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Advanced Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('advanced')\">\n <div class=\"head-elements\">{{ 'ADVANCED_ELEMENTS' | nxtCustomTranslate : 'Advanced Elements' }}</div>\n <img [src]=\"sections.advanced ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.advanced\">\n <ng-container *ngFor=\"let element of advancedElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- AP-08APR25 Add Templates Component -->\n <!-- <app-templates (templateSelected)=\"onTemplateSelected($event)\"></app-templates> -->\n\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div>\n <!-- AP-27MAR25 Remove CDK drag and drop replace draggable function -->\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div style=\" display: flex; justify-content: space-between; width: 100%; gap: 10px;\">\n <div class=\"label-container field-container\"\n style=\"padding: 10px; width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;display: flex;justify-content: center;margin-bottom:10px; border-radius: 5px;\"\n [class.highlight]=\"isHeaderSelect\" (click)=\"selectHeading('Header')\">\n <div *ngIf=\"book?.records\">\n <div *ngIf=\"book.records[0].title == ''\" style=\"color:#3f4a525c\">Heading</div>\n <div *ngIf=\"book.records[0].title !== ''\">{{book.records[0].title}}</div>\n </div>\n </div>\n <nxt-dropdown \n [options]=\"langOption\" \n [selectedValue]=\"languageCode\" \n [from]=\"'normalDropDown'\"\n [mode]=\"'edit'\" (valueChange)=\"langChangeEmit($event.value)\"\n style=\"margin-bottom: 10px; background: #eff8ff; border-radius: 5px;\">\n </nxt-dropdown>\n </div>\n <ng-container *ngFor=\"let field of formElements; let i = index\" getProperties().elementProps>\n <!-- SKS12FEB26 TextBox and default element -->\n <div *ngIf=\"field.type === 'Text' || field.type === 'currency' || !statictype.includes(field.type)\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_TEXT' | nxtCustomTranslate : 'Enter text')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : '' \" />\n </div>\n </div>\n </div>\n\n <!-- MSM-09JUL25 Icon-selectir Element -->\n <div *ngIf=\"field.type === 'Icon'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isRequired\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('CHOOSE_ICON' | nxtCustomTranslate : 'Choose Icon')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"choose-icon-placeholder\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field.type === 'Line'\" class=\"line-field\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF',\n 'border-style': field?.lineStyle?.toLowerCase() || 'solid'\n }\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field.type === 'Image'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('UPLOAD_IMAGE' | nxtCustomTranslate : 'Upload Image')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <img [src]=\"field.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!field.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' | nxtCustomTranslate : 'Upload Image' }}</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(i, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"field.type === 'Space'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\"></label>\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Boolean Element -->\n <div *ngIf=\"field.type === 'Boolean'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{ field.questionText\n ? field.questionText : ('BOOLEAN' | nxtCustomTranslate : 'Boolean')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"checkbox\" [checked]=\"field.boolean\" (change)=\"toggleBoolean(field)\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n\n <!-- Calendar -->\n <div *ngIf=\"field.type === 'Calendar'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE' | nxtCustomTranslate : 'Select Date')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP -12MAR25 Date -->\n <div *ngIf=\"field.type === 'Date'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE' | nxtCustomTranslate : 'Select Date')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-21MAR25 Add Time element -->\n <!-- Time Field -->\n <div *ngIf=\"field.type === 'Time'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\">{{ field.questionText ? field.questionText : ('TIME' |\n nxtCustomTranslate : 'Time') }}</label>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"time\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-28MAR25 DateTime -->\n <div *ngIf=\"field.type === 'DateTime'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('SELECT_DATE_TIME' | nxtCustomTranslate : 'Select Date & Time')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"datetime-local\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n <!-- SKS7AUG25 month -->\n <div *ngIf=\"field.type === 'month'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" \n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{field.questionText ? field.questionText : ('SELECT_MONTH' | nxtCustomTranslate : 'Select Month')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"month\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- Email -->\n <div *ngIf=\"field.type === 'Email'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\"> {{ field.questionText ? field.questionText : ('LABEL' |\n nxtCustomTranslate : 'Label') }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"email\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_EMAIL' | nxtCustomTranslate : 'Enter email')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- Numbers -->\n <div *ngIf=\"field.type === 'Number'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"number\" class=\"custom-input\"\n [placeholder]=\"field.question || ('ENTER_NUMBER' | nxtCustomTranslate : 'Enter number')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- TextArea -->\n <div *ngIf=\"field.type === 'TextArea'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('ENTER_YOUR_TEXT' | nxtCustomTranslate : 'Enter your text')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\"\n [placeholder]=\"field.question || ('ENTER_DETAILED_TEXT' | nxtCustomTranslate : 'Enter detailed text here...')\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- RichText -->\n <div *ngIf=\"field.type === 'RichTextArea'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('ENTER_YOUR_TEXT' | nxtCustomTranslate : 'Enter your text')}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\"\n [placeholder]=\"field.question ||('ENTER_DETAILED_TEXT' | nxtCustomTranslate : 'Enter detailed text here...')\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- Label -->\n <div *ngIf=\"field.type === 'Label'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Book -->\n <div *ngIf=\"field.type === 'Book'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <lib-booklet [bookletJSON]=\"field.qbReferenceQuestions\" from=\"formBuilder\"></lib-booklet>\n </div>\n </div>\n </div>\n\n <!-- File -->\n <div *ngIf=\"field.type === 'File'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('UPLOAD_FILE' | nxtCustomTranslate : 'Upload File')\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"file\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- CheckBox -->\n <div *ngIf=\"field.type === 'Checkbox'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">\n {{ field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n\n <div class=\"checkbox-options-container\">\n <div *ngFor=\"let option of field.options\" class=\"checkbox-option\">\n <input type=\"checkbox\" [id]=\"option.value + i\" [name]=\"field.id\"\n [value]=\"option.value || field.defaultValue\" class=\"checkbox-input\" [disabled]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\">\n <label [for]=\"option.value + i\" class=\"checkbox-label\">{{ option.label }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Radio -->\n <div *ngIf=\"field.type === 'Radio'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"radio-options-container\">\n <div *ngFor=\"let option of field.options; let j = index\" class=\"radio-option\">\n <input type=\"radio\" [id]=\"'radio-' + field.id + '-' + j\" [name]=\"'radio-group-' + field.id\"\n [value]=\"option.value || field.defaultValue\" [(ngModel)]=\"field.selectedValue\" class=\"radio-input\"\n [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <label [for]=\"'radio-' + field.id + '-' + j\" class=\"radio-label\"> {{ option.label }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Dropdown -->\n <div *ngIf=\"field.type === 'Dropdown' || field.type === 'MultiSelect'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <select id=\"options\" class=\"dropdown\" [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <option *ngFor=\"let option of field.options\" [value]=\"option.value || field.defaultValue\"> {{ option.label }} </option>\n </select>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <!-- AP-06MAR25 -->\n <div *ngIf=\"field.type === 'Table'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\" [apiMeta]=\"field.subText\"\n [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\" tableWidth=\"auto\" isEditable=true\n [selectedColumn]=\"selectedColumn\" (columnSelected)=columnSelected($event)\n (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n\n <!-- List -->\n <!-- AP-06MAR25 - List data show-->\n <div *ngIf=\"field.type === 'List'\" class=\"field-container\" (click)=\"selectElement(i)\" [ngStyle]=\"{\n 'font-family': field?.font || 'Helvetica Neue',\n 'font-weight': field?.fontWeight || '400',\n 'font-size': field?.fontSize || '14px',\n 'width': field?.size ? (field.size / 12 * 100) + '%' : '100%',\n 'text-align': field?.textAlign || 'left',\n 'border-radius': '5px',\n 'border-width': field?.lineWidth ? field.lineWidth + 'px' : '1px',\n 'color': field?.color || '#000000',\n 'margin-top': field?.paddingTop ? field.paddingTop + 'px' : '0px',\n 'margin-bottom': field?.paddingBottom ? field.paddingBottom + 'px' : '10px',\n 'border-color': field?.color || '#EFF8FF'\n }\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : ('LABEL' | nxtCustomTranslate : 'Label') }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" [placeholder]=\"('SEARCH' | nxtCustomTranslate : 'Search...')\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n </ng-container>\n </div>\n</div>\n<!-- SKS13MAR25 popup conformation box -->\n<div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>{{ 'ADD_TABLE_CONFIRMATION' | nxtCustomTranslate : 'These element want to add a table' }}</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">{{ 'YES' | nxtCustomTranslate : 'Yes' }}</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">{{ 'NO' | nxtCustomTranslate : 'No' }}</button>\n </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:33.33%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element:hover img{filter:invert(1)}.form-builder .element:hover .hover-label{color:#fff}.form-builder .element:hover .dot{background-color:#ffffffb3}.form-builder .element .drag-dots:active{cursor:grabbing}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.drag-dot{height:10px;cursor:grab}.field-wrapper,.line-field{background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:10px}.line-field{width:100%;margin:10px 0;padding:3px}.field-container{padding:0 5px;transition:background .2s}.field-container:hover .top-right,.field-container.highlight .top-right{opacity:1;visibility:visible}.field-content{display:flex;flex-direction:column;gap:5px}.label-container{display:flex;justify-content:space-between;align-items:center}.label-container:hover .delete-icon{opacity:1;visibility:visible}.label-container label{font-size:15px;font-weight:400}.top-right{display:flex;align-items:center;gap:3px;padding:3px;border-radius:3px;position:relative;top:-5px;margin:-10px -10px 0 0;background-color:#d7edff;opacity:0;visibility:hidden;transition:opacity .1s,visibility .1s}.custom-input,.custom-textarea,.dropdown{width:100%;padding:8px;border:1px solid #ccc;background-color:#fff;border-radius:5px;outline:none}.custom-input{border-color:#dddbda}.custom-input:focus{border-color:#00008b;box-shadow:0 0 5px #0000ff80}.custom-textarea{min-height:100px;resize:vertical}.dropdown{font-size:14px;color:#333;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.checkbox-options-container,.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;border-radius:6px;outline:none;width:100%}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.form-preview{width:100%;height:fit-content;min-height:250px;max-height:calc(100vh - 20px);overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px}.required:after{content:\" *\";color:red;margin-left:5px}.highlight{border:2px solid #5592FD!important;background-color:#eff8ff}.delete-icon{width:15px;height:15px}.element.disabled{opacity:.5;cursor:not-allowed}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-container{display:flex;flex-direction:column;padding:10px;border:1px dashed #ccc;border-radius:5px;background-color:#f9f9f9}.logo-preview{position:relative;border:1px solid #e0e0e0;background-color:#fff;overflow:hidden}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.choose-icon-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:48px;height:150px;border:2px dashed #ccc;cursor:pointer}\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: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BookletComponent$1, selector: "lib-booklet", inputs: ["bookletId", "serv", "tkn", "bookletJSON", "allIcons", "themeColor", "cdnIconURL", "dropdownDependentData", "labelValue", "token", "languageCode", "fieldRestrictions", "from", "apiUrl", "isEdit", "direction", "isLoading", "onlyView", "dataBind"], outputs: ["handleBookletActionEvent", "handlePage", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent", "formEditEvent"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "summaryValues", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "hideSaveButton", "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: 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: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }] });
|
|
65470
67292
|
}
|
|
65471
67293
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ElementComponent, decorators: [{
|
|
65472
67294
|
type: Component,
|
|
65473
67295
|
args: [{ selector: "app-element", standalone: true, imports: [
|
|
65474
67296
|
CommonModule,
|
|
65475
67297
|
FormsModule,
|
|
65476
|
-
BookletComponent,
|
|
67298
|
+
BookletComponent$1,
|
|
65477
67299
|
NxtDatatable,
|
|
65478
67300
|
nxtDropdown,
|
|
65479
67301
|
NxtCustomTranslatePipe
|
|
@@ -65538,14 +67360,14 @@ class NxtAppModule {
|
|
|
65538
67360
|
NxtInput,
|
|
65539
67361
|
NxtMultiSelect,
|
|
65540
67362
|
QuestionnaireComponent,
|
|
65541
|
-
BookletComponent,
|
|
67363
|
+
BookletComponent$1,
|
|
65542
67364
|
QuestionbookComponent,
|
|
65543
67365
|
NxtButtonComponent,
|
|
65544
67366
|
IconSelectorComponent, //MSM10JUL25 import icon selector component
|
|
65545
67367
|
PdfDesignerComponent,
|
|
65546
67368
|
FormComponent], exports: [NxtAppComponent,
|
|
65547
67369
|
QuestionnaireComponent,
|
|
65548
|
-
BookletComponent,
|
|
67370
|
+
BookletComponent$1,
|
|
65549
67371
|
NxtDatatable,
|
|
65550
67372
|
NxtSearchBox,
|
|
65551
67373
|
ListViewFilterComponent,
|
|
@@ -65571,7 +67393,7 @@ class NxtAppModule {
|
|
|
65571
67393
|
NxtInput,
|
|
65572
67394
|
NxtMultiSelect,
|
|
65573
67395
|
QuestionnaireComponent,
|
|
65574
|
-
BookletComponent,
|
|
67396
|
+
BookletComponent$1,
|
|
65575
67397
|
QuestionbookComponent,
|
|
65576
67398
|
NxtButtonComponent,
|
|
65577
67399
|
IconSelectorComponent, //MSM10JUL25 import icon selector component
|
|
@@ -65590,7 +67412,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
65590
67412
|
NxtInput,
|
|
65591
67413
|
NxtMultiSelect,
|
|
65592
67414
|
QuestionnaireComponent,
|
|
65593
|
-
BookletComponent,
|
|
67415
|
+
BookletComponent$1,
|
|
65594
67416
|
QuestionbookComponent,
|
|
65595
67417
|
NxtButtonComponent,
|
|
65596
67418
|
IconSelectorComponent, //MSM10JUL25 import icon selector component
|
|
@@ -65601,7 +67423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
65601
67423
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
65602
67424
|
exports: [NxtAppComponent,
|
|
65603
67425
|
QuestionnaireComponent,
|
|
65604
|
-
BookletComponent,
|
|
67426
|
+
BookletComponent$1,
|
|
65605
67427
|
NxtDatatable,
|
|
65606
67428
|
NxtSearchBox,
|
|
65607
67429
|
ListViewFilterComponent,
|
|
@@ -65633,5 +67455,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
65633
67455
|
* Generated bundle index. Do not edit.
|
|
65634
67456
|
*/
|
|
65635
67457
|
|
|
65636
|
-
export { BookletComponent, FormComponent, IconSelectorComponent, ListViewFilterComponent, NxtAppComponent, NxtAppModule, NxtAppService, NxtButtonComponent, NxtDatatable, NxtDatePipe, NxtFileUpload, NxtInput, NxtMultiSelect, NxtSearchBox, PdfDesignerComponent, QuestionnaireComponent, SalesforceService, initializeApp, nxtDropdown };
|
|
67458
|
+
export { BookletComponent$1 as BookletComponent, FormComponent, IconSelectorComponent, ListViewFilterComponent, NxtAppComponent, NxtAppModule, NxtAppService, NxtButtonComponent, NxtDatatable, NxtDatePipe, NxtFileUpload, NxtInput, NxtMultiSelect, NxtSearchBox, PdfDesignerComponent, PdfDesignerService, QuestionnaireComponent, SalesforceService, initializeApp, nxtDropdown };
|
|
65637
67459
|
//# sourceMappingURL=rangertechnologies-ngnxt.mjs.map
|