commons-shared-web-ui 0.0.23 → 0.0.25
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/commons-shared-web-ui.mjs +276 -39
- package/fesm2022/commons-shared-web-ui.mjs.map +1 -1
- package/index.d.ts +85 -13
- package/package.json +1 -1
- package/src/lib/modules/confirmation-modal/confirmation-modal.theme.scss +1 -1
- package/src/lib/modules/smart-table/smart-table.theme.scss +4 -0
- package/src/lib/styles/utilities.scss +250 -0
|
@@ -44,7 +44,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
|
44
44
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
45
45
|
import * as i3 from '@angular/common/http';
|
|
46
46
|
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
|
47
|
-
import {
|
|
47
|
+
import { Subject, BehaviorSubject, combineLatest, forkJoin, takeUntil as takeUntil$1, of } from 'rxjs';
|
|
48
48
|
import * as i1$4 from '@angular/router';
|
|
49
49
|
import { RouterModule } from '@angular/router';
|
|
50
50
|
import { takeUntil, debounceTime, distinctUntilChanged, map, finalize, catchError } from 'rxjs/operators';
|
|
@@ -244,6 +244,9 @@ class SmartFormController {
|
|
|
244
244
|
/** Custom label keys for form actions (Next, Submit, Add, etc.) */
|
|
245
245
|
actionLabels;
|
|
246
246
|
fieldSubjects = new Map();
|
|
247
|
+
fileAdded$ = new Subject();
|
|
248
|
+
fileUploadFinished$ = new Subject();
|
|
249
|
+
fileRemoved$ = new Subject();
|
|
247
250
|
initialize(initialData) {
|
|
248
251
|
this.formData = { ...initialData };
|
|
249
252
|
this.fieldSubjects.forEach((subject, key) => {
|
|
@@ -1394,13 +1397,16 @@ class FormFieldComponent {
|
|
|
1394
1397
|
}
|
|
1395
1398
|
const placeholder = { mediaType: 'image', url: '', isUploading: true };
|
|
1396
1399
|
this._appendMediaItem(placeholder);
|
|
1400
|
+
this.controller.fileAdded$.next(file);
|
|
1397
1401
|
const formData = new FormData();
|
|
1398
1402
|
formData.append('file', file);
|
|
1399
|
-
if (mediaCfg.entityType)
|
|
1400
|
-
formData.append('entity_type', mediaCfg.entityType);
|
|
1401
1403
|
if (!mediaCfg.uploadUrl)
|
|
1402
1404
|
return;
|
|
1403
|
-
|
|
1405
|
+
let finalUrl = mediaCfg.uploadUrl;
|
|
1406
|
+
if (finalUrl.includes('{fileName}')) {
|
|
1407
|
+
finalUrl = finalUrl.replace('{fileName}', encodeURIComponent(file.name));
|
|
1408
|
+
}
|
|
1409
|
+
this.http.post(finalUrl, formData, { headers: this.getHeaders() })
|
|
1404
1410
|
.pipe(takeUntil(this.destroy$))
|
|
1405
1411
|
.subscribe({
|
|
1406
1412
|
next: (response) => {
|
|
@@ -1419,11 +1425,13 @@ class FormFieldComponent {
|
|
|
1419
1425
|
};
|
|
1420
1426
|
this.updateValue(current);
|
|
1421
1427
|
this.mediaCarouselIndex = current.length - 1;
|
|
1428
|
+
this.controller.fileUploadFinished$.next(file);
|
|
1422
1429
|
}
|
|
1423
1430
|
},
|
|
1424
1431
|
error: () => {
|
|
1425
1432
|
const cleaned = this.mediaItems.filter(m => m !== placeholder);
|
|
1426
1433
|
this.updateValue(cleaned.length ? cleaned : null);
|
|
1434
|
+
this.controller.fileUploadFinished$.next(file);
|
|
1427
1435
|
}
|
|
1428
1436
|
});
|
|
1429
1437
|
});
|
|
@@ -1462,12 +1470,14 @@ class FormFieldComponent {
|
|
|
1462
1470
|
? [...(this.value || []), entry]
|
|
1463
1471
|
: [entry];
|
|
1464
1472
|
this.updateValue(withPlaceholder);
|
|
1473
|
+
this.controller.fileAdded$.next(file);
|
|
1465
1474
|
const formData = new FormData();
|
|
1466
1475
|
formData.append('file', file);
|
|
1467
|
-
|
|
1468
|
-
|
|
1476
|
+
let finalUrl = cfg.uploadUrl;
|
|
1477
|
+
if (finalUrl.includes('{fileName}')) {
|
|
1478
|
+
finalUrl = finalUrl.replace('{fileName}', encodeURIComponent(file.name));
|
|
1469
1479
|
}
|
|
1470
|
-
this.http.post(
|
|
1480
|
+
this.http.post(finalUrl, formData, { headers: this.getHeaders() })
|
|
1471
1481
|
.pipe(takeUntil(this.destroy$))
|
|
1472
1482
|
.subscribe({
|
|
1473
1483
|
next: (response) => {
|
|
@@ -1481,6 +1491,7 @@ class FormFieldComponent {
|
|
|
1481
1491
|
const updatedList = [...current];
|
|
1482
1492
|
updatedList[idx] = updatedEntry;
|
|
1483
1493
|
this.updateValue(updatedList);
|
|
1494
|
+
this.controller.fileUploadFinished$.next(file);
|
|
1484
1495
|
}
|
|
1485
1496
|
},
|
|
1486
1497
|
error: () => {
|
|
@@ -1489,6 +1500,7 @@ class FormFieldComponent {
|
|
|
1489
1500
|
const cleaned = current.filter(f => f !== entry);
|
|
1490
1501
|
this.updateValue(cleaned.length ? cleaned : null);
|
|
1491
1502
|
this.fileUploadError = `Failed to upload "${file.name}". Please try again.`;
|
|
1503
|
+
this.controller.fileUploadFinished$.next(file);
|
|
1492
1504
|
}
|
|
1493
1505
|
});
|
|
1494
1506
|
}
|
|
@@ -1531,13 +1543,14 @@ class FormFieldComponent {
|
|
|
1531
1543
|
}
|
|
1532
1544
|
if (!deleteUrl.includes('reason=')) {
|
|
1533
1545
|
// As requested in the API link, the reason is passed
|
|
1534
|
-
params = params.set('reason', '
|
|
1546
|
+
params = params.set('reason', 'DELETED BY CREATOR');
|
|
1535
1547
|
}
|
|
1536
1548
|
this.http.delete(deleteUrl, { headers: this.getHeaders(), params })
|
|
1537
1549
|
.pipe(takeUntil(this.destroy$))
|
|
1538
1550
|
.subscribe({
|
|
1539
1551
|
next: () => {
|
|
1540
1552
|
removeLocally();
|
|
1553
|
+
this.controller.fileRemoved$.next(fileToRemove);
|
|
1541
1554
|
},
|
|
1542
1555
|
error: (err) => {
|
|
1543
1556
|
console.error('Failed to delete attachment', err);
|
|
@@ -1549,6 +1562,7 @@ class FormFieldComponent {
|
|
|
1549
1562
|
}
|
|
1550
1563
|
else {
|
|
1551
1564
|
removeLocally();
|
|
1565
|
+
this.controller.fileRemoved$.next(fileToRemove);
|
|
1552
1566
|
}
|
|
1553
1567
|
}
|
|
1554
1568
|
getFileIcon(mimeType) {
|
|
@@ -1883,7 +1897,10 @@ class FormFieldComponent {
|
|
|
1883
1897
|
this.http.delete(deleteUrl, { headers: this.getHeaders(), params })
|
|
1884
1898
|
.pipe(takeUntil(this.destroy$))
|
|
1885
1899
|
.subscribe({
|
|
1886
|
-
next: () =>
|
|
1900
|
+
next: () => {
|
|
1901
|
+
removeLocally();
|
|
1902
|
+
this.controller.fileRemoved$.next(item);
|
|
1903
|
+
},
|
|
1887
1904
|
error: (err) => {
|
|
1888
1905
|
console.error('Failed to delete media attachment', err);
|
|
1889
1906
|
item.isUploading = false;
|
|
@@ -1894,6 +1911,7 @@ class FormFieldComponent {
|
|
|
1894
1911
|
else {
|
|
1895
1912
|
// ── No id or no deleteUrl: remove locally, no API call ───────────────
|
|
1896
1913
|
removeLocally();
|
|
1914
|
+
this.controller.fileRemoved$.next(item);
|
|
1897
1915
|
}
|
|
1898
1916
|
}
|
|
1899
1917
|
_appendMediaItem(item) {
|
|
@@ -2307,6 +2325,9 @@ class SmartFormComponent {
|
|
|
2307
2325
|
*/
|
|
2308
2326
|
actionClick = new EventEmitter();
|
|
2309
2327
|
valueChange = new EventEmitter();
|
|
2328
|
+
fileAdded = new EventEmitter();
|
|
2329
|
+
fileUploadFinished = new EventEmitter();
|
|
2330
|
+
fileRemoved = new EventEmitter();
|
|
2310
2331
|
formSchema;
|
|
2311
2332
|
formGroup;
|
|
2312
2333
|
fieldList = [];
|
|
@@ -2331,6 +2352,9 @@ class SmartFormComponent {
|
|
|
2331
2352
|
else if (this.initialValues) {
|
|
2332
2353
|
this.controller.initialize(this.initialValues);
|
|
2333
2354
|
}
|
|
2355
|
+
this.controller.fileAdded$.pipe(takeUntil$1(this.destroy$)).subscribe(file => this.fileAdded.emit(file));
|
|
2356
|
+
this.controller.fileUploadFinished$.pipe(takeUntil$1(this.destroy$)).subscribe(file => this.fileUploadFinished.emit(file));
|
|
2357
|
+
this.controller.fileRemoved$.pipe(takeUntil$1(this.destroy$)).subscribe(file => this.fileRemoved.emit(file));
|
|
2334
2358
|
}
|
|
2335
2359
|
loadEditData() {
|
|
2336
2360
|
const config = this.formSchema.editConfig;
|
|
@@ -2836,7 +2860,7 @@ class SmartFormComponent {
|
|
|
2836
2860
|
}
|
|
2837
2861
|
}
|
|
2838
2862
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartFormComponent, deps: [{ token: i1$3.FormBuilder }, { token: SmartFormController }, { token: ExpressionService }, { token: i3.HttpClient }, { token: SnackbarService }, { token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
2839
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SmartFormComponent, isStandalone: false, selector: "lib-smart-form", inputs: { formJson: "formJson", initialValues: "initialValues", enableDraftAutoSave: "enableDraftAutoSave", labels: "labels", mode: "mode" }, outputs: { submit: "submit", draftSave: "draftSave", actionClick: "actionClick", valueChange: "valueChange" }, providers: [SmartFormController], usesOnChanges: true, ngImport: i0, template: "<div class=\"smart-form-container\">\r\n <div class=\"smart-form-wrapper\" *ngIf=\"formSchema\">\r\n\r\n <!-- Form Header -->\r\n <div class=\"form-header\" *ngIf=\"formSchema.showTitle !== false\">\r\n <h2 class=\"form-title\">{{ formSchema.label }}</h2>\r\n <p class=\"form-description\" *ngIf=\"formSchema.description\">{{ formSchema.description }}</p>\r\n </div>\r\n\r\n <!-- Stepper Navigation -->\r\n <div class=\"stepper-nav\" *ngIf=\"isStepper && formSchema.stepperConfig?.showStep !== false\">\r\n <div class=\"stepper-steps\" [class.horizontal]=\"formSchema.stepperConfig?.isHorizontal !== false\">\r\n <div *ngFor=\"let step of fieldList; let i = index\" class=\"stepper-step\" [class.active]=\"i === currentStep\"\r\n [class.completed]=\"i < currentStep\">\r\n <div class=\"step-number\">{{ i + 1 }}</div>\r\n <div class=\"step-label\">{{ step.sectionConfig?.label || 'Step ' + (i + 1) }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Form Content -->\r\n <form [formGroup]=\"formGroup\" class=\"smart-form\">\r\n <!-- Section Form -->\r\n <div *ngIf=\"!isStepper && formSchema.sectionConfig && formSchema.sectionConfig.isEnabled !== false\" class=\"form-section\">\r\n <lib-form-section [config]=\"formSchema.sectionConfig\" [controller]=\"controller\" [formGroup]=\"formGroup\">\r\n </lib-form-section>\r\n </div>\r\n\r\n <!-- Stepper Form -->\r\n <div *ngIf=\"isStepper && currentStepConfig && currentStepConfig.sectionConfig?.isEnabled !== false\" class=\"form-stepper\">\r\n <lib-form-section [config]=\"currentStepConfig.sectionConfig!\" [controller]=\"controller\" [formGroup]=\"formGroup\">\r\n </lib-form-section>\r\n </div>\r\n </form>\r\n\r\n <!-- \u2500\u2500 Form Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\r\n <div class=\"form-actions\" *ngIf=\"formSchema.showActions !== false\">\r\n\r\n <!-- LEFT GROUP -->\r\n <div class=\"action-group action-group--left\">\r\n <!-- Optional: Navigational buttons like 'Previous' for stepper can be explicitly added to config, \r\n but we'll keep the logic if they are provided in the buttons array via action.kind === 'prev' -->\r\n <lib-button\r\n *ngFor=\"let btn of getButtonsForAlignment('left')\"\r\n [variant]=\"$any(btn.variant) || 'outline'\"\r\n [disabled]=\"isButtonDisabled(btn)\"\r\n (click)=\"handleButtonClick(btn)\">\r\n {{ getButtonLabel(btn) }}\r\n </lib-button>\r\n </div>\r\n\r\n <!-- RIGHT GROUP -->\r\n <div class=\"action-group action-group--right\">\r\n <lib-button\r\n *ngFor=\"let btn of getButtonsForAlignment('right')\"\r\n [variant]=\"$any(btn.variant) || 'primary'\"\r\n [disabled]=\"isButtonDisabled(btn)\"\r\n (click)=\"handleButtonClick(btn)\">\r\n {{ getButtonLabel(btn) }}\r\n </lib-button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".smart-form-container{width:100%;font-family:var(--cc-sf-font-family, \"Inter\", sans-serif)}.smart-form-wrapper{background:var(--cc-sf-form-bg, #ffffff);border-radius:var(--cc-sf-form-border-radius, 12px);border:var(--cc-sf-form-border, none);box-shadow:var(--cc-sf-form-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.smart-form-wrapper .form-alert-feedback{margin-bottom:1rem}.form-header .form-title{font-size:var(--cc-sf-form-title-size, 1.5rem);font-weight:var(--cc-sf-form-title-weight, 700);color:var(--cc-sf-form-title-color, #111827);margin:0 0 8px;line-height:1.25}.form-header .form-description{font-size:var(--cc-sf-form-desc-size, .875rem);color:var(--cc-sf-form-desc-color, #6B7280);margin:0}.stepper-nav{margin-bottom:32px}.stepper-nav .stepper-steps{display:flex;gap:16px}.stepper-nav .stepper-steps.horizontal{flex-direction:row;justify-content:space-between}.stepper-nav .stepper-steps:not(.horizontal){flex-direction:column}.stepper-nav .stepper-step{display:flex;align-items:center;gap:12px;flex:1;position:relative}.stepper-nav .stepper-step:not(:last-child):after{content:\"\";position:absolute;top:calc(var(--cc-sf-step-number-size, 40px) / 2);left:calc(100% + 8px);width:calc(100% - 40px);height:2px;background:var(--cc-sf-step-connector-color, #E5E7EB);transition:background var(--cc-sf-btn-transition, .2s ease)}.stepper-nav .stepper-step.completed:after{background:var(--cc-sf-step-connector-done, #22C55E)}.stepper-nav .stepper-step .step-number{width:var(--cc-sf-step-number-size, 40px);height:var(--cc-sf-step-number-size, 40px);min-width:var(--cc-sf-step-number-size, 40px);border-radius:50%;background:var(--cc-sf-step-number-bg, #E5E7EB);color:var(--cc-sf-step-number-color, #6B7280);display:flex;align-items:center;justify-content:center;font-size:var(--cc-sf-step-number-font-size, .875rem);font-weight:var(--cc-sf-step-number-weight, 600);transition:var(--cc-sf-btn-transition, all .2s ease)}.stepper-nav .stepper-step .step-label{font-size:var(--cc-sf-step-label-size, .875rem);color:var(--cc-sf-step-label-color, #6B7280);font-weight:var(--cc-sf-step-label-weight, 500);transition:var(--cc-sf-btn-transition, all .2s ease)}.stepper-nav .stepper-step.active .step-number{background:var(--cc-sf-step-active-bg, #3B82F6);color:var(--cc-sf-step-active-color, #ffffff)}.stepper-nav .stepper-step.active .step-label{color:var(--cc-sf-step-active-label, #1D4ED8);font-weight:var(--cc-sf-step-active-label-weight, 700)}.stepper-nav .stepper-step.completed .step-number{background:var(--cc-sf-step-done-bg, #22C55E);color:var(--cc-sf-step-done-color, #ffffff)}.smart-form{margin-bottom:24px}.form-actions{display:flex;justify-content:space-between;align-items:center;gap:var(--cc-sf-actions-gap, 12px);padding:var(--cc-sf-actions-padding, 20px 0 0);border-top:var(--cc-sf-actions-border, 1px solid #E5E7EB)}.form-actions .action-group{display:flex;align-items:center;gap:var(--cc-sf-actions-gap, 12px)}.form-actions .action-group--left{justify-content:flex-start}.form-actions .action-group--right{justify-content:flex-end;margin-left:auto}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }, { kind: "component", type: FormSectionComponent, selector: "lib-form-section", inputs: ["config", "controller", "formGroup"] }] });
|
|
2863
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SmartFormComponent, isStandalone: false, selector: "lib-smart-form", inputs: { formJson: "formJson", initialValues: "initialValues", enableDraftAutoSave: "enableDraftAutoSave", labels: "labels", mode: "mode" }, outputs: { submit: "submit", draftSave: "draftSave", actionClick: "actionClick", valueChange: "valueChange", fileAdded: "fileAdded", fileUploadFinished: "fileUploadFinished", fileRemoved: "fileRemoved" }, providers: [SmartFormController], usesOnChanges: true, ngImport: i0, template: "<div class=\"smart-form-container\">\r\n <div class=\"smart-form-wrapper\" *ngIf=\"formSchema\">\r\n\r\n <!-- Form Header -->\r\n <div class=\"form-header\" *ngIf=\"formSchema.showTitle !== false\">\r\n <h2 class=\"form-title\">{{ formSchema.label }}</h2>\r\n <p class=\"form-description\" *ngIf=\"formSchema.description\">{{ formSchema.description }}</p>\r\n </div>\r\n\r\n <!-- Stepper Navigation -->\r\n <div class=\"stepper-nav\" *ngIf=\"isStepper && formSchema.stepperConfig?.showStep !== false\">\r\n <div class=\"stepper-steps\" [class.horizontal]=\"formSchema.stepperConfig?.isHorizontal !== false\">\r\n <div *ngFor=\"let step of fieldList; let i = index\" class=\"stepper-step\" [class.active]=\"i === currentStep\"\r\n [class.completed]=\"i < currentStep\">\r\n <div class=\"step-number\">{{ i + 1 }}</div>\r\n <div class=\"step-label\">{{ step.sectionConfig?.label || 'Step ' + (i + 1) }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Form Content -->\r\n <form [formGroup]=\"formGroup\" class=\"smart-form\">\r\n <!-- Section Form -->\r\n <div *ngIf=\"!isStepper && formSchema.sectionConfig && formSchema.sectionConfig.isEnabled !== false\" class=\"form-section\">\r\n <lib-form-section [config]=\"formSchema.sectionConfig\" [controller]=\"controller\" [formGroup]=\"formGroup\">\r\n </lib-form-section>\r\n </div>\r\n\r\n <!-- Stepper Form -->\r\n <div *ngIf=\"isStepper && currentStepConfig && currentStepConfig.sectionConfig?.isEnabled !== false\" class=\"form-stepper\">\r\n <lib-form-section [config]=\"currentStepConfig.sectionConfig!\" [controller]=\"controller\" [formGroup]=\"formGroup\">\r\n </lib-form-section>\r\n </div>\r\n </form>\r\n\r\n <!-- \u2500\u2500 Form Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\r\n <div class=\"form-actions\" *ngIf=\"formSchema.showActions !== false\">\r\n\r\n <!-- LEFT GROUP -->\r\n <div class=\"action-group action-group--left\">\r\n <!-- Optional: Navigational buttons like 'Previous' for stepper can be explicitly added to config, \r\n but we'll keep the logic if they are provided in the buttons array via action.kind === 'prev' -->\r\n <lib-button\r\n *ngFor=\"let btn of getButtonsForAlignment('left')\"\r\n [variant]=\"$any(btn.variant) || 'outline'\"\r\n [disabled]=\"isButtonDisabled(btn)\"\r\n (click)=\"handleButtonClick(btn)\">\r\n {{ getButtonLabel(btn) }}\r\n </lib-button>\r\n </div>\r\n\r\n <!-- RIGHT GROUP -->\r\n <div class=\"action-group action-group--right\">\r\n <lib-button\r\n *ngFor=\"let btn of getButtonsForAlignment('right')\"\r\n [variant]=\"$any(btn.variant) || 'primary'\"\r\n [disabled]=\"isButtonDisabled(btn)\"\r\n (click)=\"handleButtonClick(btn)\">\r\n {{ getButtonLabel(btn) }}\r\n </lib-button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".smart-form-container{width:100%;font-family:var(--cc-sf-font-family, \"Inter\", sans-serif)}.smart-form-wrapper{background:var(--cc-sf-form-bg, #ffffff);border-radius:var(--cc-sf-form-border-radius, 12px);border:var(--cc-sf-form-border, none);box-shadow:var(--cc-sf-form-shadow, 0 1px 3px rgba(0, 0, 0, .06))}.smart-form-wrapper .form-alert-feedback{margin-bottom:1rem}.form-header .form-title{font-size:var(--cc-sf-form-title-size, 1.5rem);font-weight:var(--cc-sf-form-title-weight, 700);color:var(--cc-sf-form-title-color, #111827);margin:0 0 8px;line-height:1.25}.form-header .form-description{font-size:var(--cc-sf-form-desc-size, .875rem);color:var(--cc-sf-form-desc-color, #6B7280);margin:0}.stepper-nav{margin-bottom:32px}.stepper-nav .stepper-steps{display:flex;gap:16px}.stepper-nav .stepper-steps.horizontal{flex-direction:row;justify-content:space-between}.stepper-nav .stepper-steps:not(.horizontal){flex-direction:column}.stepper-nav .stepper-step{display:flex;align-items:center;gap:12px;flex:1;position:relative}.stepper-nav .stepper-step:not(:last-child):after{content:\"\";position:absolute;top:calc(var(--cc-sf-step-number-size, 40px) / 2);left:calc(100% + 8px);width:calc(100% - 40px);height:2px;background:var(--cc-sf-step-connector-color, #E5E7EB);transition:background var(--cc-sf-btn-transition, .2s ease)}.stepper-nav .stepper-step.completed:after{background:var(--cc-sf-step-connector-done, #22C55E)}.stepper-nav .stepper-step .step-number{width:var(--cc-sf-step-number-size, 40px);height:var(--cc-sf-step-number-size, 40px);min-width:var(--cc-sf-step-number-size, 40px);border-radius:50%;background:var(--cc-sf-step-number-bg, #E5E7EB);color:var(--cc-sf-step-number-color, #6B7280);display:flex;align-items:center;justify-content:center;font-size:var(--cc-sf-step-number-font-size, .875rem);font-weight:var(--cc-sf-step-number-weight, 600);transition:var(--cc-sf-btn-transition, all .2s ease)}.stepper-nav .stepper-step .step-label{font-size:var(--cc-sf-step-label-size, .875rem);color:var(--cc-sf-step-label-color, #6B7280);font-weight:var(--cc-sf-step-label-weight, 500);transition:var(--cc-sf-btn-transition, all .2s ease)}.stepper-nav .stepper-step.active .step-number{background:var(--cc-sf-step-active-bg, #3B82F6);color:var(--cc-sf-step-active-color, #ffffff)}.stepper-nav .stepper-step.active .step-label{color:var(--cc-sf-step-active-label, #1D4ED8);font-weight:var(--cc-sf-step-active-label-weight, 700)}.stepper-nav .stepper-step.completed .step-number{background:var(--cc-sf-step-done-bg, #22C55E);color:var(--cc-sf-step-done-color, #ffffff)}.smart-form{margin-bottom:24px}.form-actions{display:flex;justify-content:space-between;align-items:center;gap:var(--cc-sf-actions-gap, 12px);padding:var(--cc-sf-actions-padding, 20px 0 0);border-top:var(--cc-sf-actions-border, 1px solid #E5E7EB)}.form-actions .action-group{display:flex;align-items:center;gap:var(--cc-sf-actions-gap, 12px)}.form-actions .action-group--left{justify-content:flex-start}.form-actions .action-group--right{justify-content:flex-end;margin-left:auto}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }, { kind: "component", type: FormSectionComponent, selector: "lib-form-section", inputs: ["config", "controller", "formGroup"] }] });
|
|
2840
2864
|
}
|
|
2841
2865
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartFormComponent, decorators: [{
|
|
2842
2866
|
type: Component,
|
|
@@ -2859,6 +2883,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
2859
2883
|
type: Output
|
|
2860
2884
|
}], valueChange: [{
|
|
2861
2885
|
type: Output
|
|
2886
|
+
}], fileAdded: [{
|
|
2887
|
+
type: Output
|
|
2888
|
+
}], fileUploadFinished: [{
|
|
2889
|
+
type: Output
|
|
2890
|
+
}], fileRemoved: [{
|
|
2891
|
+
type: Output
|
|
2862
2892
|
}] } });
|
|
2863
2893
|
|
|
2864
2894
|
class ButtonModule {
|
|
@@ -4156,8 +4186,8 @@ class RadioComponent {
|
|
|
4156
4186
|
setDisabledState(isDisabled) {
|
|
4157
4187
|
this.disabled = isDisabled;
|
|
4158
4188
|
}
|
|
4159
|
-
onRadioChange(
|
|
4160
|
-
this.value =
|
|
4189
|
+
onRadioChange(option) {
|
|
4190
|
+
this.value = option.value;
|
|
4161
4191
|
this.onChange(this.value);
|
|
4162
4192
|
this.onTouched();
|
|
4163
4193
|
this.selectionChange.emit(this.value);
|
|
@@ -4165,6 +4195,19 @@ class RadioComponent {
|
|
|
4165
4195
|
getStyleValue(value) {
|
|
4166
4196
|
return value ? `${value}` : undefined;
|
|
4167
4197
|
}
|
|
4198
|
+
getThemeColor(colorStr) {
|
|
4199
|
+
if (!colorStr)
|
|
4200
|
+
return undefined;
|
|
4201
|
+
const themeColors = {
|
|
4202
|
+
'primary': 'var(--cc-radio-primary-bg, var(--cc-btn-primary-bg, #1A73E8))',
|
|
4203
|
+
'warning': 'var(--cc-radio-warning-bg, var(--cc-btn-warning-bg, #F9C80E))',
|
|
4204
|
+
'danger': 'var(--cc-radio-danger-bg, var(--cc-btn-danger-bg, #dc3545))',
|
|
4205
|
+
'success': 'var(--cc-radio-success-bg, var(--cc-btn-success-bg, #28a745))',
|
|
4206
|
+
'warn': 'var(--cc-radio-danger-bg, var(--cc-btn-danger-bg, #dc3545))',
|
|
4207
|
+
'accent': 'var(--cc-radio-accent-bg, #ff4081)'
|
|
4208
|
+
};
|
|
4209
|
+
return themeColors[colorStr] || colorStr;
|
|
4210
|
+
}
|
|
4168
4211
|
get wrapperStyles() {
|
|
4169
4212
|
return {
|
|
4170
4213
|
'--cc-radio-font-family': this.getStyleValue(this.fontFamily),
|
|
@@ -4173,7 +4216,7 @@ class RadioComponent {
|
|
|
4173
4216
|
'--cc-radio-label-color': this.getStyleValue(this.labelColor),
|
|
4174
4217
|
'--cc-radio-size': this.getStyleValue(this.size),
|
|
4175
4218
|
'--cc-radio-border-radius': this.getStyleValue(this.borderRadius),
|
|
4176
|
-
'--cc-radio-checked-color': this.getStyleValue(this.checkedColor),
|
|
4219
|
+
'--cc-radio-checked-color': this.getStyleValue(this.getThemeColor(this.checkedColor || this.color)),
|
|
4177
4220
|
'--cc-radio-unchecked-color': this.getStyleValue(this.uncheckedColor),
|
|
4178
4221
|
'--cc-radio-disabled-color': this.getStyleValue(this.disabledColor),
|
|
4179
4222
|
'--cc-radio-error-color': this.getStyleValue(this.errorColor),
|
|
@@ -4190,7 +4233,7 @@ class RadioComponent {
|
|
|
4190
4233
|
useExisting: forwardRef(() => RadioComponent),
|
|
4191
4234
|
multi: true
|
|
4192
4235
|
}
|
|
4193
|
-
], usesOnChanges: true, ngImport: i0, template: "<div class=\"cc-radio-wrapper\" [ngStyle]=\"wrapperStyles\">\r\n <label *ngIf=\"label\" class=\"cc-radio-group-label\" [class.disabled]=\"disabled\">\r\n {{ label }}\r\n <span *ngIf=\"required\" class=\"cc-required\">{{ requiredMarker }}</span>\r\n </label>\r\n\r\n <div class=\"cc-radio-group\" [class.horizontal]=\"layout === 'horizontal'\" [class.vertical]=\"layout === 'vertical'\"\r\n role=\"radiogroup\">\r\n\r\n <label class=\"cc-radio-label\" *ngFor=\"let option of options; let i = index\"\r\n [class.disabled]=\"disabled || option.disabled\" [class.checked]=\"value === option.value\"\r\n [class.label-before]=\"labelPosition === 'before'\">\r\n\r\n <input type=\"radio\" [name]=\"uuid\" [value]=\"option.value\" [checked]=\"value === option.value\"\r\n [disabled]=\"disabled || option.disabled\" (change)=\"onRadioChange(
|
|
4236
|
+
], usesOnChanges: true, ngImport: i0, template: "<div class=\"cc-radio-wrapper\" [ngStyle]=\"wrapperStyles\">\r\n <label *ngIf=\"label\" class=\"cc-radio-group-label\" [class.disabled]=\"disabled\">\r\n {{ label }}\r\n <span *ngIf=\"required\" class=\"cc-required\">{{ requiredMarker }}</span>\r\n </label>\r\n\r\n <div class=\"cc-radio-group\" [class.horizontal]=\"layout === 'horizontal'\" [class.vertical]=\"layout === 'vertical'\"\r\n role=\"radiogroup\">\r\n\r\n <label class=\"cc-radio-label\" *ngFor=\"let option of options; let i = index\"\r\n [class.disabled]=\"disabled || option.disabled\" [class.checked]=\"value === option.value\"\r\n [class.label-before]=\"labelPosition === 'before'\">\r\n\r\n <input type=\"radio\" [name]=\"uuid\" [value]=\"option.value\" [checked]=\"value === option.value\"\r\n [disabled]=\"disabled || option.disabled\" (change)=\"onRadioChange(option)\" class=\"cc-native-radio\"\r\n [id]=\"uuid + '-' + i\">\r\n\r\n <span class=\"cc-radio-circle\"></span>\r\n <span class=\"cc-text\">{{ option.label }}</span>\r\n </label>\r\n </div>\r\n</div>", styles: [".cc-radio-wrapper{display:block;width:100%;font-family:var(--cc-radio-font-family, inherit)}.cc-radio-group-label{display:block;font-size:var(--cc-radio-group-label-font-size, 14px);font-weight:var(--cc-radio-group-label-font-weight, 500);color:var(--cc-radio-group-label-color, #202124);margin-bottom:8px}.cc-radio-group{display:flex;gap:var(--cc-radio-group-gap, 12px)}.cc-radio-group.vertical{flex-direction:column}.cc-radio-group.horizontal{flex-direction:row;flex-wrap:wrap}.cc-radio-label{display:flex;align-items:center;cursor:pointer;font-size:var(--cc-radio-font-size, 14px);color:var(--cc-radio-label-color, #202124);-webkit-user-select:none;user-select:none;padding:4px 0}.cc-native-radio{position:absolute;left:-9999px}.cc-radio-circle{width:var(--cc-radio-size, 20px);height:var(--cc-radio-size, 20px);border:2px solid var(--cc-radio-unchecked-color, #5F6368);border-radius:var(--cc-radio-border-radius, 50%);margin-right:8px;flex-shrink:0;position:relative;background:#fff;box-sizing:border-box}.cc-radio-circle:after{content:\"\";width:calc(var(--cc-radio-size, 20px) * .5);height:calc(var(--cc-radio-size, 20px) * .5);background:var(--cc-radio-checked-color, #1A73E8);border-radius:var(--cc-radio-border-radius, 50%);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(0);transition:transform .2s}.cc-native-radio:checked+.cc-radio-circle{border-color:var(--cc-radio-checked-color, #1A73E8)}.cc-native-radio:checked+.cc-radio-circle:after{transform:translate(-50%,-50%) scale(1)}.cc-text{line-height:1.5}.cc-radio-label.disabled{opacity:.5;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
4194
4237
|
}
|
|
4195
4238
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadioComponent, decorators: [{
|
|
4196
4239
|
type: Component,
|
|
@@ -4200,7 +4243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
4200
4243
|
useExisting: forwardRef(() => RadioComponent),
|
|
4201
4244
|
multi: true
|
|
4202
4245
|
}
|
|
4203
|
-
], template: "<div class=\"cc-radio-wrapper\" [ngStyle]=\"wrapperStyles\">\r\n <label *ngIf=\"label\" class=\"cc-radio-group-label\" [class.disabled]=\"disabled\">\r\n {{ label }}\r\n <span *ngIf=\"required\" class=\"cc-required\">{{ requiredMarker }}</span>\r\n </label>\r\n\r\n <div class=\"cc-radio-group\" [class.horizontal]=\"layout === 'horizontal'\" [class.vertical]=\"layout === 'vertical'\"\r\n role=\"radiogroup\">\r\n\r\n <label class=\"cc-radio-label\" *ngFor=\"let option of options; let i = index\"\r\n [class.disabled]=\"disabled || option.disabled\" [class.checked]=\"value === option.value\"\r\n [class.label-before]=\"labelPosition === 'before'\">\r\n\r\n <input type=\"radio\" [name]=\"uuid\" [value]=\"option.value\" [checked]=\"value === option.value\"\r\n [disabled]=\"disabled || option.disabled\" (change)=\"onRadioChange(
|
|
4246
|
+
], template: "<div class=\"cc-radio-wrapper\" [ngStyle]=\"wrapperStyles\">\r\n <label *ngIf=\"label\" class=\"cc-radio-group-label\" [class.disabled]=\"disabled\">\r\n {{ label }}\r\n <span *ngIf=\"required\" class=\"cc-required\">{{ requiredMarker }}</span>\r\n </label>\r\n\r\n <div class=\"cc-radio-group\" [class.horizontal]=\"layout === 'horizontal'\" [class.vertical]=\"layout === 'vertical'\"\r\n role=\"radiogroup\">\r\n\r\n <label class=\"cc-radio-label\" *ngFor=\"let option of options; let i = index\"\r\n [class.disabled]=\"disabled || option.disabled\" [class.checked]=\"value === option.value\"\r\n [class.label-before]=\"labelPosition === 'before'\">\r\n\r\n <input type=\"radio\" [name]=\"uuid\" [value]=\"option.value\" [checked]=\"value === option.value\"\r\n [disabled]=\"disabled || option.disabled\" (change)=\"onRadioChange(option)\" class=\"cc-native-radio\"\r\n [id]=\"uuid + '-' + i\">\r\n\r\n <span class=\"cc-radio-circle\"></span>\r\n <span class=\"cc-text\">{{ option.label }}</span>\r\n </label>\r\n </div>\r\n</div>", styles: [".cc-radio-wrapper{display:block;width:100%;font-family:var(--cc-radio-font-family, inherit)}.cc-radio-group-label{display:block;font-size:var(--cc-radio-group-label-font-size, 14px);font-weight:var(--cc-radio-group-label-font-weight, 500);color:var(--cc-radio-group-label-color, #202124);margin-bottom:8px}.cc-radio-group{display:flex;gap:var(--cc-radio-group-gap, 12px)}.cc-radio-group.vertical{flex-direction:column}.cc-radio-group.horizontal{flex-direction:row;flex-wrap:wrap}.cc-radio-label{display:flex;align-items:center;cursor:pointer;font-size:var(--cc-radio-font-size, 14px);color:var(--cc-radio-label-color, #202124);-webkit-user-select:none;user-select:none;padding:4px 0}.cc-native-radio{position:absolute;left:-9999px}.cc-radio-circle{width:var(--cc-radio-size, 20px);height:var(--cc-radio-size, 20px);border:2px solid var(--cc-radio-unchecked-color, #5F6368);border-radius:var(--cc-radio-border-radius, 50%);margin-right:8px;flex-shrink:0;position:relative;background:#fff;box-sizing:border-box}.cc-radio-circle:after{content:\"\";width:calc(var(--cc-radio-size, 20px) * .5);height:calc(var(--cc-radio-size, 20px) * .5);background:var(--cc-radio-checked-color, #1A73E8);border-radius:var(--cc-radio-border-radius, 50%);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(0);transition:transform .2s}.cc-native-radio:checked+.cc-radio-circle{border-color:var(--cc-radio-checked-color, #1A73E8)}.cc-native-radio:checked+.cc-radio-circle:after{transform:translate(-50%,-50%) scale(1)}.cc-text{line-height:1.5}.cc-radio-label.disabled{opacity:.5;cursor:not-allowed}\n"] }]
|
|
4204
4247
|
}], propDecorators: { config: [{
|
|
4205
4248
|
type: Input
|
|
4206
4249
|
}], label: [{
|
|
@@ -4356,6 +4399,17 @@ class ToggleComponent {
|
|
|
4356
4399
|
getStyleValue(value) {
|
|
4357
4400
|
return value ? `${value}` : undefined;
|
|
4358
4401
|
}
|
|
4402
|
+
getThemeColor(colorStr) {
|
|
4403
|
+
if (!colorStr)
|
|
4404
|
+
return undefined;
|
|
4405
|
+
const themeColors = {
|
|
4406
|
+
'primary': 'var(--cc-toggle-primary-bg, var(--cc-btn-primary-bg, #1A73E8))',
|
|
4407
|
+
'warning': 'var(--cc-toggle-warning-bg, var(--cc-btn-warning-bg, #F9C80E))',
|
|
4408
|
+
'danger': 'var(--cc-toggle-danger-bg, var(--cc-btn-danger-bg, #dc3545))',
|
|
4409
|
+
'success': 'var(--cc-toggle-success-bg, var(--cc-btn-success-bg, #28a745))'
|
|
4410
|
+
};
|
|
4411
|
+
return themeColors[colorStr] || colorStr;
|
|
4412
|
+
}
|
|
4359
4413
|
get wrapperStyles() {
|
|
4360
4414
|
return {
|
|
4361
4415
|
'--cc-toggle-font-family': this.getStyleValue(this.fontFamily),
|
|
@@ -4366,7 +4420,7 @@ class ToggleComponent {
|
|
|
4366
4420
|
'--cc-toggle-height': this.getStyleValue(this.toggleHeight),
|
|
4367
4421
|
'--cc-toggle-gap': this.getStyleValue(this.gap),
|
|
4368
4422
|
'--cc-toggle-unchecked-bg': this.getStyleValue(this.uncheckedColor),
|
|
4369
|
-
'--cc-toggle-checked-bg': this.getStyleValue(this.checkedColor || this.color),
|
|
4423
|
+
'--cc-toggle-checked-bg': this.getStyleValue(this.getThemeColor(this.checkedColor || this.color)),
|
|
4370
4424
|
'--cc-toggle-thumb-color': this.getStyleValue(this.thumbColor || this.sliderColor),
|
|
4371
4425
|
'--cc-toggle-checked-thumb-color': this.getStyleValue(this.checkedThumbColor),
|
|
4372
4426
|
'--cc-toggle-disabled-color': this.getStyleValue(this.disabledColor)
|
|
@@ -6890,7 +6944,7 @@ class ConfiguratorConfigPanelComponent {
|
|
|
6890
6944
|
return patch;
|
|
6891
6945
|
}
|
|
6892
6946
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfiguratorConfigPanelComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6893
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfiguratorConfigPanelComponent, isStandalone: false, selector: "lib-configurator-config-panel", inputs: { selectedField: "selectedField", selectedFieldInfo: "selectedFieldInfo", builderFieldType: "builderFieldType", fieldTypeSchemaMap: "fieldTypeSchemaMap" }, outputs: { configChange: "configChange", typeChange: "typeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"fb-config-panel\">\r\n @if (!selectedField) {\r\n <div class=\"fb-config-panel__empty\">\r\n <div class=\"fb-config-panel__empty-icon\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"fb-config-panel__empty-text\">\r\n Select a field from the tree panel to edit its configuration.\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"fb-config-panel__header\">\r\n <div class=\"fb-config-panel__header-left\">\r\n <h3 class=\"fb-config-panel__title\">\r\n {{ selectedField.label || selectedField.name || 'Field Settings' }}\r\n </h3>\r\n @if (selectedField.type) {\r\n <span class=\"fb-config-panel__badge\">{{ selectedField.type }}</span>\r\n }\r\n </div>\r\n\r\n <!-- Field Type Switcher: hidden for DROPDOWN / MULTI_SELECT fields -->\r\n @if (!isDropdownType) {\r\n <div class=\"fb-config-panel__type-switcher\">\r\n <label class=\"fb-config-panel__type-label\" for=\"fb-field-type-select\">Field Type</label>\r\n <select\r\n id=\"fb-field-type-select\"\r\n class=\"fb-config-panel__type-select\"\r\n [value]=\"currentBuilderType\"\r\n (change)=\"onTypeSelectChange($event)\"\r\n >\r\n @for (opt of switchableFieldTypes; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-config-panel__form-wrapper\">\r\n @if (showConfigForm && configFormJson) {\r\n <div class=\"fb-config-card\">\r\n <lib-smart-form\r\n [formJson]=\"configFormJson\"\r\n [initialValues]=\"configInitialValues\"\r\n (actionClick)=\"onActionClick($event)\"\r\n />\r\n </div>\r\n } @else if (!showConfigForm) {\r\n <!-- intentionally empty \u2014 SmartForm is being recycled -->\r\n } @else {\r\n <div class=\"fb-config-panel__error\">\r\n No configuration schema available for this field type.\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".fb-config-panel{display:flex;flex-direction:column;height:100%;background:var(--fb-fc-panel-bg, #f9fafb);overflow:hidden}.fb-config-panel__empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--fb-fc-empty-color, #9ca3af);text-align:center;padding:48px}.fb-config-panel__empty-icon{margin-bottom:24px;opacity:.4;color:var(--fb-fc-accent, #3b82f6)}.fb-config-panel__empty-text{font-size:15px;max-width:320px;line-height:1.6;font-weight:500}.fb-config-panel__header{background:var(--fb-fc-header-bg, #ffffff);padding:20px 32px;border-bottom:1px solid var(--fb-fc-border, #e5e7eb);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;gap:16px;flex-wrap:wrap}.fb-config-panel__header-left{display:flex;align-items:center;gap:12px;min-width:0}.fb-config-panel__type-switcher{display:flex;align-items:center;gap:8px;flex-shrink:0}.fb-config-panel__type-label{font-size:var(--fb-fc-type-label-size, .75rem);font-weight:600;color:var(--fb-fc-type-label-color, #6b7280);white-space:nowrap}.fb-config-panel__type-select{height:var(--fb-fc-type-select-height, 36px);padding:0 32px 0 10px;border:1px solid var(--fb-fc-type-select-border, #d1d5db);border-radius:var(--fb-fc-type-select-radius, 8px);background-color:var(--fb-fc-type-select-bg, #ffffff);color:var(--fb-fc-type-select-color, #111827);font-size:.8125rem;font-weight:500;cursor:pointer;appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 8px center;min-width:160px;transition:border-color .15s ease,box-shadow .15s ease}.fb-config-panel__type-select:hover{border-color:var(--fb-fc-type-select-hover-border, #9ca3af)}.fb-config-panel__type-select:focus{outline:none;border-color:var(--fb-fc-accent, #3b82f6);box-shadow:0 0 0 3px #3b82f61f}.fb-config-panel__title{margin:0;font-size:1.25rem;font-weight:700;color:var(--fb-fc-title-color, #111827)}.fb-config-panel__badge{padding:4px 12px;background:var(--fb-fc-badge-bg, #eff6ff);color:var(--fb-fc-badge-color, #3b82f6);border-radius:20px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;border:1px solid var(--fb-fc-badge-border, #dbeafe)}.fb-config-panel__form-wrapper{flex:1;overflow-y:auto;padding:40px}.fb-config-panel__form-wrapper .fb-config-card{background:var(--fb-fc-card-bg, #ffffff);border-radius:12px;border:1px solid var(--fb-fc-card-border, #e5e7eb);padding:40px;box-shadow:0 4px 20px #00000008;max-width:800px;margin:0 auto;--cc-sf-font-family: Inter, Segoe UI, sans-serif;--cc-sf-font-size-base: .875rem;--cc-sf-form-bg: transparent;--cc-sf-form-padding: 0;--cc-sf-form-border-radius: 12px;--cc-sf-form-border: none;--cc-sf-form-shadow: none;--cc-sf-form-max-width: 1200px;--cc-sf-form-title-size: 1.5rem;--cc-sf-form-title-weight: 700;--cc-sf-form-title-color: #111827;--cc-sf-form-desc-size: .875rem;--cc-sf-form-desc-color: #6B7280;--cc-sf-section-bg: transparent;--cc-sf-section-border: none;--cc-sf-section-radius: 10px;--cc-sf-section-padding: 0;--cc-sf-section-shadow: none;--cc-sf-section-gap: 20px;--cc-sf-section-label-size: 1rem;--cc-sf-section-label-weight: 600;--cc-sf-section-label-color: #1F2937;--cc-sf-section-label-border: 2px solid #E5E7EB;--cc-sf-instance-bg: #F9FAFB;--cc-sf-instance-border: 1px solid #E5E7EB;--cc-sf-instance-radius: 8px;--cc-sf-instance-padding: 16px;--cc-sf-instance-divider: 1px dashed #D1D5DB;--cc-sf-instance-num-color:#4B5563;--cc-sf-instance-num-size: .8125rem;--cc-sf-grid-gap: 24px;--cc-sf-label-size: .8125rem;--cc-sf-label-weight: 600;--cc-sf-label-color: #111827;--cc-sf-label-required-color: #DC2626;--cc-sf-input-bg: #ffffff;--cc-sf-input-color: #111827;--cc-sf-input-placeholder: #9CA3AF;--cc-sf-input-border: 1.5px solid #D1D5DB;--cc-sf-input-radius: 8px;--cc-sf-input-padding: .75rem 1rem;--cc-sf-input-font-size: .875rem;--cc-sf-input-shadow: none;--cc-sf-input-hover-border:#9CA3AF;--cc-sf-input-focus-border:#3B82F6;--cc-sf-input-focus-shadow:0 0 0 3px rgba(59, 130, 246, .12);--cc-sf-input-transition: all .2s ease;--cc-sf-input-disabled-bg: #F3F4F6;--cc-sf-input-disabled-color: #6B7280;--cc-sf-input-disabled-border:#E5E7EB;--cc-sf-error-border: #DC2626;--cc-sf-error-bg: #FEF2F2;--cc-sf-error-focus-shadow: 0 0 0 3px rgba(220, 38, 38, .1);--cc-sf-error-text-color: #DC2626;--cc-sf-error-text-size: .75rem;--cc-sf-hint-color: #6B7280;--cc-sf-hint-size: .75rem;--cc-sf-chip-border: 1px solid #D1D5DB;--cc-sf-chip-radius: 20px;--cc-sf-chip-padding: 6px 14px;--cc-sf-chip-bg: #ffffff;--cc-sf-chip-color: #374151;--cc-sf-chip-hover-bg: #F3F4F6;--cc-sf-chip-selected-bg: #3B82F6;--cc-sf-chip-selected-color: #ffffff;--cc-sf-chip-selected-border:#3B82F6;--cc-sf-switch-track-off: #D1D5DB;--cc-sf-switch-track-on: #3B82F6;--cc-sf-switch-thumb: #ffffff;--cc-sf-star-empty: #D1D5DB;--cc-sf-star-filled: #F59E0B;--cc-sf-star-size: 28px;--cc-sf-generated-bg: #F3F4F6;--cc-sf-generated-border: 1px solid #E5E7EB;--cc-sf-generated-color: #6B7280;--cc-sf-generated-radius: 8px;--cc-sf-generated-padding: .625rem .875rem;--cc-sf-dropzone-bg: #FFFAF1;--cc-sf-dropzone-border: 1.5px dashed #CBD5E1;--cc-sf-dropzone-radius: 12px;--cc-sf-dropzone-hover-bg: #EFF6FF;--cc-sf-dropzone-hover-border: #93C5FD;--cc-sf-dropzone-over-border: #3B82F6;--cc-sf-dropzone-over-shadow: 0 0 0 4px rgba(59, 130, 246, .12);--cc-sf-dropzone-icon-color: #94A3B8;--cc-sf-dropzone-link-color: #3B82F6;--cc-sf-dropzone-hint-color: #64748B;--cc-sf-uploaded-item-bg: #ffffff;--cc-sf-uploaded-item-border: 1px solid #E2E8F0;--cc-sf-uploaded-item-radius: 8px;--cc-sf-uploaded-remove-color: #94A3B8;--cc-sf-uploaded-remove-hover-bg: #FEF2F2;--cc-sf-uploaded-remove-hover-color: #DC2626;--cc-sf-btn-add-bg: transparent;--cc-sf-btn-add-color: #3B82F6;--cc-sf-btn-add-border: 1px dashed #CBD5E1;--cc-sf-btn-add-radius: 6px;--cc-sf-btn-add-hover-bg: #EFF6FF;--cc-sf-btn-add-hover-border: #BFDBFE;--cc-sf-btn-remove-bg: #FFF5F5;--cc-sf-btn-remove-color: #E53E3E;--cc-sf-btn-remove-border: 1px solid #FED7D7;--cc-sf-btn-remove-radius: 4px;--cc-sf-btn-remove-hover-bg: #FED7D7;--cc-sf-step-connector-color: #E5E7EB;--cc-sf-step-connector-done: #22C55E;--cc-sf-step-number-bg: #E5E7EB;--cc-sf-step-number-color: #6B7280;--cc-sf-step-number-size: 40px;--cc-sf-step-number-font-size: .875rem;--cc-sf-step-number-weight: 600;--cc-sf-step-label-size: .875rem;--cc-sf-step-label-color: #6B7280;--cc-sf-step-label-weight: 500;--cc-sf-step-active-bg: #3B82F6;--cc-sf-step-active-color: #ffffff;--cc-sf-step-active-label: #1D4ED8;--cc-sf-step-active-label-weight: 700;--cc-sf-step-done-bg: #22C55E;--cc-sf-step-done-color: #ffffff;--cc-sf-actions-border: 1px solid #E5E7EB;--cc-sf-actions-padding: 20px 0 0;--cc-sf-actions-gap: 12px;--cc-sf-btn-primary-bg: #3B82F6;--cc-sf-btn-primary-color: #ffffff;--cc-sf-btn-primary-radius: 8px;--cc-sf-btn-primary-padding: .625rem 1.5rem;--cc-sf-btn-primary-hover-bg: #2563EB;--cc-sf-btn-secondary-bg: #F3F4F6;--cc-sf-btn-secondary-color: #374151;--cc-sf-btn-secondary-radius: 8px;--cc-sf-btn-secondary-padding: .625rem 1.5rem;--cc-sf-btn-secondary-hover-bg: #E5E7EB;--cc-sf-btn-font-size: .875rem;--cc-sf-btn-font-weight: 600;--cc-sf-btn-transition: all .2s ease;--cc-sf-btn-disabled-opacity: .55}.fb-config-panel__error{padding:24px;background:var(--fb-fc-error-bg, #fef2f2);color:var(--fb-fc-error-color, #dc2626);border:1px solid var(--fb-fc-error-border, #fee2e2);border-radius:8px;font-size:14px;font-weight:500}\n"], dependencies: [{ kind: "component", type: SmartFormComponent, selector: "lib-smart-form", inputs: ["formJson", "initialValues", "enableDraftAutoSave", "labels", "mode"], outputs: ["submit", "draftSave", "actionClick", "valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6947
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfiguratorConfigPanelComponent, isStandalone: false, selector: "lib-configurator-config-panel", inputs: { selectedField: "selectedField", selectedFieldInfo: "selectedFieldInfo", builderFieldType: "builderFieldType", fieldTypeSchemaMap: "fieldTypeSchemaMap" }, outputs: { configChange: "configChange", typeChange: "typeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"fb-config-panel\">\r\n @if (!selectedField) {\r\n <div class=\"fb-config-panel__empty\">\r\n <div class=\"fb-config-panel__empty-icon\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"fb-config-panel__empty-text\">\r\n Select a field from the tree panel to edit its configuration.\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"fb-config-panel__header\">\r\n <div class=\"fb-config-panel__header-left\">\r\n <h3 class=\"fb-config-panel__title\">\r\n {{ selectedField.label || selectedField.name || 'Field Settings' }}\r\n </h3>\r\n @if (selectedField.type) {\r\n <span class=\"fb-config-panel__badge\">{{ selectedField.type }}</span>\r\n }\r\n </div>\r\n\r\n <!-- Field Type Switcher: hidden for DROPDOWN / MULTI_SELECT fields -->\r\n @if (!isDropdownType) {\r\n <div class=\"fb-config-panel__type-switcher\">\r\n <label class=\"fb-config-panel__type-label\" for=\"fb-field-type-select\">Field Type</label>\r\n <select\r\n id=\"fb-field-type-select\"\r\n class=\"fb-config-panel__type-select\"\r\n [value]=\"currentBuilderType\"\r\n (change)=\"onTypeSelectChange($event)\"\r\n >\r\n @for (opt of switchableFieldTypes; track opt.value) {\r\n <option [value]=\"opt.value\">{{ opt.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"fb-config-panel__form-wrapper\">\r\n @if (showConfigForm && configFormJson) {\r\n <div class=\"fb-config-card\">\r\n <lib-smart-form\r\n [formJson]=\"configFormJson\"\r\n [initialValues]=\"configInitialValues\"\r\n (actionClick)=\"onActionClick($event)\"\r\n />\r\n </div>\r\n } @else if (!showConfigForm) {\r\n <!-- intentionally empty \u2014 SmartForm is being recycled -->\r\n } @else {\r\n <div class=\"fb-config-panel__error\">\r\n No configuration schema available for this field type.\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".fb-config-panel{display:flex;flex-direction:column;height:100%;background:var(--fb-fc-panel-bg, #f9fafb);overflow:hidden}.fb-config-panel__empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--fb-fc-empty-color, #9ca3af);text-align:center;padding:48px}.fb-config-panel__empty-icon{margin-bottom:24px;opacity:.4;color:var(--fb-fc-accent, #3b82f6)}.fb-config-panel__empty-text{font-size:15px;max-width:320px;line-height:1.6;font-weight:500}.fb-config-panel__header{background:var(--fb-fc-header-bg, #ffffff);padding:20px 32px;border-bottom:1px solid var(--fb-fc-border, #e5e7eb);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;gap:16px;flex-wrap:wrap}.fb-config-panel__header-left{display:flex;align-items:center;gap:12px;min-width:0}.fb-config-panel__type-switcher{display:flex;align-items:center;gap:8px;flex-shrink:0}.fb-config-panel__type-label{font-size:var(--fb-fc-type-label-size, .75rem);font-weight:600;color:var(--fb-fc-type-label-color, #6b7280);white-space:nowrap}.fb-config-panel__type-select{height:var(--fb-fc-type-select-height, 36px);padding:0 32px 0 10px;border:1px solid var(--fb-fc-type-select-border, #d1d5db);border-radius:var(--fb-fc-type-select-radius, 8px);background-color:var(--fb-fc-type-select-bg, #ffffff);color:var(--fb-fc-type-select-color, #111827);font-size:.8125rem;font-weight:500;cursor:pointer;appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 8px center;min-width:160px;transition:border-color .15s ease,box-shadow .15s ease}.fb-config-panel__type-select:hover{border-color:var(--fb-fc-type-select-hover-border, #9ca3af)}.fb-config-panel__type-select:focus{outline:none;border-color:var(--fb-fc-accent, #3b82f6);box-shadow:0 0 0 3px #3b82f61f}.fb-config-panel__title{margin:0;font-size:1.25rem;font-weight:700;color:var(--fb-fc-title-color, #111827)}.fb-config-panel__badge{padding:4px 12px;background:var(--fb-fc-badge-bg, #eff6ff);color:var(--fb-fc-badge-color, #3b82f6);border-radius:20px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;border:1px solid var(--fb-fc-badge-border, #dbeafe)}.fb-config-panel__form-wrapper{flex:1;overflow-y:auto;padding:40px}.fb-config-panel__form-wrapper .fb-config-card{background:var(--fb-fc-card-bg, #ffffff);border-radius:12px;border:1px solid var(--fb-fc-card-border, #e5e7eb);padding:40px;box-shadow:0 4px 20px #00000008;max-width:800px;margin:0 auto;--cc-sf-font-family: Inter, Segoe UI, sans-serif;--cc-sf-font-size-base: .875rem;--cc-sf-form-bg: transparent;--cc-sf-form-padding: 0;--cc-sf-form-border-radius: 12px;--cc-sf-form-border: none;--cc-sf-form-shadow: none;--cc-sf-form-max-width: 1200px;--cc-sf-form-title-size: 1.5rem;--cc-sf-form-title-weight: 700;--cc-sf-form-title-color: #111827;--cc-sf-form-desc-size: .875rem;--cc-sf-form-desc-color: #6B7280;--cc-sf-section-bg: transparent;--cc-sf-section-border: none;--cc-sf-section-radius: 10px;--cc-sf-section-padding: 0;--cc-sf-section-shadow: none;--cc-sf-section-gap: 20px;--cc-sf-section-label-size: 1rem;--cc-sf-section-label-weight: 600;--cc-sf-section-label-color: #1F2937;--cc-sf-section-label-border: 2px solid #E5E7EB;--cc-sf-instance-bg: #F9FAFB;--cc-sf-instance-border: 1px solid #E5E7EB;--cc-sf-instance-radius: 8px;--cc-sf-instance-padding: 16px;--cc-sf-instance-divider: 1px dashed #D1D5DB;--cc-sf-instance-num-color:#4B5563;--cc-sf-instance-num-size: .8125rem;--cc-sf-grid-gap: 24px;--cc-sf-label-size: .8125rem;--cc-sf-label-weight: 600;--cc-sf-label-color: #111827;--cc-sf-label-required-color: #DC2626;--cc-sf-input-bg: #ffffff;--cc-sf-input-color: #111827;--cc-sf-input-placeholder: #9CA3AF;--cc-sf-input-border: 1.5px solid #D1D5DB;--cc-sf-input-radius: 8px;--cc-sf-input-padding: .75rem 1rem;--cc-sf-input-font-size: .875rem;--cc-sf-input-shadow: none;--cc-sf-input-hover-border:#9CA3AF;--cc-sf-input-focus-border:#3B82F6;--cc-sf-input-focus-shadow:0 0 0 3px rgba(59, 130, 246, .12);--cc-sf-input-transition: all .2s ease;--cc-sf-input-disabled-bg: #F3F4F6;--cc-sf-input-disabled-color: #6B7280;--cc-sf-input-disabled-border:#E5E7EB;--cc-sf-error-border: #DC2626;--cc-sf-error-bg: #FEF2F2;--cc-sf-error-focus-shadow: 0 0 0 3px rgba(220, 38, 38, .1);--cc-sf-error-text-color: #DC2626;--cc-sf-error-text-size: .75rem;--cc-sf-hint-color: #6B7280;--cc-sf-hint-size: .75rem;--cc-sf-chip-border: 1px solid #D1D5DB;--cc-sf-chip-radius: 20px;--cc-sf-chip-padding: 6px 14px;--cc-sf-chip-bg: #ffffff;--cc-sf-chip-color: #374151;--cc-sf-chip-hover-bg: #F3F4F6;--cc-sf-chip-selected-bg: #3B82F6;--cc-sf-chip-selected-color: #ffffff;--cc-sf-chip-selected-border:#3B82F6;--cc-sf-switch-track-off: #D1D5DB;--cc-sf-switch-track-on: #3B82F6;--cc-sf-switch-thumb: #ffffff;--cc-sf-star-empty: #D1D5DB;--cc-sf-star-filled: #F59E0B;--cc-sf-star-size: 28px;--cc-sf-generated-bg: #F3F4F6;--cc-sf-generated-border: 1px solid #E5E7EB;--cc-sf-generated-color: #6B7280;--cc-sf-generated-radius: 8px;--cc-sf-generated-padding: .625rem .875rem;--cc-sf-dropzone-bg: #FFFAF1;--cc-sf-dropzone-border: 1.5px dashed #CBD5E1;--cc-sf-dropzone-radius: 12px;--cc-sf-dropzone-hover-bg: #EFF6FF;--cc-sf-dropzone-hover-border: #93C5FD;--cc-sf-dropzone-over-border: #3B82F6;--cc-sf-dropzone-over-shadow: 0 0 0 4px rgba(59, 130, 246, .12);--cc-sf-dropzone-icon-color: #94A3B8;--cc-sf-dropzone-link-color: #3B82F6;--cc-sf-dropzone-hint-color: #64748B;--cc-sf-uploaded-item-bg: #ffffff;--cc-sf-uploaded-item-border: 1px solid #E2E8F0;--cc-sf-uploaded-item-radius: 8px;--cc-sf-uploaded-remove-color: #94A3B8;--cc-sf-uploaded-remove-hover-bg: #FEF2F2;--cc-sf-uploaded-remove-hover-color: #DC2626;--cc-sf-btn-add-bg: transparent;--cc-sf-btn-add-color: #3B82F6;--cc-sf-btn-add-border: 1px dashed #CBD5E1;--cc-sf-btn-add-radius: 6px;--cc-sf-btn-add-hover-bg: #EFF6FF;--cc-sf-btn-add-hover-border: #BFDBFE;--cc-sf-btn-remove-bg: #FFF5F5;--cc-sf-btn-remove-color: #E53E3E;--cc-sf-btn-remove-border: 1px solid #FED7D7;--cc-sf-btn-remove-radius: 4px;--cc-sf-btn-remove-hover-bg: #FED7D7;--cc-sf-step-connector-color: #E5E7EB;--cc-sf-step-connector-done: #22C55E;--cc-sf-step-number-bg: #E5E7EB;--cc-sf-step-number-color: #6B7280;--cc-sf-step-number-size: 40px;--cc-sf-step-number-font-size: .875rem;--cc-sf-step-number-weight: 600;--cc-sf-step-label-size: .875rem;--cc-sf-step-label-color: #6B7280;--cc-sf-step-label-weight: 500;--cc-sf-step-active-bg: #3B82F6;--cc-sf-step-active-color: #ffffff;--cc-sf-step-active-label: #1D4ED8;--cc-sf-step-active-label-weight: 700;--cc-sf-step-done-bg: #22C55E;--cc-sf-step-done-color: #ffffff;--cc-sf-actions-border: 1px solid #E5E7EB;--cc-sf-actions-padding: 20px 0 0;--cc-sf-actions-gap: 12px;--cc-sf-btn-primary-bg: #3B82F6;--cc-sf-btn-primary-color: #ffffff;--cc-sf-btn-primary-radius: 8px;--cc-sf-btn-primary-padding: .625rem 1.5rem;--cc-sf-btn-primary-hover-bg: #2563EB;--cc-sf-btn-secondary-bg: #F3F4F6;--cc-sf-btn-secondary-color: #374151;--cc-sf-btn-secondary-radius: 8px;--cc-sf-btn-secondary-padding: .625rem 1.5rem;--cc-sf-btn-secondary-hover-bg: #E5E7EB;--cc-sf-btn-font-size: .875rem;--cc-sf-btn-font-weight: 600;--cc-sf-btn-transition: all .2s ease;--cc-sf-btn-disabled-opacity: .55}.fb-config-panel__error{padding:24px;background:var(--fb-fc-error-bg, #fef2f2);color:var(--fb-fc-error-color, #dc2626);border:1px solid var(--fb-fc-error-border, #fee2e2);border-radius:8px;font-size:14px;font-weight:500}\n"], dependencies: [{ kind: "component", type: SmartFormComponent, selector: "lib-smart-form", inputs: ["formJson", "initialValues", "enableDraftAutoSave", "labels", "mode"], outputs: ["submit", "draftSave", "actionClick", "valueChange", "fileAdded", "fileUploadFinished", "fileRemoved"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6894
6948
|
}
|
|
6895
6949
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfiguratorConfigPanelComponent, decorators: [{
|
|
6896
6950
|
type: Component,
|
|
@@ -7005,6 +7059,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
7005
7059
|
class ConfirmationModalComponent {
|
|
7006
7060
|
config;
|
|
7007
7061
|
isOpen = false;
|
|
7062
|
+
confirmDisabled = false;
|
|
7063
|
+
confirmLoading = false;
|
|
7008
7064
|
confirm = new EventEmitter();
|
|
7009
7065
|
cancel = new EventEmitter();
|
|
7010
7066
|
close = new EventEmitter();
|
|
@@ -7024,6 +7080,7 @@ class ConfirmationModalComponent {
|
|
|
7024
7080
|
};
|
|
7025
7081
|
mergedConfig;
|
|
7026
7082
|
previousActiveElement = null;
|
|
7083
|
+
isSubmitting = false;
|
|
7027
7084
|
ngOnInit() {
|
|
7028
7085
|
this.updateConfig();
|
|
7029
7086
|
// Store currently focused element
|
|
@@ -7037,9 +7094,20 @@ class ConfirmationModalComponent {
|
|
|
7037
7094
|
this.updateConfig();
|
|
7038
7095
|
if (this.isOpen !== undefined) {
|
|
7039
7096
|
this.toggleBodyScroll(this.isOpen);
|
|
7097
|
+
if (!this.isOpen) {
|
|
7098
|
+
this.isSubmitting = false; // Reset submission guard when modal closes
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
7101
|
+
// Reset submission guard when loading state finishes
|
|
7102
|
+
if (this.isSubmitting && !this.confirmLoading && !this.mergedConfig.confirmButton.loading) {
|
|
7103
|
+
this.isSubmitting = false;
|
|
7040
7104
|
}
|
|
7041
7105
|
}
|
|
7042
7106
|
updateConfig() {
|
|
7107
|
+
if (!this.config) {
|
|
7108
|
+
this.mergedConfig = { ...this.defaultConfig };
|
|
7109
|
+
return;
|
|
7110
|
+
}
|
|
7043
7111
|
// Merge user config with defaults
|
|
7044
7112
|
this.mergedConfig = {
|
|
7045
7113
|
...this.defaultConfig,
|
|
@@ -7052,6 +7120,9 @@ class ConfirmationModalComponent {
|
|
|
7052
7120
|
...this.config.confirmButton
|
|
7053
7121
|
}
|
|
7054
7122
|
};
|
|
7123
|
+
if (this.mergedConfig.confirmButton) {
|
|
7124
|
+
// Logic handled by input/flag
|
|
7125
|
+
}
|
|
7055
7126
|
}
|
|
7056
7127
|
ngOnDestroy() {
|
|
7057
7128
|
// Restore body scroll
|
|
@@ -7083,8 +7154,10 @@ class ConfirmationModalComponent {
|
|
|
7083
7154
|
}
|
|
7084
7155
|
}
|
|
7085
7156
|
onConfirm() {
|
|
7086
|
-
|
|
7087
|
-
|
|
7157
|
+
const isDisabled = this.confirmDisabled || this.mergedConfig.confirmButton.disabled;
|
|
7158
|
+
const isLoading = this.confirmLoading || this.mergedConfig.confirmButton.loading;
|
|
7159
|
+
if (!isDisabled && !isLoading && !this.isSubmitting) {
|
|
7160
|
+
this.isSubmitting = true;
|
|
7088
7161
|
this.confirm.emit();
|
|
7089
7162
|
}
|
|
7090
7163
|
}
|
|
@@ -7114,7 +7187,8 @@ class ConfirmationModalComponent {
|
|
|
7114
7187
|
danger: 'cc-btn-danger',
|
|
7115
7188
|
warning: 'cc-btn-warning'
|
|
7116
7189
|
};
|
|
7117
|
-
|
|
7190
|
+
const isLoading = this.confirmLoading || this.mergedConfig.confirmButton.loading;
|
|
7191
|
+
return `cc-btn ${typeMap[this.mergedConfig.confirmButton.type]} ${isLoading ? 'cc-btn-loading' : ''}`;
|
|
7118
7192
|
}
|
|
7119
7193
|
getHeaderClass() {
|
|
7120
7194
|
return `modal-header modal-header--${this.mergedConfig.headerTheme}`;
|
|
@@ -7141,15 +7215,19 @@ class ConfirmationModalComponent {
|
|
|
7141
7215
|
return typeof icon === 'object' ? icon.color : undefined;
|
|
7142
7216
|
}
|
|
7143
7217
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfirmationModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7144
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ConfirmationModalComponent, isStandalone: false, selector: "cc-confirmation-modal", inputs: { config: "config", isOpen: "isOpen" }, outputs: { confirm: "confirm", cancel: "cancel", close: "close", showCodeSnippet: "showCodeSnippet" }, host: { listeners: { "document:keydown.escape": "handleEscape($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"isOpen\" class=\"cc-modal-backdrop\" (click)=\"onBackdropClick($event)\" role=\"dialog\" [attr.aria-modal]=\"true\"\r\n [attr.aria-labelledby]=\"'modal-title-' + mergedConfig.title\" [attr.aria-label]=\"mergedConfig.ariaLabel\"\r\n [attr.aria-describedby]=\"mergedConfig.ariaDescribedBy\">\r\n\r\n <div class=\"cc-modal-container {{ mergedConfig.customClass }}\" [style.width]=\"getModalWidth()\"\r\n [style.background-color]=\"mergedConfig.backgroundColor\" [style.border-radius]=\"mergedConfig.borderRadius\"\r\n [style.border-top-left-radius]=\"mergedConfig.borderTopLeftRadius\"\r\n [style.border-top-right-radius]=\"mergedConfig.borderTopRightRadius\"\r\n [style.border-bottom-left-radius]=\"mergedConfig.borderBottomLeftRadius\"\r\n [style.border-bottom-right-radius]=\"mergedConfig.borderBottomRightRadius\" (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- Header -->\r\n <div [ngClass]=\"getHeaderClass()\" [style.background-color]=\"mergedConfig.headerBackgroundColor\"\r\n [style.border-bottom]=\"mergedConfig.headerBorderBottom\">\r\n <div class=\"modal-header__content\">\r\n <!-- Icon (Optional) -->\r\n <span *ngIf=\"mergedConfig.icon\" class=\"modal-header__icon\">\r\n <ng-container [ngSwitch]=\"resolveIconType(mergedConfig.icon)\">\r\n <mat-icon *ngSwitchCase=\"'material'\" [style.color]=\"getIconColor(mergedConfig.icon)\">\r\n {{ getIconValue(mergedConfig.icon) }}\r\n </mat-icon>\r\n <img *ngSwitchCase=\"'custom'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n <img *ngSwitchCase=\"'img'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n </ng-container>\r\n </span>\r\n\r\n <!-- Title -->\r\n <h2 class=\"modal-header__title\" [id]=\"'modal-title-' + mergedConfig.title\"\r\n [style.color]=\"mergedConfig.headerTextColor\">\r\n {{ mergedConfig.title }}\r\n </h2>\r\n </div>\r\n\r\n <!-- Code Snippet Button -->\r\n <button *ngIf=\"mergedConfig.showCodeSnippetButton\" type=\"button\" class=\"modal-header__code-btn\"\r\n (click)=\"onShowCodeSnippet()\" [attr.aria-label]=\"mergedConfig.labels?.codeSnippetAriaLabel\"\r\n [attr.title]=\"mergedConfig.labels?.codeSnippetTitle\">\r\n <mat-icon>code</mat-icon>\r\n </button>\r\n\r\n <!-- Close Button -->\r\n <button *ngIf=\"mergedConfig.showCloseButton\" type=\"button\" class=\"modal-header__close\" (click)=\"onClose()\"\r\n [attr.aria-label]=\"mergedConfig.labels?.closeAriaLabel\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Body (Content Projection) -->\r\n <div class=\"cc-modal-body\" [style.padding]=\"mergedConfig.padding\" [style.color]=\"mergedConfig.bodyTextColor\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"cc-modal-footer\" [style.background-color]=\"mergedConfig.footerBackgroundColor\"\r\n [style.border-top]=\"mergedConfig.footerBorderTop\">\r\n\r\n <ng-container *ngIf=\"!mergedConfig.customFooter\">\r\n <button *ngIf=\"mergedConfig.cancelButton?.show\" type=\"button\" class=\"cc-btn cc-btn-secondary\"\r\n (click)=\"onCancel()\">\r\n {{ mergedConfig.cancelButton?.label }}\r\n </button>\r\n\r\n <button type=\"button\" [ngClass]=\"getConfirmButtonClass()\"\r\n [disabled]=\"mergedConfig.confirmButton.disabled || mergedConfig.confirmButton.loading\"\r\n (click)=\"onConfirm()\">\r\n <span *ngIf=\"mergedConfig.confirmButton.loading\" class=\"cc-btn-spinner\"></span>\r\n {{ mergedConfig.confirmButton.label }}\r\n </button>\r\n </ng-container>\r\n\r\n <ng-content select=\"[cc-modal-footer]\"></ng-content>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000;animation:fadeIn .2s ease-in-out}.cc-modal-container{background:var(--cc-modal-bg);border-radius:var(--cc-modal-radius);box-shadow:var(--cc-modal-shadow);border:var(--cc-modal-border, none);display:flex;flex-direction:column;max-height:90vh;max-width:90vw;animation:slideIn .3s ease-out;overflow:hidden}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:var(--cc-modal-header-padding);border-bottom:var(--cc-modal-header-border-bottom)}.modal-header__content{display:flex;align-items:center;gap:.75rem;flex:1}.modal-header__icon{display:flex;align-items:center;justify-content:center}.modal-header__icon mat-icon{font-size:var(--cc-modal-icon-size, 1.5rem);width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem)}.modal-header__custom-icon{width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem);object-fit:contain}.modal-header__title{margin:0;font-size:var(--cc-modal-title-size);font-weight:var(--cc-modal-title-weight);line-height:1.4;color:var(--cc-modal-title-color)}.modal-header__close{background:none;border:none;padding:.25rem;cursor:pointer;color:#6b7280;transition:color .2s;display:flex;align-items:center}.modal-header__close:hover{color:#111827}.modal-header__close mat-icon{font-size:var(--cc-modal-close-icon-size, 1.25rem);width:var(--cc-modal-close-icon-size, 1.25rem);height:var(--cc-modal-close-icon-size, 1.25rem)}.modal-header__code-btn{background:none;border:none;padding:.25rem;margin-right:.5rem;cursor:pointer;color:#6b7280;transition:all .2s;display:flex;align-items:center}.modal-header__code-btn:hover{color:#ef4444;transform:scale(1.1)}.modal-header__code-btn mat-icon{font-size:1.15rem;width:1.15rem;height:1.15rem}.modal-header--dark{background-color:var(--cc-modal-header-bg-dark);border-bottom:none}.modal-header--dark .modal-header__title{color:var(--cc-modal-header-title-color-dark)}.modal-header--dark .modal-header__close{color:#ffffffb3}.modal-header--dark .modal-header__close:hover{color:#fff}.modal-header--dark .modal-header__code-btn{color:#ffffffb3}.modal-header--dark .modal-header__code-btn:hover{color:#fff}.cc-modal-body{padding:var(--cc-modal-body-padding);overflow-y:auto;flex:1;color:var(--cc-modal-body-color);font-size:.875rem;line-height:1.6}.cc-modal-body ::ng-deep input[type=text],.cc-modal-body ::ng-deep textarea,.cc-modal-body ::ng-deep select{width:100%;padding:var(--cc-modal-input-padding, .625rem .75rem);border:.0625rem solid #D1D5DB;border-radius:var(--cc-modal-input-radius, .375rem);font-size:var(--cc-modal-input-font-size, .875rem);transition:border-color .2s}.cc-modal-body ::ng-deep input[type=text]:focus,.cc-modal-body ::ng-deep textarea:focus,.cc-modal-body ::ng-deep select:focus{outline:none;border-color:var(--cc-btn-primary-bg, #3b82f6);box-shadow:0 0 0 .1875rem #3b82f61a}.cc-modal-body ::ng-deep textarea{resize:vertical;min-height:var(--cc-modal-textarea-min-height, 6.25rem)}.cc-modal-body ::ng-deep label{display:block;margin-bottom:var(--cc-modal-label-margin-bottom, .5rem);font-weight:500;color:var(--cc-modal-body-color)}.cc-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;padding:var(--cc-modal-footer-padding);border-top:var(--cc-modal-footer-border-top);background:var(--cc-modal-footer-bg)}.cc-btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:var(--cc-btn-padding, .5rem 1rem);font-family:var(--cc-btn-font-family, inherit);font-weight:var(--cc-btn-font-weight, 500);font-size:var(--cc-btn-font-size, .875rem);cursor:pointer;transition:all .2s;min-width:5rem}.cc-btn:disabled{opacity:var(--cc-btn-disabled-opacity, .6);cursor:var(--cc-btn-disabled-cursor, not-allowed)}.cc-btn-secondary{background:var(--cc-btn-secondary-bg);color:var(--cc-btn-secondary-color);border:var(--cc-btn-secondary-border);border-radius:var(--cc-btn-secondary-radius)}.cc-btn-primary{background:var(--cc-btn-primary-bg);color:var(--cc-btn-primary-color);border:var(--cc-btn-primary-border);border-radius:var(--cc-btn-primary-radius)}.cc-btn-danger{background:var(--cc-btn-danger-bg);color:var(--cc-btn-danger-color);border:var(--cc-btn-danger-border);border-radius:var(--cc-btn-danger-radius)}.cc-btn-warning{background:var(--cc-btn-warning-bg);color:var(--cc-btn-warning-color);border:var(--cc-btn-warning-border);border-radius:var(--cc-btn-warning-radius)}.cc-btn-spinner{width:var(--cc-modal-spinner-size, 1rem);height:var(--cc-modal-spinner-size, 1rem);border:.125rem solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{transform:translateY(-1.25rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:40rem){.cc-modal-container{width:95vw!important;max-height:95vh}.modal-header,.cc-modal-body{padding:1rem}.cc-modal-footer{padding:.75rem 1rem;flex-direction:column}.cc-modal-footer .cc-btn{width:100%}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
7218
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ConfirmationModalComponent, isStandalone: false, selector: "cc-confirmation-modal", inputs: { config: "config", isOpen: "isOpen", confirmDisabled: "confirmDisabled", confirmLoading: "confirmLoading" }, outputs: { confirm: "confirm", cancel: "cancel", close: "close", showCodeSnippet: "showCodeSnippet" }, host: { listeners: { "document:keydown.escape": "handleEscape($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"isOpen\" class=\"cc-modal-backdrop\" (click)=\"onBackdropClick($event)\" role=\"dialog\" [attr.aria-modal]=\"true\"\r\n [attr.aria-labelledby]=\"'modal-title-' + mergedConfig.title\" [attr.aria-label]=\"mergedConfig.ariaLabel\"\r\n [attr.aria-describedby]=\"mergedConfig.ariaDescribedBy\">\r\n\r\n <div class=\"cc-modal-container {{ mergedConfig.customClass }}\" [style.width]=\"getModalWidth()\"\r\n [style.background-color]=\"mergedConfig.backgroundColor\" [style.border-radius]=\"mergedConfig.borderRadius\"\r\n [style.border-top-left-radius]=\"mergedConfig.borderTopLeftRadius\"\r\n [style.border-top-right-radius]=\"mergedConfig.borderTopRightRadius\"\r\n [style.border-bottom-left-radius]=\"mergedConfig.borderBottomLeftRadius\"\r\n [style.border-bottom-right-radius]=\"mergedConfig.borderBottomRightRadius\" (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- Header -->\r\n <div [ngClass]=\"getHeaderClass()\" [style.background-color]=\"mergedConfig.headerBackgroundColor\"\r\n [style.border-bottom]=\"mergedConfig.headerBorderBottom\">\r\n <div class=\"modal-header__content\">\r\n <!-- Icon (Optional) -->\r\n <span *ngIf=\"mergedConfig.icon\" class=\"modal-header__icon\">\r\n <ng-container [ngSwitch]=\"resolveIconType(mergedConfig.icon)\">\r\n <mat-icon *ngSwitchCase=\"'material'\" [style.color]=\"getIconColor(mergedConfig.icon)\">\r\n {{ getIconValue(mergedConfig.icon) }}\r\n </mat-icon>\r\n <img *ngSwitchCase=\"'custom'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n <img *ngSwitchCase=\"'img'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n </ng-container>\r\n </span>\r\n\r\n <!-- Title -->\r\n <h2 class=\"modal-header__title\" [id]=\"'modal-title-' + mergedConfig.title\"\r\n [style.color]=\"mergedConfig.headerTextColor\">\r\n {{ mergedConfig.title }}\r\n </h2>\r\n </div>\r\n\r\n <!-- Code Snippet Button -->\r\n <button *ngIf=\"mergedConfig.showCodeSnippetButton\" type=\"button\" class=\"modal-header__code-btn\"\r\n (click)=\"onShowCodeSnippet()\" [attr.aria-label]=\"mergedConfig.labels?.codeSnippetAriaLabel\"\r\n [attr.title]=\"mergedConfig.labels?.codeSnippetTitle\">\r\n <mat-icon>code</mat-icon>\r\n </button>\r\n\r\n <!-- Close Button -->\r\n <button *ngIf=\"mergedConfig.showCloseButton\" type=\"button\" class=\"modal-header__close\" (click)=\"onClose()\"\r\n [attr.aria-label]=\"mergedConfig.labels?.closeAriaLabel\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Body (Content Projection) -->\r\n <div class=\"cc-modal-body\" [style.padding]=\"mergedConfig.padding\" [style.color]=\"mergedConfig.bodyTextColor\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"cc-modal-footer\" [style.background-color]=\"mergedConfig.footerBackgroundColor\"\r\n [style.border-top]=\"mergedConfig.footerBorderTop\">\r\n\r\n <ng-container *ngIf=\"!mergedConfig.customFooter\">\r\n <button *ngIf=\"mergedConfig.cancelButton?.show\" type=\"button\" class=\"cc-btn cc-btn-secondary\"\r\n (click)=\"onCancel()\">\r\n {{ mergedConfig.cancelButton?.label }}\r\n </button>\r\n\r\n <button type=\"button\" [ngClass]=\"getConfirmButtonClass()\"\r\n [disabled]=\"confirmDisabled || mergedConfig.confirmButton.disabled || confirmLoading || mergedConfig.confirmButton.loading\"\r\n (click)=\"onConfirm()\">\r\n <span *ngIf=\"confirmLoading || mergedConfig.confirmButton.loading\" class=\"cc-btn-spinner\"></span>\r\n {{ mergedConfig.confirmButton.label }}\r\n </button>\r\n </ng-container>\r\n\r\n <ng-content select=\"[cc-modal-footer]\"></ng-content>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000;animation:fadeIn .2s ease-in-out}.cc-modal-container{background:var(--cc-modal-bg);border-radius:var(--cc-modal-radius);box-shadow:var(--cc-modal-shadow);border:var(--cc-modal-border, none);display:flex;flex-direction:column;max-height:90vh;max-width:90vw;animation:slideIn .3s ease-out;overflow:hidden}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:var(--cc-modal-header-padding);border-bottom:var(--cc-modal-header-border-bottom)}.modal-header__content{display:flex;align-items:center;gap:.75rem;flex:1}.modal-header__icon{display:flex;align-items:center;justify-content:center}.modal-header__icon mat-icon{font-size:var(--cc-modal-icon-size, 1.5rem);width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem)}.modal-header__custom-icon{width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem);object-fit:contain}.modal-header__title{margin:0;font-size:var(--cc-modal-title-size);font-weight:var(--cc-modal-title-weight);line-height:1.4;color:var(--cc-modal-title-color)}.modal-header__close{background:none;border:none;padding:.25rem;cursor:pointer;color:#6b7280;transition:color .2s;display:flex;align-items:center}.modal-header__close:hover{color:#111827}.modal-header__close mat-icon{font-size:var(--cc-modal-close-icon-size, 1.25rem);width:var(--cc-modal-close-icon-size, 1.25rem);height:var(--cc-modal-close-icon-size, 1.25rem)}.modal-header__code-btn{background:none;border:none;padding:.25rem;margin-right:.5rem;cursor:pointer;color:#6b7280;transition:all .2s;display:flex;align-items:center}.modal-header__code-btn:hover{color:#ef4444;transform:scale(1.1)}.modal-header__code-btn mat-icon{font-size:1.15rem;width:1.15rem;height:1.15rem}.modal-header--dark{background-color:var(--cc-modal-header-bg-dark);border-bottom:none}.modal-header--dark .modal-header__title{color:var(--cc-modal-header-title-color-dark)}.modal-header--dark .modal-header__close{color:#ffffffb3}.modal-header--dark .modal-header__close:hover{color:#fff}.modal-header--dark .modal-header__code-btn{color:#ffffffb3}.modal-header--dark .modal-header__code-btn:hover{color:#fff}.cc-modal-body{padding:var(--cc-modal-body-padding);overflow-y:auto;flex:1;color:var(--cc-modal-body-color);font-size:.875rem;line-height:1.6}.cc-modal-body ::ng-deep input[type=text],.cc-modal-body ::ng-deep textarea,.cc-modal-body ::ng-deep select{width:100%;padding:var(--cc-modal-input-padding, .625rem .75rem);border:.0625rem solid #D1D5DB;border-radius:var(--cc-modal-input-radius, .375rem);font-size:var(--cc-modal-input-font-size, .875rem);transition:border-color .2s}.cc-modal-body ::ng-deep input[type=text]:focus,.cc-modal-body ::ng-deep textarea:focus,.cc-modal-body ::ng-deep select:focus{outline:none;border-color:var(--cc-btn-primary-bg, #3b82f6);box-shadow:0 0 0 .1875rem #3b82f61a}.cc-modal-body ::ng-deep textarea{resize:vertical;min-height:var(--cc-modal-textarea-min-height, 6.25rem)}.cc-modal-body ::ng-deep label{display:block;margin-bottom:var(--cc-modal-label-margin-bottom, .5rem);font-weight:500;color:var(--cc-modal-body-color)}.cc-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;padding:var(--cc-modal-footer-padding);border-top:var(--cc-modal-footer-border-top);background:var(--cc-modal-footer-bg)}.cc-btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:var(--cc-btn-padding, .5rem 1rem);font-family:var(--cc-btn-font-family, inherit);font-weight:var(--cc-btn-font-weight, 500);font-size:var(--cc-btn-font-size, .875rem);cursor:pointer;transition:all .2s;min-width:5rem}.cc-btn:disabled{opacity:var(--cc-btn-disabled-opacity, .6);cursor:var(--cc-btn-disabled-cursor, not-allowed)}.cc-btn-secondary{background:var(--cc-btn-secondary-bg);color:var(--cc-btn-secondary-color);border:var(--cc-btn-secondary-border);border-radius:var(--cc-btn-secondary-radius)}.cc-btn-primary{background:var(--cc-btn-primary-bg);color:var(--cc-btn-primary-color);border:var(--cc-btn-primary-border);border-radius:var(--cc-btn-primary-radius)}.cc-btn-danger{background:var(--cc-btn-danger-bg);color:var(--cc-btn-danger-color);border:var(--cc-btn-danger-border);border-radius:var(--cc-btn-danger-radius)}.cc-btn-warning{background:var(--cc-btn-warning-bg);color:var(--cc-btn-warning-color);border:var(--cc-btn-warning-border);border-radius:var(--cc-btn-warning-radius)}.cc-btn-spinner{width:var(--cc-modal-spinner-size, 1rem);height:var(--cc-modal-spinner-size, 1rem);border:.125rem solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{transform:translateY(-1.25rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:40rem){.cc-modal-container{width:95vw!important;max-height:95vh}.modal-header,.cc-modal-body{padding:1rem}.cc-modal-footer{padding:.75rem 1rem;flex-direction:column}.cc-modal-footer .cc-btn{width:100%}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
7145
7219
|
}
|
|
7146
7220
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfirmationModalComponent, decorators: [{
|
|
7147
7221
|
type: Component,
|
|
7148
|
-
args: [{ selector: 'cc-confirmation-modal', standalone: false, template: "<div *ngIf=\"isOpen\" class=\"cc-modal-backdrop\" (click)=\"onBackdropClick($event)\" role=\"dialog\" [attr.aria-modal]=\"true\"\r\n [attr.aria-labelledby]=\"'modal-title-' + mergedConfig.title\" [attr.aria-label]=\"mergedConfig.ariaLabel\"\r\n [attr.aria-describedby]=\"mergedConfig.ariaDescribedBy\">\r\n\r\n <div class=\"cc-modal-container {{ mergedConfig.customClass }}\" [style.width]=\"getModalWidth()\"\r\n [style.background-color]=\"mergedConfig.backgroundColor\" [style.border-radius]=\"mergedConfig.borderRadius\"\r\n [style.border-top-left-radius]=\"mergedConfig.borderTopLeftRadius\"\r\n [style.border-top-right-radius]=\"mergedConfig.borderTopRightRadius\"\r\n [style.border-bottom-left-radius]=\"mergedConfig.borderBottomLeftRadius\"\r\n [style.border-bottom-right-radius]=\"mergedConfig.borderBottomRightRadius\" (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- Header -->\r\n <div [ngClass]=\"getHeaderClass()\" [style.background-color]=\"mergedConfig.headerBackgroundColor\"\r\n [style.border-bottom]=\"mergedConfig.headerBorderBottom\">\r\n <div class=\"modal-header__content\">\r\n <!-- Icon (Optional) -->\r\n <span *ngIf=\"mergedConfig.icon\" class=\"modal-header__icon\">\r\n <ng-container [ngSwitch]=\"resolveIconType(mergedConfig.icon)\">\r\n <mat-icon *ngSwitchCase=\"'material'\" [style.color]=\"getIconColor(mergedConfig.icon)\">\r\n {{ getIconValue(mergedConfig.icon) }}\r\n </mat-icon>\r\n <img *ngSwitchCase=\"'custom'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n <img *ngSwitchCase=\"'img'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n </ng-container>\r\n </span>\r\n\r\n <!-- Title -->\r\n <h2 class=\"modal-header__title\" [id]=\"'modal-title-' + mergedConfig.title\"\r\n [style.color]=\"mergedConfig.headerTextColor\">\r\n {{ mergedConfig.title }}\r\n </h2>\r\n </div>\r\n\r\n <!-- Code Snippet Button -->\r\n <button *ngIf=\"mergedConfig.showCodeSnippetButton\" type=\"button\" class=\"modal-header__code-btn\"\r\n (click)=\"onShowCodeSnippet()\" [attr.aria-label]=\"mergedConfig.labels?.codeSnippetAriaLabel\"\r\n [attr.title]=\"mergedConfig.labels?.codeSnippetTitle\">\r\n <mat-icon>code</mat-icon>\r\n </button>\r\n\r\n <!-- Close Button -->\r\n <button *ngIf=\"mergedConfig.showCloseButton\" type=\"button\" class=\"modal-header__close\" (click)=\"onClose()\"\r\n [attr.aria-label]=\"mergedConfig.labels?.closeAriaLabel\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Body (Content Projection) -->\r\n <div class=\"cc-modal-body\" [style.padding]=\"mergedConfig.padding\" [style.color]=\"mergedConfig.bodyTextColor\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"cc-modal-footer\" [style.background-color]=\"mergedConfig.footerBackgroundColor\"\r\n [style.border-top]=\"mergedConfig.footerBorderTop\">\r\n\r\n <ng-container *ngIf=\"!mergedConfig.customFooter\">\r\n <button *ngIf=\"mergedConfig.cancelButton?.show\" type=\"button\" class=\"cc-btn cc-btn-secondary\"\r\n (click)=\"onCancel()\">\r\n {{ mergedConfig.cancelButton?.label }}\r\n </button>\r\n\r\n <button type=\"button\" [ngClass]=\"getConfirmButtonClass()\"\r\n [disabled]=\"mergedConfig.confirmButton.disabled || mergedConfig.confirmButton.loading\"\r\n (click)=\"onConfirm()\">\r\n <span *ngIf=\"mergedConfig.confirmButton.loading\" class=\"cc-btn-spinner\"></span>\r\n {{ mergedConfig.confirmButton.label }}\r\n </button>\r\n </ng-container>\r\n\r\n <ng-content select=\"[cc-modal-footer]\"></ng-content>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000;animation:fadeIn .2s ease-in-out}.cc-modal-container{background:var(--cc-modal-bg);border-radius:var(--cc-modal-radius);box-shadow:var(--cc-modal-shadow);border:var(--cc-modal-border, none);display:flex;flex-direction:column;max-height:90vh;max-width:90vw;animation:slideIn .3s ease-out;overflow:hidden}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:var(--cc-modal-header-padding);border-bottom:var(--cc-modal-header-border-bottom)}.modal-header__content{display:flex;align-items:center;gap:.75rem;flex:1}.modal-header__icon{display:flex;align-items:center;justify-content:center}.modal-header__icon mat-icon{font-size:var(--cc-modal-icon-size, 1.5rem);width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem)}.modal-header__custom-icon{width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem);object-fit:contain}.modal-header__title{margin:0;font-size:var(--cc-modal-title-size);font-weight:var(--cc-modal-title-weight);line-height:1.4;color:var(--cc-modal-title-color)}.modal-header__close{background:none;border:none;padding:.25rem;cursor:pointer;color:#6b7280;transition:color .2s;display:flex;align-items:center}.modal-header__close:hover{color:#111827}.modal-header__close mat-icon{font-size:var(--cc-modal-close-icon-size, 1.25rem);width:var(--cc-modal-close-icon-size, 1.25rem);height:var(--cc-modal-close-icon-size, 1.25rem)}.modal-header__code-btn{background:none;border:none;padding:.25rem;margin-right:.5rem;cursor:pointer;color:#6b7280;transition:all .2s;display:flex;align-items:center}.modal-header__code-btn:hover{color:#ef4444;transform:scale(1.1)}.modal-header__code-btn mat-icon{font-size:1.15rem;width:1.15rem;height:1.15rem}.modal-header--dark{background-color:var(--cc-modal-header-bg-dark);border-bottom:none}.modal-header--dark .modal-header__title{color:var(--cc-modal-header-title-color-dark)}.modal-header--dark .modal-header__close{color:#ffffffb3}.modal-header--dark .modal-header__close:hover{color:#fff}.modal-header--dark .modal-header__code-btn{color:#ffffffb3}.modal-header--dark .modal-header__code-btn:hover{color:#fff}.cc-modal-body{padding:var(--cc-modal-body-padding);overflow-y:auto;flex:1;color:var(--cc-modal-body-color);font-size:.875rem;line-height:1.6}.cc-modal-body ::ng-deep input[type=text],.cc-modal-body ::ng-deep textarea,.cc-modal-body ::ng-deep select{width:100%;padding:var(--cc-modal-input-padding, .625rem .75rem);border:.0625rem solid #D1D5DB;border-radius:var(--cc-modal-input-radius, .375rem);font-size:var(--cc-modal-input-font-size, .875rem);transition:border-color .2s}.cc-modal-body ::ng-deep input[type=text]:focus,.cc-modal-body ::ng-deep textarea:focus,.cc-modal-body ::ng-deep select:focus{outline:none;border-color:var(--cc-btn-primary-bg, #3b82f6);box-shadow:0 0 0 .1875rem #3b82f61a}.cc-modal-body ::ng-deep textarea{resize:vertical;min-height:var(--cc-modal-textarea-min-height, 6.25rem)}.cc-modal-body ::ng-deep label{display:block;margin-bottom:var(--cc-modal-label-margin-bottom, .5rem);font-weight:500;color:var(--cc-modal-body-color)}.cc-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;padding:var(--cc-modal-footer-padding);border-top:var(--cc-modal-footer-border-top);background:var(--cc-modal-footer-bg)}.cc-btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:var(--cc-btn-padding, .5rem 1rem);font-family:var(--cc-btn-font-family, inherit);font-weight:var(--cc-btn-font-weight, 500);font-size:var(--cc-btn-font-size, .875rem);cursor:pointer;transition:all .2s;min-width:5rem}.cc-btn:disabled{opacity:var(--cc-btn-disabled-opacity, .6);cursor:var(--cc-btn-disabled-cursor, not-allowed)}.cc-btn-secondary{background:var(--cc-btn-secondary-bg);color:var(--cc-btn-secondary-color);border:var(--cc-btn-secondary-border);border-radius:var(--cc-btn-secondary-radius)}.cc-btn-primary{background:var(--cc-btn-primary-bg);color:var(--cc-btn-primary-color);border:var(--cc-btn-primary-border);border-radius:var(--cc-btn-primary-radius)}.cc-btn-danger{background:var(--cc-btn-danger-bg);color:var(--cc-btn-danger-color);border:var(--cc-btn-danger-border);border-radius:var(--cc-btn-danger-radius)}.cc-btn-warning{background:var(--cc-btn-warning-bg);color:var(--cc-btn-warning-color);border:var(--cc-btn-warning-border);border-radius:var(--cc-btn-warning-radius)}.cc-btn-spinner{width:var(--cc-modal-spinner-size, 1rem);height:var(--cc-modal-spinner-size, 1rem);border:.125rem solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{transform:translateY(-1.25rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:40rem){.cc-modal-container{width:95vw!important;max-height:95vh}.modal-header,.cc-modal-body{padding:1rem}.cc-modal-footer{padding:.75rem 1rem;flex-direction:column}.cc-modal-footer .cc-btn{width:100%}}\n"] }]
|
|
7222
|
+
args: [{ selector: 'cc-confirmation-modal', standalone: false, template: "<div *ngIf=\"isOpen\" class=\"cc-modal-backdrop\" (click)=\"onBackdropClick($event)\" role=\"dialog\" [attr.aria-modal]=\"true\"\r\n [attr.aria-labelledby]=\"'modal-title-' + mergedConfig.title\" [attr.aria-label]=\"mergedConfig.ariaLabel\"\r\n [attr.aria-describedby]=\"mergedConfig.ariaDescribedBy\">\r\n\r\n <div class=\"cc-modal-container {{ mergedConfig.customClass }}\" [style.width]=\"getModalWidth()\"\r\n [style.background-color]=\"mergedConfig.backgroundColor\" [style.border-radius]=\"mergedConfig.borderRadius\"\r\n [style.border-top-left-radius]=\"mergedConfig.borderTopLeftRadius\"\r\n [style.border-top-right-radius]=\"mergedConfig.borderTopRightRadius\"\r\n [style.border-bottom-left-radius]=\"mergedConfig.borderBottomLeftRadius\"\r\n [style.border-bottom-right-radius]=\"mergedConfig.borderBottomRightRadius\" (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- Header -->\r\n <div [ngClass]=\"getHeaderClass()\" [style.background-color]=\"mergedConfig.headerBackgroundColor\"\r\n [style.border-bottom]=\"mergedConfig.headerBorderBottom\">\r\n <div class=\"modal-header__content\">\r\n <!-- Icon (Optional) -->\r\n <span *ngIf=\"mergedConfig.icon\" class=\"modal-header__icon\">\r\n <ng-container [ngSwitch]=\"resolveIconType(mergedConfig.icon)\">\r\n <mat-icon *ngSwitchCase=\"'material'\" [style.color]=\"getIconColor(mergedConfig.icon)\">\r\n {{ getIconValue(mergedConfig.icon) }}\r\n </mat-icon>\r\n <img *ngSwitchCase=\"'custom'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n <img *ngSwitchCase=\"'img'\" [src]=\"getIconValue(mergedConfig.icon)\"\r\n [attr.alt]=\"mergedConfig.labels?.iconAltText || mergedConfig.title + ' icon'\"\r\n class=\"modal-header__custom-icon\">\r\n </ng-container>\r\n </span>\r\n\r\n <!-- Title -->\r\n <h2 class=\"modal-header__title\" [id]=\"'modal-title-' + mergedConfig.title\"\r\n [style.color]=\"mergedConfig.headerTextColor\">\r\n {{ mergedConfig.title }}\r\n </h2>\r\n </div>\r\n\r\n <!-- Code Snippet Button -->\r\n <button *ngIf=\"mergedConfig.showCodeSnippetButton\" type=\"button\" class=\"modal-header__code-btn\"\r\n (click)=\"onShowCodeSnippet()\" [attr.aria-label]=\"mergedConfig.labels?.codeSnippetAriaLabel\"\r\n [attr.title]=\"mergedConfig.labels?.codeSnippetTitle\">\r\n <mat-icon>code</mat-icon>\r\n </button>\r\n\r\n <!-- Close Button -->\r\n <button *ngIf=\"mergedConfig.showCloseButton\" type=\"button\" class=\"modal-header__close\" (click)=\"onClose()\"\r\n [attr.aria-label]=\"mergedConfig.labels?.closeAriaLabel\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Body (Content Projection) -->\r\n <div class=\"cc-modal-body\" [style.padding]=\"mergedConfig.padding\" [style.color]=\"mergedConfig.bodyTextColor\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"cc-modal-footer\" [style.background-color]=\"mergedConfig.footerBackgroundColor\"\r\n [style.border-top]=\"mergedConfig.footerBorderTop\">\r\n\r\n <ng-container *ngIf=\"!mergedConfig.customFooter\">\r\n <button *ngIf=\"mergedConfig.cancelButton?.show\" type=\"button\" class=\"cc-btn cc-btn-secondary\"\r\n (click)=\"onCancel()\">\r\n {{ mergedConfig.cancelButton?.label }}\r\n </button>\r\n\r\n <button type=\"button\" [ngClass]=\"getConfirmButtonClass()\"\r\n [disabled]=\"confirmDisabled || mergedConfig.confirmButton.disabled || confirmLoading || mergedConfig.confirmButton.loading\"\r\n (click)=\"onConfirm()\">\r\n <span *ngIf=\"confirmLoading || mergedConfig.confirmButton.loading\" class=\"cc-btn-spinner\"></span>\r\n {{ mergedConfig.confirmButton.label }}\r\n </button>\r\n </ng-container>\r\n\r\n <ng-content select=\"[cc-modal-footer]\"></ng-content>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000;animation:fadeIn .2s ease-in-out}.cc-modal-container{background:var(--cc-modal-bg);border-radius:var(--cc-modal-radius);box-shadow:var(--cc-modal-shadow);border:var(--cc-modal-border, none);display:flex;flex-direction:column;max-height:90vh;max-width:90vw;animation:slideIn .3s ease-out;overflow:hidden}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:var(--cc-modal-header-padding);border-bottom:var(--cc-modal-header-border-bottom)}.modal-header__content{display:flex;align-items:center;gap:.75rem;flex:1}.modal-header__icon{display:flex;align-items:center;justify-content:center}.modal-header__icon mat-icon{font-size:var(--cc-modal-icon-size, 1.5rem);width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem)}.modal-header__custom-icon{width:var(--cc-modal-icon-size, 1.5rem);height:var(--cc-modal-icon-size, 1.5rem);object-fit:contain}.modal-header__title{margin:0;font-size:var(--cc-modal-title-size);font-weight:var(--cc-modal-title-weight);line-height:1.4;color:var(--cc-modal-title-color)}.modal-header__close{background:none;border:none;padding:.25rem;cursor:pointer;color:#6b7280;transition:color .2s;display:flex;align-items:center}.modal-header__close:hover{color:#111827}.modal-header__close mat-icon{font-size:var(--cc-modal-close-icon-size, 1.25rem);width:var(--cc-modal-close-icon-size, 1.25rem);height:var(--cc-modal-close-icon-size, 1.25rem)}.modal-header__code-btn{background:none;border:none;padding:.25rem;margin-right:.5rem;cursor:pointer;color:#6b7280;transition:all .2s;display:flex;align-items:center}.modal-header__code-btn:hover{color:#ef4444;transform:scale(1.1)}.modal-header__code-btn mat-icon{font-size:1.15rem;width:1.15rem;height:1.15rem}.modal-header--dark{background-color:var(--cc-modal-header-bg-dark);border-bottom:none}.modal-header--dark .modal-header__title{color:var(--cc-modal-header-title-color-dark)}.modal-header--dark .modal-header__close{color:#ffffffb3}.modal-header--dark .modal-header__close:hover{color:#fff}.modal-header--dark .modal-header__code-btn{color:#ffffffb3}.modal-header--dark .modal-header__code-btn:hover{color:#fff}.cc-modal-body{padding:var(--cc-modal-body-padding);overflow-y:auto;flex:1;color:var(--cc-modal-body-color);font-size:.875rem;line-height:1.6}.cc-modal-body ::ng-deep input[type=text],.cc-modal-body ::ng-deep textarea,.cc-modal-body ::ng-deep select{width:100%;padding:var(--cc-modal-input-padding, .625rem .75rem);border:.0625rem solid #D1D5DB;border-radius:var(--cc-modal-input-radius, .375rem);font-size:var(--cc-modal-input-font-size, .875rem);transition:border-color .2s}.cc-modal-body ::ng-deep input[type=text]:focus,.cc-modal-body ::ng-deep textarea:focus,.cc-modal-body ::ng-deep select:focus{outline:none;border-color:var(--cc-btn-primary-bg, #3b82f6);box-shadow:0 0 0 .1875rem #3b82f61a}.cc-modal-body ::ng-deep textarea{resize:vertical;min-height:var(--cc-modal-textarea-min-height, 6.25rem)}.cc-modal-body ::ng-deep label{display:block;margin-bottom:var(--cc-modal-label-margin-bottom, .5rem);font-weight:500;color:var(--cc-modal-body-color)}.cc-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;padding:var(--cc-modal-footer-padding);border-top:var(--cc-modal-footer-border-top);background:var(--cc-modal-footer-bg)}.cc-btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:var(--cc-btn-padding, .5rem 1rem);font-family:var(--cc-btn-font-family, inherit);font-weight:var(--cc-btn-font-weight, 500);font-size:var(--cc-btn-font-size, .875rem);cursor:pointer;transition:all .2s;min-width:5rem}.cc-btn:disabled{opacity:var(--cc-btn-disabled-opacity, .6);cursor:var(--cc-btn-disabled-cursor, not-allowed)}.cc-btn-secondary{background:var(--cc-btn-secondary-bg);color:var(--cc-btn-secondary-color);border:var(--cc-btn-secondary-border);border-radius:var(--cc-btn-secondary-radius)}.cc-btn-primary{background:var(--cc-btn-primary-bg);color:var(--cc-btn-primary-color);border:var(--cc-btn-primary-border);border-radius:var(--cc-btn-primary-radius)}.cc-btn-danger{background:var(--cc-btn-danger-bg);color:var(--cc-btn-danger-color);border:var(--cc-btn-danger-border);border-radius:var(--cc-btn-danger-radius)}.cc-btn-warning{background:var(--cc-btn-warning-bg);color:var(--cc-btn-warning-color);border:var(--cc-btn-warning-border);border-radius:var(--cc-btn-warning-radius)}.cc-btn-spinner{width:var(--cc-modal-spinner-size, 1rem);height:var(--cc-modal-spinner-size, 1rem);border:.125rem solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{transform:translateY(-1.25rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:40rem){.cc-modal-container{width:95vw!important;max-height:95vh}.modal-header,.cc-modal-body{padding:1rem}.cc-modal-footer{padding:.75rem 1rem;flex-direction:column}.cc-modal-footer .cc-btn{width:100%}}\n"] }]
|
|
7149
7223
|
}], propDecorators: { config: [{
|
|
7150
7224
|
type: Input
|
|
7151
7225
|
}], isOpen: [{
|
|
7152
7226
|
type: Input
|
|
7227
|
+
}], confirmDisabled: [{
|
|
7228
|
+
type: Input
|
|
7229
|
+
}], confirmLoading: [{
|
|
7230
|
+
type: Input
|
|
7153
7231
|
}], confirm: [{
|
|
7154
7232
|
type: Output
|
|
7155
7233
|
}], cancel: [{
|
|
@@ -7295,7 +7373,7 @@ class ButtonDropdownComponent {
|
|
|
7295
7373
|
this.confirmMessage = '';
|
|
7296
7374
|
}
|
|
7297
7375
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonDropdownComponent, deps: [{ token: i0.ElementRef }, { token: i1$4.Router }, { token: i3.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
|
|
7298
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ButtonDropdownComponent, isStandalone: false, selector: "lib-button-dropdown", inputs: { label: "label", variant: "variant", menuTheme: "menuTheme", icon: "icon", actions: "actions", data: "data", disabled: "disabled" }, outputs: { apiActionStart: "apiActionStart", apiActionSuccess: "apiActionSuccess", apiActionError: "apiActionError", actionClick: "actionClick" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, ngImport: i0, template: "<div class=\"cc-btn-dropdown-container\">\r\n <!-- Main Toggle Button -->\r\n <lib-button \r\n [variant]=\"variant\" \r\n [disabled]=\"disabled\"\r\n (click)=\"toggleDropdown($event)\">\r\n <span class=\"cc-btn-dropdown-content\">\r\n {{ label }}\r\n <i *ngIf=\"icon\" [class]=\"icon\" class=\"cc-btn-dropdown-icon\"></i>\r\n </span>\r\n </lib-button>\r\n\r\n <!-- Dropdown Menu -->\r\n <div class=\"cc-dropdown-menu\" [ngClass]=\"'cc-dropdown-menu--' + menuTheme\" *ngIf=\"isOpen\">\r\n <button \r\n type=\"button\" \r\n class=\"cc-dropdown-item\" \r\n *ngFor=\"let action of actions\"\r\n [disabled]=\"action.disabled\"\r\n [ngClass]=\"action.variant ? 'cc-dropdown-item--' + action.variant : (action.color === 'red' || action.color === 'danger') ? 'cc-dropdown-item--danger' : ''\"\r\n [style.color]=\"action.color && !action.variant && action.color !== 'red' && action.color !== 'danger' ? action.color : null\"\r\n (click)=\"onActionItemClick(action, $event)\">\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\" class=\"cc-dropdown-item-icon\"></i>\r\n <span>{{ action.label }}</span>\r\n </button>\r\n <div class=\"cc-dropdown-empty\" *ngIf=\"!actions || actions.length === 0\">\r\n No actions available\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Confirmation Modal for Critical Actions -->\r\n<cc-confirmation-modal \r\n *ngIf=\"isConfirmModalOpen\"\r\n [isOpen]=\"isConfirmModalOpen\" \r\n [config]=\"confirmConfig!\"\r\n (confirm)=\"invokePendingAction()\"\r\n (close)=\"closeConfirmModal()\"\r\n (cancel)=\"closeConfirmModal()\">\r\n <p>{{ confirmMessage }}</p>\r\n</cc-confirmation-modal>\r\n", styles: [".cc-btn-dropdown-container{position:relative;display:inline-block}.cc-btn-dropdown-container .cc-btn-dropdown-content{display:flex;align-items:center;gap:.5rem}.cc-btn-dropdown-container .cc-btn-dropdown-icon{font-size:.85em;margin-left:2px}.cc-dropdown-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:1000;min-width:140px;border-radius:var(--cc-btn-dropdown-radius, 4px);padding:.25rem 0;font-family:var(--cc-btn-font-family, \"Inter\", sans-serif);font-size:var(--cc-btn-font-size, .875rem)}.cc-dropdown-menu--light{background-color:var(--cc-btn-dropdown-light-bg, #ffffff);border:var(--cc-btn-dropdown-border-light, 1px solid #e0e0e0);box-shadow:var(--cc-btn-dropdown-shadow-light, 0 4px 6px rgba(0, 0, 0, .1))}.cc-dropdown-menu--light .cc-dropdown-item{color:var(--cc-btn-dropdown-light-item-color, #333333)}.cc-dropdown-menu--light .cc-dropdown-item:hover:not(:disabled){background-color:var(--cc-btn-dropdown-light-item-hover-bg, #f5f5f5)}.cc-dropdown-menu--light .cc-dropdown-empty{color:#888}.cc-dropdown-menu--dark{background-color:var(--cc-btn-dropdown-dark-bg, #1a1a1a);border:var(--cc-btn-dropdown-border-dark, 1px solid #444444);box-shadow:var(--cc-btn-dropdown-shadow-dark, 0 4px 6px rgba(0, 0, 0, .5))}.cc-dropdown-menu--dark .cc-dropdown-item{color:var(--cc-btn-dropdown-dark-item-color, #ffffff)}.cc-dropdown-menu--dark .cc-dropdown-item:hover:not(:disabled){background-color:var(--cc-btn-dropdown-dark-item-hover-bg, #2d2d2d)}.cc-dropdown-menu--dark .cc-dropdown-empty{color:#bbb}.cc-dropdown-menu .cc-dropdown-empty{padding:.5rem 1rem;font-style:italic}.cc-dropdown-menu .cc-dropdown-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .2s,color .2s}.cc-dropdown-menu .cc-dropdown-item:disabled{opacity:.5;cursor:not-allowed}.cc-dropdown-menu .cc-dropdown-item .cc-dropdown-item-icon{margin-right:.5rem;width:1rem;text-align:center}.cc-dropdown-menu .cc-dropdown-item--primary{background-color:var(--cc-btn-dropdown-primary-bg, #262125);color:var(--cc-btn-dropdown-primary-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--primary:hover:not(:disabled){background-color:var(--cc-btn-dropdown-primary-hover, #3d353b)}.cc-dropdown-menu .cc-dropdown-item--warning{background-color:var(--cc-btn-dropdown-warning-bg, #F9C80E);color:var(--cc-btn-dropdown-warning-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--warning:hover:not(:disabled){background-color:var(--cc-btn-dropdown-warning-hover, #ebd573)}.cc-dropdown-menu .cc-dropdown-item--danger{background-color:var(--cc-btn-dropdown-danger-bg, #E63E30);color:var(--cc-btn-dropdown-danger-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--danger:hover:not(:disabled){background-color:var(--cc-btn-dropdown-danger-hover, #c93528)}.cc-dropdown-menu .cc-dropdown-item--success{background-color:var(--cc-btn-dropdown-success-bg, #16A34A);color:var(--cc-btn-dropdown-success-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--success:hover:not(:disabled){background-color:var(--cc-btn-dropdown-success-hover, #148f41)}.cc-dropdown-menu .cc-dropdown-item--secondary{background-color:var(--cc-btn-dropdown-secondary-bg, #E8EAED);color:var(--cc-btn-dropdown-secondary-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--secondary:hover:not(:disabled){background-color:var(--cc-btn-dropdown-secondary-hover, #d1d5db)}.cc-dropdown-menu .cc-dropdown-item--outline{background-color:var(--cc-btn-dropdown-outline-bg, transparent);color:var(--cc-btn-dropdown-outline-color, #000000);border:1px solid var(--cc-btn-dropdown-outline-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--outline:hover:not(:disabled){background-color:var(--cc-btn-dropdown-outline-hover, rgba(0, 0, 0, .05))}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }, { kind: "component", type: ConfirmationModalComponent, selector: "cc-confirmation-modal", inputs: ["config", "isOpen"], outputs: ["confirm", "cancel", "close", "showCodeSnippet"] }] });
|
|
7376
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ButtonDropdownComponent, isStandalone: false, selector: "lib-button-dropdown", inputs: { label: "label", variant: "variant", menuTheme: "menuTheme", icon: "icon", actions: "actions", data: "data", disabled: "disabled" }, outputs: { apiActionStart: "apiActionStart", apiActionSuccess: "apiActionSuccess", apiActionError: "apiActionError", actionClick: "actionClick" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, ngImport: i0, template: "<div class=\"cc-btn-dropdown-container\">\r\n <!-- Main Toggle Button -->\r\n <lib-button \r\n [variant]=\"variant\" \r\n [disabled]=\"disabled\"\r\n (click)=\"toggleDropdown($event)\">\r\n <span class=\"cc-btn-dropdown-content\">\r\n {{ label }}\r\n <i *ngIf=\"icon\" [class]=\"icon\" class=\"cc-btn-dropdown-icon\"></i>\r\n </span>\r\n </lib-button>\r\n\r\n <!-- Dropdown Menu -->\r\n <div class=\"cc-dropdown-menu\" [ngClass]=\"'cc-dropdown-menu--' + menuTheme\" *ngIf=\"isOpen\">\r\n <button \r\n type=\"button\" \r\n class=\"cc-dropdown-item\" \r\n *ngFor=\"let action of actions\"\r\n [disabled]=\"action.disabled\"\r\n [ngClass]=\"action.variant ? 'cc-dropdown-item--' + action.variant : (action.color === 'red' || action.color === 'danger') ? 'cc-dropdown-item--danger' : ''\"\r\n [style.color]=\"action.color && !action.variant && action.color !== 'red' && action.color !== 'danger' ? action.color : null\"\r\n (click)=\"onActionItemClick(action, $event)\">\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\" class=\"cc-dropdown-item-icon\"></i>\r\n <span>{{ action.label }}</span>\r\n </button>\r\n <div class=\"cc-dropdown-empty\" *ngIf=\"!actions || actions.length === 0\">\r\n No actions available\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Confirmation Modal for Critical Actions -->\r\n<cc-confirmation-modal \r\n *ngIf=\"isConfirmModalOpen\"\r\n [isOpen]=\"isConfirmModalOpen\" \r\n [config]=\"confirmConfig!\"\r\n (confirm)=\"invokePendingAction()\"\r\n (close)=\"closeConfirmModal()\"\r\n (cancel)=\"closeConfirmModal()\">\r\n <p>{{ confirmMessage }}</p>\r\n</cc-confirmation-modal>\r\n", styles: [".cc-btn-dropdown-container{position:relative;display:inline-block}.cc-btn-dropdown-container .cc-btn-dropdown-content{display:flex;align-items:center;gap:.5rem}.cc-btn-dropdown-container .cc-btn-dropdown-icon{font-size:.85em;margin-left:2px}.cc-dropdown-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:1000;min-width:140px;border-radius:var(--cc-btn-dropdown-radius, 4px);padding:.25rem 0;font-family:var(--cc-btn-font-family, \"Inter\", sans-serif);font-size:var(--cc-btn-font-size, .875rem)}.cc-dropdown-menu--light{background-color:var(--cc-btn-dropdown-light-bg, #ffffff);border:var(--cc-btn-dropdown-border-light, 1px solid #e0e0e0);box-shadow:var(--cc-btn-dropdown-shadow-light, 0 4px 6px rgba(0, 0, 0, .1))}.cc-dropdown-menu--light .cc-dropdown-item{color:var(--cc-btn-dropdown-light-item-color, #333333)}.cc-dropdown-menu--light .cc-dropdown-item:hover:not(:disabled){background-color:var(--cc-btn-dropdown-light-item-hover-bg, #f5f5f5)}.cc-dropdown-menu--light .cc-dropdown-empty{color:#888}.cc-dropdown-menu--dark{background-color:var(--cc-btn-dropdown-dark-bg, #1a1a1a);border:var(--cc-btn-dropdown-border-dark, 1px solid #444444);box-shadow:var(--cc-btn-dropdown-shadow-dark, 0 4px 6px rgba(0, 0, 0, .5))}.cc-dropdown-menu--dark .cc-dropdown-item{color:var(--cc-btn-dropdown-dark-item-color, #ffffff)}.cc-dropdown-menu--dark .cc-dropdown-item:hover:not(:disabled){background-color:var(--cc-btn-dropdown-dark-item-hover-bg, #2d2d2d)}.cc-dropdown-menu--dark .cc-dropdown-empty{color:#bbb}.cc-dropdown-menu .cc-dropdown-empty{padding:.5rem 1rem;font-style:italic}.cc-dropdown-menu .cc-dropdown-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;border:none;background:transparent;text-align:left;cursor:pointer;transition:background-color .2s,color .2s}.cc-dropdown-menu .cc-dropdown-item:disabled{opacity:.5;cursor:not-allowed}.cc-dropdown-menu .cc-dropdown-item .cc-dropdown-item-icon{margin-right:.5rem;width:1rem;text-align:center}.cc-dropdown-menu .cc-dropdown-item--primary{background-color:var(--cc-btn-dropdown-primary-bg, #262125);color:var(--cc-btn-dropdown-primary-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--primary:hover:not(:disabled){background-color:var(--cc-btn-dropdown-primary-hover, #3d353b)}.cc-dropdown-menu .cc-dropdown-item--warning{background-color:var(--cc-btn-dropdown-warning-bg, #F9C80E);color:var(--cc-btn-dropdown-warning-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--warning:hover:not(:disabled){background-color:var(--cc-btn-dropdown-warning-hover, #ebd573)}.cc-dropdown-menu .cc-dropdown-item--danger{background-color:var(--cc-btn-dropdown-danger-bg, #E63E30);color:var(--cc-btn-dropdown-danger-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--danger:hover:not(:disabled){background-color:var(--cc-btn-dropdown-danger-hover, #c93528)}.cc-dropdown-menu .cc-dropdown-item--success{background-color:var(--cc-btn-dropdown-success-bg, #16A34A);color:var(--cc-btn-dropdown-success-color, #ffffff)}.cc-dropdown-menu .cc-dropdown-item--success:hover:not(:disabled){background-color:var(--cc-btn-dropdown-success-hover, #148f41)}.cc-dropdown-menu .cc-dropdown-item--secondary{background-color:var(--cc-btn-dropdown-secondary-bg, #E8EAED);color:var(--cc-btn-dropdown-secondary-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--secondary:hover:not(:disabled){background-color:var(--cc-btn-dropdown-secondary-hover, #d1d5db)}.cc-dropdown-menu .cc-dropdown-item--outline{background-color:var(--cc-btn-dropdown-outline-bg, transparent);color:var(--cc-btn-dropdown-outline-color, #000000);border:1px solid var(--cc-btn-dropdown-outline-color, #000000)}.cc-dropdown-menu .cc-dropdown-item--outline:hover:not(:disabled){background-color:var(--cc-btn-dropdown-outline-hover, rgba(0, 0, 0, .05))}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }, { kind: "component", type: ConfirmationModalComponent, selector: "cc-confirmation-modal", inputs: ["config", "isOpen", "confirmDisabled", "confirmLoading"], outputs: ["confirm", "cancel", "close", "showCodeSnippet"] }] });
|
|
7299
7377
|
}
|
|
7300
7378
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonDropdownComponent, decorators: [{
|
|
7301
7379
|
type: Component,
|
|
@@ -9223,23 +9301,48 @@ class SmartTableComponent {
|
|
|
9223
9301
|
cdr;
|
|
9224
9302
|
ngZone;
|
|
9225
9303
|
config;
|
|
9304
|
+
/**
|
|
9305
|
+
* External data mode: pass table rows directly from the parent.
|
|
9306
|
+
* When this input is provided, the component will NOT make any internal API calls.
|
|
9307
|
+
* Instead, it emits sortChange / pageChange / searchChange / filterChange events
|
|
9308
|
+
* so the parent can fetch and supply updated data.
|
|
9309
|
+
*/
|
|
9310
|
+
tableData;
|
|
9311
|
+
/**
|
|
9312
|
+
* Total number of items — used by the pagination component when operating in
|
|
9313
|
+
* external-data mode. Must be kept in sync by the parent.
|
|
9314
|
+
*/
|
|
9315
|
+
totalItemsCount;
|
|
9226
9316
|
action = new EventEmitter();
|
|
9227
9317
|
topAction = new EventEmitter(); // For top bar buttons
|
|
9228
9318
|
filterChange = new EventEmitter();
|
|
9229
9319
|
rowSelect = new EventEmitter();
|
|
9230
9320
|
columnClick = new EventEmitter();
|
|
9321
|
+
/** Emitted in external-data mode when the user changes the sort column/direction. */
|
|
9322
|
+
sortChange = new EventEmitter();
|
|
9323
|
+
/** Emitted in external-data mode when the user changes the page or page size. */
|
|
9324
|
+
pageChange = new EventEmitter();
|
|
9325
|
+
/** Emitted in external-data mode when the user types in the search box. */
|
|
9326
|
+
searchChange = new EventEmitter();
|
|
9231
9327
|
data = [];
|
|
9232
9328
|
totalItems = 0;
|
|
9233
9329
|
currentPage = 1;
|
|
9234
9330
|
loading = false;
|
|
9235
9331
|
// State
|
|
9236
9332
|
activeSort = { key: '', direction: 'ASC' };
|
|
9333
|
+
isSortActive = false; // true only when orderBy is explicitly configured or user has sorted
|
|
9237
9334
|
activeFilters = {};
|
|
9238
9335
|
searchTerm = '';
|
|
9239
9336
|
selectedRows = [];
|
|
9240
9337
|
stickyColumnStyles = {};
|
|
9241
9338
|
hasStickyColumns = false;
|
|
9242
9339
|
openDropdownId = null;
|
|
9340
|
+
/** Viewport-relative position used to render the dropdown as position:fixed. */
|
|
9341
|
+
dropdownPosition = { top: 0, right: 0 };
|
|
9342
|
+
// --- Delete confirmation modal state ---
|
|
9343
|
+
deleteModalOpen = false;
|
|
9344
|
+
deleteModalConfig = {};
|
|
9345
|
+
pendingDeleteAction = null;
|
|
9243
9346
|
searchSubject = new Subject();
|
|
9244
9347
|
stickyHeaders;
|
|
9245
9348
|
resizeObserver = null;
|
|
@@ -9253,7 +9356,13 @@ class SmartTableComponent {
|
|
|
9253
9356
|
this.searchSubject.pipe(debounceTime(this.config?.searchConfig?.debounceTime || 300), distinctUntilChanged()).subscribe(term => {
|
|
9254
9357
|
this.searchTerm = term;
|
|
9255
9358
|
this.currentPage = 1;
|
|
9256
|
-
this.
|
|
9359
|
+
if (this.tableData !== undefined) {
|
|
9360
|
+
// External-data mode: delegate to parent via event
|
|
9361
|
+
this.searchChange.emit(this.buildChangeEvent());
|
|
9362
|
+
}
|
|
9363
|
+
else {
|
|
9364
|
+
this.loadData();
|
|
9365
|
+
}
|
|
9257
9366
|
});
|
|
9258
9367
|
}
|
|
9259
9368
|
ngOnInit() {
|
|
@@ -9263,15 +9372,36 @@ class SmartTableComponent {
|
|
|
9263
9372
|
}
|
|
9264
9373
|
if (this.config.orderBy) {
|
|
9265
9374
|
this.activeSort.direction = this.config.orderBy;
|
|
9375
|
+
this.isSortActive = true;
|
|
9266
9376
|
}
|
|
9267
9377
|
this.loadFilterOptions();
|
|
9268
|
-
this.
|
|
9378
|
+
if (this.tableData !== undefined) {
|
|
9379
|
+
// External-data mode: sync incoming data, skip internal API call
|
|
9380
|
+
this.data = this.tableData;
|
|
9381
|
+
if (this.totalItemsCount !== undefined) {
|
|
9382
|
+
this.totalItems = this.totalItemsCount;
|
|
9383
|
+
}
|
|
9384
|
+
}
|
|
9385
|
+
else {
|
|
9386
|
+
this.loadData();
|
|
9387
|
+
}
|
|
9269
9388
|
}
|
|
9270
9389
|
}
|
|
9271
9390
|
ngOnChanges(changes) {
|
|
9391
|
+
// External data changed — sync directly without an API call
|
|
9392
|
+
if (changes['tableData']) {
|
|
9393
|
+
this.data = this.tableData || [];
|
|
9394
|
+
}
|
|
9395
|
+
// Total count updated from parent
|
|
9396
|
+
if (changes['totalItemsCount'] && this.totalItemsCount !== undefined) {
|
|
9397
|
+
this.totalItems = this.totalItemsCount;
|
|
9398
|
+
}
|
|
9399
|
+
// Config changed (non-first) — reload filter opts; reload data only if NOT in external mode
|
|
9272
9400
|
if (changes['config'] && !changes['config'].firstChange) {
|
|
9273
9401
|
this.loadFilterOptions();
|
|
9274
|
-
this.
|
|
9402
|
+
if (this.tableData === undefined) {
|
|
9403
|
+
this.loadData();
|
|
9404
|
+
}
|
|
9275
9405
|
setTimeout(() => this.calculateStickyPositions());
|
|
9276
9406
|
}
|
|
9277
9407
|
}
|
|
@@ -9325,8 +9455,8 @@ class SmartTableComponent {
|
|
|
9325
9455
|
};
|
|
9326
9456
|
if (this.activeSort.key)
|
|
9327
9457
|
paramsObj['sortBy'] = this.activeSort.key;
|
|
9328
|
-
//
|
|
9329
|
-
if (this.activeSort.direction)
|
|
9458
|
+
// Only include orderBy if explicitly configured or user has sorted a column
|
|
9459
|
+
if (this.isSortActive && this.activeSort.direction)
|
|
9330
9460
|
paramsObj['orderBy'] = this.activeSort.direction;
|
|
9331
9461
|
// Search Handling
|
|
9332
9462
|
if (this.searchTerm) {
|
|
@@ -9377,7 +9507,9 @@ class SmartTableComponent {
|
|
|
9377
9507
|
}
|
|
9378
9508
|
if (this.activeSort.key) {
|
|
9379
9509
|
paramsObj['sortBy'] = this.activeSort.key;
|
|
9380
|
-
|
|
9510
|
+
// Only include orderBy if explicitly configured or user has sorted a column
|
|
9511
|
+
if (this.isSortActive)
|
|
9512
|
+
paramsObj['orderBy'] = this.activeSort.direction;
|
|
9381
9513
|
}
|
|
9382
9514
|
if (this.searchTerm) {
|
|
9383
9515
|
const searchKey = this.config.searchConfig?.searchKey || 'search';
|
|
@@ -9466,13 +9598,23 @@ class SmartTableComponent {
|
|
|
9466
9598
|
// --- Actions ---
|
|
9467
9599
|
onPageChange(page) {
|
|
9468
9600
|
this.currentPage = page;
|
|
9469
|
-
this.
|
|
9601
|
+
if (this.tableData !== undefined) {
|
|
9602
|
+
this.pageChange.emit(this.buildChangeEvent());
|
|
9603
|
+
}
|
|
9604
|
+
else {
|
|
9605
|
+
this.loadData();
|
|
9606
|
+
}
|
|
9470
9607
|
}
|
|
9471
9608
|
onPageSizeChange(size) {
|
|
9472
9609
|
if (this.config.pagination) {
|
|
9473
9610
|
this.config.pagination.pageSize = size;
|
|
9474
9611
|
this.currentPage = 1; // Reset to first page
|
|
9475
|
-
this.
|
|
9612
|
+
if (this.tableData !== undefined) {
|
|
9613
|
+
this.pageChange.emit(this.buildChangeEvent());
|
|
9614
|
+
}
|
|
9615
|
+
else {
|
|
9616
|
+
this.loadData();
|
|
9617
|
+
}
|
|
9476
9618
|
}
|
|
9477
9619
|
}
|
|
9478
9620
|
onSort(col) {
|
|
@@ -9485,7 +9627,14 @@ class SmartTableComponent {
|
|
|
9485
9627
|
this.activeSort.key = col.key;
|
|
9486
9628
|
this.activeSort.direction = 'ASC';
|
|
9487
9629
|
}
|
|
9488
|
-
this.
|
|
9630
|
+
this.isSortActive = true; // User has actively sorted, include orderBy in API call
|
|
9631
|
+
if (this.tableData !== undefined) {
|
|
9632
|
+
// External-data mode: let the parent handle the API call
|
|
9633
|
+
this.sortChange.emit(this.buildChangeEvent());
|
|
9634
|
+
}
|
|
9635
|
+
else {
|
|
9636
|
+
this.loadData();
|
|
9637
|
+
}
|
|
9489
9638
|
}
|
|
9490
9639
|
onSearch(event) {
|
|
9491
9640
|
const value = event.target.value;
|
|
@@ -9496,7 +9645,24 @@ class SmartTableComponent {
|
|
|
9496
9645
|
this.activeFilters[key] = value;
|
|
9497
9646
|
this.currentPage = 1;
|
|
9498
9647
|
this.filterChange.emit({ key, value });
|
|
9499
|
-
this.
|
|
9648
|
+
if (this.tableData === undefined) {
|
|
9649
|
+
this.loadData();
|
|
9650
|
+
}
|
|
9651
|
+
}
|
|
9652
|
+
// --- Private helpers ---
|
|
9653
|
+
/**
|
|
9654
|
+
* Assembles the current table state into a `TableDataChangeEvent` object.
|
|
9655
|
+
* Emitted to the parent in external-data mode so it can fetch and supply new data.
|
|
9656
|
+
*/
|
|
9657
|
+
buildChangeEvent() {
|
|
9658
|
+
return {
|
|
9659
|
+
page: this.currentPage,
|
|
9660
|
+
pageSize: this.config.pagination?.pageSize || 10,
|
|
9661
|
+
sortBy: this.activeSort.key || undefined,
|
|
9662
|
+
orderBy: this.isSortActive ? this.activeSort.direction : undefined,
|
|
9663
|
+
searchTerm: this.searchTerm || undefined,
|
|
9664
|
+
filters: { ...this.activeFilters }
|
|
9665
|
+
};
|
|
9500
9666
|
}
|
|
9501
9667
|
onAction(action, row) {
|
|
9502
9668
|
if (action.type === 'callback' && action.callback) {
|
|
@@ -9526,6 +9692,10 @@ class SmartTableComponent {
|
|
|
9526
9692
|
}
|
|
9527
9693
|
onActionItemClick(item, row, event) {
|
|
9528
9694
|
event.stopPropagation();
|
|
9695
|
+
if (item.type === 'delete') {
|
|
9696
|
+
this.openDeleteConfirmModal(item, row);
|
|
9697
|
+
return;
|
|
9698
|
+
}
|
|
9529
9699
|
if (item.type === 'callback' && item.callback) {
|
|
9530
9700
|
item.callback(row);
|
|
9531
9701
|
}
|
|
@@ -9551,6 +9721,48 @@ class SmartTableComponent {
|
|
|
9551
9721
|
this.action.emit({ action: item, row });
|
|
9552
9722
|
}
|
|
9553
9723
|
}
|
|
9724
|
+
openDeleteConfirmModal(item, row) {
|
|
9725
|
+
const cfg = item.deleteConfig || {};
|
|
9726
|
+
this.deleteModalConfig = {
|
|
9727
|
+
title: cfg.modalTitle || 'Confirm Delete',
|
|
9728
|
+
size: 'sm',
|
|
9729
|
+
headerTheme: 'dark',
|
|
9730
|
+
confirmButton: {
|
|
9731
|
+
label: cfg.confirmLabel || 'Delete',
|
|
9732
|
+
type: 'danger'
|
|
9733
|
+
},
|
|
9734
|
+
cancelButton: {
|
|
9735
|
+
label: cfg.cancelLabel || 'Cancel',
|
|
9736
|
+
show: true
|
|
9737
|
+
}
|
|
9738
|
+
};
|
|
9739
|
+
this.deleteModalMessage = cfg.modalMessage || 'Are you sure you want to delete this item?';
|
|
9740
|
+
this.pendingDeleteAction = { item, row };
|
|
9741
|
+
this.deleteModalOpen = true;
|
|
9742
|
+
}
|
|
9743
|
+
deleteModalMessage = '';
|
|
9744
|
+
onDeleteConfirm() {
|
|
9745
|
+
this.deleteModalOpen = false;
|
|
9746
|
+
if (!this.pendingDeleteAction)
|
|
9747
|
+
return;
|
|
9748
|
+
const { item, row } = this.pendingDeleteAction;
|
|
9749
|
+
const cfg = item.deleteConfig || {};
|
|
9750
|
+
const idField = cfg.idField || 'id';
|
|
9751
|
+
const url = cfg.apiUrl.replace(`:${idField}`, row[idField]);
|
|
9752
|
+
this.pendingDeleteAction = null;
|
|
9753
|
+
this.loading = true;
|
|
9754
|
+
this.http.delete(url, { headers: this.getHeaders() }).pipe(finalize(() => this.loading = false)).subscribe({
|
|
9755
|
+
next: () => {
|
|
9756
|
+
this.loadData();
|
|
9757
|
+
this.action.emit({ action: item, row });
|
|
9758
|
+
},
|
|
9759
|
+
error: (err) => console.error('[SmartTable] Delete API Error', err)
|
|
9760
|
+
});
|
|
9761
|
+
}
|
|
9762
|
+
onDeleteCancel() {
|
|
9763
|
+
this.deleteModalOpen = false;
|
|
9764
|
+
this.pendingDeleteAction = null;
|
|
9765
|
+
}
|
|
9554
9766
|
onTopAction(action) {
|
|
9555
9767
|
if (action.type === 'callback' && action.callback) {
|
|
9556
9768
|
action.callback(null); // No row for top action
|
|
@@ -9788,19 +10000,35 @@ class SmartTableComponent {
|
|
|
9788
10000
|
}
|
|
9789
10001
|
toggleDropdown(id, event) {
|
|
9790
10002
|
event.stopPropagation();
|
|
9791
|
-
|
|
10003
|
+
if (this.openDropdownId === id) {
|
|
10004
|
+
this.openDropdownId = null;
|
|
10005
|
+
return;
|
|
10006
|
+
}
|
|
10007
|
+
// Compute fixed position from the trigger button so the menu escapes
|
|
10008
|
+
// any overflow:auto ancestor (the table container).
|
|
10009
|
+
const btn = event.currentTarget;
|
|
10010
|
+
const rect = btn.getBoundingClientRect();
|
|
10011
|
+
this.dropdownPosition = {
|
|
10012
|
+
top: rect.bottom + 4,
|
|
10013
|
+
right: window.innerWidth - rect.right
|
|
10014
|
+
};
|
|
10015
|
+
this.openDropdownId = id;
|
|
9792
10016
|
}
|
|
9793
10017
|
closeDropdown() {
|
|
9794
10018
|
this.openDropdownId = null;
|
|
9795
10019
|
}
|
|
9796
10020
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableComponent, deps: [{ token: i3.HttpClient }, { token: i1$4.Router }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
9797
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SmartTableComponent, isStandalone: false, selector: "lib-smart-table", inputs: { config: "config" }, outputs: { action: "action", topAction: "topAction", filterChange: "filterChange", rowSelect: "rowSelect", columnClick: "columnClick" }, host: { listeners: { "document:click": "closeDropdown()" } }, viewQueries: [{ propertyName: "stickyHeaders", predicate: ["stickyHeader"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data; let rowIndex = index\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" \n [class.sticky-col]=\"col.sticky\" \n [ngStyle]=\"stickyColumnStyles[col.key]\"\n [class.clickable-cell]=\"col.clickAction\"\n (click)=\"onColumnClick(row, col)\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions; let i = index\">\n <ng-container *ngIf=\"action.type === 'dropdown'\">\n <div class=\"st-dropdown-container\" (click)=\"$event.stopPropagation()\">\n <button class=\"st-dropdown-btn\" (click)=\"toggleDropdown(rowIndex + '-' + i, $event)\">\n <i [class]=\"action.icon || 'fa fa-ellipsis-h'\"></i>\n </button>\n <div class=\"st-dropdown-menu\" *ngIf=\"openDropdownId === (rowIndex + '-' + i)\">\n <button class=\"st-dropdown-item\" *ngFor=\"let item of action.items\" (click)=\"onActionItemClick(item, row, $event); closeDropdown()\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon + ' st-action-icon'\"></i>\n <span>{{ item.label }}</span>\n </button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"action.type !== 'dropdown'\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </ng-container>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n</div>\n", styles: [".smart-table-wrapper{margin:var(--st-margin, 1.5rem 0);font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:auto;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}.st-table-container table tbody tr .clickable-cell{cursor:pointer;transition:background .2s}.st-table-container table tbody tr .clickable-cell:hover{background:var(--st-cell-hover-bg, #f0f0f0)!important}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.st-action-icon{margin-right:var(--st-action-icon-margin, 8px)}.st-dropdown-container{position:relative;display:inline-block}.st-dropdown-btn{background:transparent;border:none;cursor:pointer;font-size:1.1rem;padding:4px 8px;color:var(--st-text-color, #333);border-radius:4px}.st-dropdown-btn:hover{background:#0000000d}.st-dropdown-menu{position:absolute;top:100%;right:0;min-width:150px;background:var(--st-card-bg, #fff);border:1px solid var(--border-color, #e0e0e0);border-radius:4px;box-shadow:0 4px 12px #00000026;z-index:1000;display:flex;flex-direction:column;padding:4px 0;margin-top:4px}.st-dropdown-item{background:transparent;border:none;padding:8px 16px;text-align:left;cursor:pointer;display:flex;align-items:center;font-size:14px;color:var(--st-text-color, #333);transition:background .2s}.st-dropdown-item:hover{background:#0000000d}.st-dropdown-item .st-action-icon{margin-right:8px;width:16px;text-align:center}.no-data{padding:2rem;color:var(--st-no-data-color, #888)}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PaginationComponent, selector: "lib-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "pageSizeOptions", "theme", "labels"], outputs: ["pageChange", "itemsPerPageChange"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }] });
|
|
10021
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SmartTableComponent, isStandalone: false, selector: "lib-smart-table", inputs: { config: "config", tableData: "tableData", totalItemsCount: "totalItemsCount" }, outputs: { action: "action", topAction: "topAction", filterChange: "filterChange", rowSelect: "rowSelect", columnClick: "columnClick", sortChange: "sortChange", pageChange: "pageChange", searchChange: "searchChange" }, host: { listeners: { "document:click": "closeDropdown()" } }, viewQueries: [{ propertyName: "stickyHeaders", predicate: ["stickyHeader"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data; let rowIndex = index\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" \n [class.sticky-col]=\"col.sticky\" \n [ngStyle]=\"stickyColumnStyles[col.key]\"\n [class.clickable-cell]=\"col.clickAction\"\n (click)=\"onColumnClick(row, col)\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions; let i = index\">\n <ng-container *ngIf=\"action.type === 'dropdown'\">\n <div class=\"st-dropdown-container\" (click)=\"$event.stopPropagation()\">\n <button class=\"st-dropdown-btn\" (click)=\"toggleDropdown(rowIndex + '-' + i, $event)\">\n <i [class]=\"action.icon || 'fa fa-ellipsis-h'\"></i>\n </button>\n <div class=\"st-dropdown-menu\"\n *ngIf=\"openDropdownId === (rowIndex + '-' + i)\"\n [ngStyle]=\"{\n position: 'fixed',\n top: dropdownPosition.top + 'px',\n right: dropdownPosition.right + 'px',\n left: 'auto'\n }\">\n <button class=\"st-dropdown-item\" *ngFor=\"let item of action.items\" (click)=\"onActionItemClick(item, row, $event); closeDropdown()\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon + ' st-action-icon'\"></i>\n <span>{{ item.label }}</span>\n </button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"action.type !== 'dropdown'\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </ng-container>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n\n <!-- Built-in Delete Confirmation Modal -->\n <cc-confirmation-modal\n [isOpen]=\"deleteModalOpen\"\n [config]=\"deleteModalConfig\"\n (confirm)=\"onDeleteConfirm()\"\n (cancel)=\"onDeleteCancel()\"\n (close)=\"onDeleteCancel()\">\n <p>{{ deleteModalMessage }}</p>\n </cc-confirmation-modal>\n</div>\n\n", styles: [".smart-table-wrapper{margin:var(--st-margin, 1.5rem 0);font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:visible;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}.st-table-container table tbody tr .clickable-cell{cursor:pointer;transition:background .2s}.st-table-container table tbody tr .clickable-cell:hover{background:var(--st-cell-hover-bg, #f0f0f0)!important}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.st-action-icon{margin-right:var(--st-action-icon-margin, 8px)}.st-dropdown-container{position:relative;display:inline-block}.st-dropdown-btn{background:transparent;border:none;cursor:pointer;font-size:1.1rem;padding:4px 8px;color:var(--st-text-color, #333);border-radius:4px}.st-dropdown-btn:hover{background:#0000000d}.st-dropdown-menu{min-width:150px;background:var(--st-card-bg, #fff);border:1px solid var(--border-color, #e0e0e0);border-radius:4px;box-shadow:0 4px 12px #00000026;z-index:9999;display:flex;flex-direction:column;padding:4px 0;margin-top:4px}.st-dropdown-item{background:transparent;border:none;padding:8px 16px;text-align:left;cursor:pointer;display:flex;align-items:center;font-size:14px;color:var(--st-text-color, #333);transition:background .2s}.st-dropdown-item:hover{background:#0000000d}.st-dropdown-item .st-action-icon{margin-right:8px;width:16px;text-align:center}.no-data{padding:2rem;color:var(--st-no-data-color, #888);text-align:center}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PaginationComponent, selector: "lib-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "pageSizeOptions", "theme", "labels"], outputs: ["pageChange", "itemsPerPageChange"] }, { kind: "component", type: ButtonComponent, selector: "lib-button", inputs: ["variant", "type", "disabled", "width", "height", "borderRadius", "fontSize", "fontWeight", "backgroundColor", "color", "border", "icon", "labels"] }, { kind: "component", type: ConfirmationModalComponent, selector: "cc-confirmation-modal", inputs: ["config", "isOpen", "confirmDisabled", "confirmLoading"], outputs: ["confirm", "cancel", "close", "showCodeSnippet"] }] });
|
|
9798
10022
|
}
|
|
9799
10023
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableComponent, decorators: [{
|
|
9800
10024
|
type: Component,
|
|
9801
|
-
args: [{ selector: 'lib-smart-table', standalone: false, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data; let rowIndex = index\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" \n [class.sticky-col]=\"col.sticky\" \n [ngStyle]=\"stickyColumnStyles[col.key]\"\n [class.clickable-cell]=\"col.clickAction\"\n (click)=\"onColumnClick(row, col)\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions; let i = index\">\n <ng-container *ngIf=\"action.type === 'dropdown'\">\n <div class=\"st-dropdown-container\" (click)=\"$event.stopPropagation()\">\n <button class=\"st-dropdown-btn\" (click)=\"toggleDropdown(rowIndex + '-' + i, $event)\">\n <i [class]=\"action.icon || 'fa fa-ellipsis-h'\"></i>\n </button>\n <div class=\"st-dropdown-menu\" *ngIf=\"openDropdownId === (rowIndex + '-' + i)\">\n <button class=\"st-dropdown-item\" *ngFor=\"let item of action.items\" (click)=\"onActionItemClick(item, row, $event); closeDropdown()\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon + ' st-action-icon'\"></i>\n <span>{{ item.label }}</span>\n </button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"action.type !== 'dropdown'\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </ng-container>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n</div>\n", styles: [".smart-table-wrapper{margin:var(--st-margin, 1.5rem 0);font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:auto;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}.st-table-container table tbody tr .clickable-cell{cursor:pointer;transition:background .2s}.st-table-container table tbody tr .clickable-cell:hover{background:var(--st-cell-hover-bg, #f0f0f0)!important}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.st-action-icon{margin-right:var(--st-action-icon-margin, 8px)}.st-dropdown-container{position:relative;display:inline-block}.st-dropdown-btn{background:transparent;border:none;cursor:pointer;font-size:1.1rem;padding:4px 8px;color:var(--st-text-color, #333);border-radius:4px}.st-dropdown-btn:hover{background:#0000000d}.st-dropdown-menu{position:absolute;top:100%;right:0;min-width:150px;background:var(--st-card-bg, #fff);border:1px solid var(--border-color, #e0e0e0);border-radius:4px;box-shadow:0 4px 12px #00000026;z-index:1000;display:flex;flex-direction:column;padding:4px 0;margin-top:4px}.st-dropdown-item{background:transparent;border:none;padding:8px 16px;text-align:left;cursor:pointer;display:flex;align-items:center;font-size:14px;color:var(--st-text-color, #333);transition:background .2s}.st-dropdown-item:hover{background:#0000000d}.st-dropdown-item .st-action-icon{margin-right:8px;width:16px;text-align:center}.no-data{padding:2rem;color:var(--st-no-data-color, #888)}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
10025
|
+
args: [{ selector: 'lib-smart-table', standalone: false, template: "<div class=\"smart-table-wrapper\">\n <!-- Top Toolbar -->\n <div class=\"st-toolbar\" *ngIf=\"config.searchConfig?.enabled || (config.filters && config.filters.length > 0) || (config.topBarButtons && config.topBarButtons.length > 0)\">\n \n <!-- Search -->\n <div class=\"st-search\" *ngIf=\"config.searchConfig?.enabled\">\n <i class=\"fa fa-search\"></i>\n <input type=\"text\" [placeholder]=\"config.labels?.searchPlaceholder || 'Search'\" (input)=\"onSearch($event)\">\n </div>\n\n <!-- Filters -->\n <div class=\"st-filters\" *ngIf=\"config.filters\">\n <div class=\"st-filter-item\" *ngFor=\"let filter of config.filters\">\n <select (change)=\"onFilterChange(filter.key, $event)\">\n <option value=\"\">{{ filter.label }}</option>\n <option *ngFor=\"let opt of filter.options\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n <!-- Top Bar Buttons -->\n <div class=\"st-actions\" *ngIf=\"config.topBarButtons\">\n <lib-button *ngFor=\"let btn of config.topBarButtons\" \n [variant]=\"btn.btnVariant || 'primary'\"\n [icon]=\"btn.icon || ''\"\n (click)=\"onTopAction(btn)\">\n {{ btn.label }}\n </lib-button>\n </div>\n </div>\n\n <!-- Table Container -->\n <div class=\"st-table-container\">\n <div class=\"st-check-loader\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <table class=\"st-table\" [class.loading-data]=\"loading\">\n <thead>\n <tr>\n <th *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" (change)=\"onSelectAll($event)\">\n </th>\n <th *ngFor=\"let col of config.columns\" \n #stickyHeader\n [class.sortable]=\"col.sortable\"\n [class.sticky-col]=\"col.sticky\"\n [ngStyle]=\"stickyColumnStyles[col.key]\"\n (click)=\"onSort(col)\">\n {{ col.label }}\n <span *ngIf=\"col.sortable\" class=\"sort-icon\">\n <i class=\"fa\" [ngClass]=\"getSortIcon(col.key)\"></i>\n </span>\n </th>\n <th *ngIf=\"config.actions && config.actions.length > 0\">{{ config.labels?.actionColumnHeader || 'Actions' }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of data; let rowIndex = index\">\n <td *ngIf=\"config.selectable\" class=\"st-checkbox-col\">\n <input type=\"checkbox\" [(ngModel)]=\"row.selected\" (change)=\"onRowSelect(row)\">\n </td>\n <td *ngFor=\"let col of config.columns\" \n [class.sticky-col]=\"col.sticky\" \n [ngStyle]=\"stickyColumnStyles[col.key]\"\n [class.clickable-cell]=\"col.clickAction\"\n (click)=\"onColumnClick(row, col)\">\n <!-- Text/Number/Date -->\n <span *ngIf=\"col.type !== 'custom' && col.type !== 'html' && col.type !== 'badge'\">\n {{ getCellValue(row, col) }}\n </span>\n <!-- HTML -->\n <div *ngIf=\"col.type === 'html'\" [innerHTML]=\"getCellValue(row, col)\"></div>\n <!-- Badge -->\n <span *ngIf=\"col.type === 'badge'\" class=\"st-badge\" [ngClass]=\"getBadgeClass(row, col)\">\n {{ getCellValue(row, col) }}\n </span>\n </td>\n \n <!-- Row Actions -->\n <td *ngIf=\"config.actions && config.actions.length > 0\" class=\"st-row-actions\">\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of config.actions; let i = index\">\n <ng-container *ngIf=\"action.type === 'dropdown'\">\n <div class=\"st-dropdown-container\" (click)=\"$event.stopPropagation()\">\n <button class=\"st-dropdown-btn\" (click)=\"toggleDropdown(rowIndex + '-' + i, $event)\">\n <i [class]=\"action.icon || 'fa fa-ellipsis-h'\"></i>\n </button>\n <div class=\"st-dropdown-menu\"\n *ngIf=\"openDropdownId === (rowIndex + '-' + i)\"\n [ngStyle]=\"{\n position: 'fixed',\n top: dropdownPosition.top + 'px',\n right: dropdownPosition.right + 'px',\n left: 'auto'\n }\">\n <button class=\"st-dropdown-item\" *ngFor=\"let item of action.items\" (click)=\"onActionItemClick(item, row, $event); closeDropdown()\">\n <i *ngIf=\"item.icon\" [class]=\"item.icon + ' st-action-icon'\"></i>\n <span>{{ item.label }}</span>\n </button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"action.type !== 'dropdown'\">\n <lib-button \n [variant]=\"action.btnVariant || 'secondary'\"\n [icon]=\"action.icon || ''\"\n (click)=\"onAction(action, row)\">\n {{ action.label }}\n </lib-button>\n </ng-container>\n </ng-container>\n </div>\n </td>\n </tr>\n <tr *ngIf=\"data.length === 0 && !loading\">\n <td [attr.colspan]=\"columnCount + (config.selectable ? 1 : 0) + (config.actions ? 1 : 0)\" class=\"no-data\">\n {{ config.labels?.noDataMessage || 'No data available' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"st-pagination\" *ngIf=\"config.pagination && config.pagination.enabled\">\n <lib-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"config.pagination.pageSize\"\n [currentPage]=\"currentPage\"\n [pageSizeOptions]=\"config.pagination.pageSizeOptions\"\n (pageChange)=\"onPageChange($event)\"\n (itemsPerPageChange)=\"onPageSizeChange($event)\">\n </lib-pagination>\n </div>\n\n <!-- Built-in Delete Confirmation Modal -->\n <cc-confirmation-modal\n [isOpen]=\"deleteModalOpen\"\n [config]=\"deleteModalConfig\"\n (confirm)=\"onDeleteConfirm()\"\n (cancel)=\"onDeleteCancel()\"\n (close)=\"onDeleteCancel()\">\n <p>{{ deleteModalMessage }}</p>\n </cc-confirmation-modal>\n</div>\n\n", styles: [".smart-table-wrapper{margin:var(--st-margin, 1.5rem 0);font-family:var(--st-font-family, \"Roboto\", sans-serif);background:var(--st-table-bg, #fff);border-radius:var(--st-border-radius, 8px);box-shadow:var(--st-box-shadow, 0 2px 4px rgba(0, 0, 0, .05));display:flex;flex-direction:column;gap:0;padding:0;border:var(--st-table-border, 1px solid #e0e0e0);overflow:hidden}.st-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;padding:var(--st-toolbar-padding, 1rem);background:var(--st-toolbar-bg, #fff);border-bottom:var(--st-toolbar-border-bottom, 1px solid #eee);gap:var(--st-toolbar-gap, 1rem)}.st-toolbar .st-search{position:relative;width:var(--st-search-width, auto)}.st-toolbar .st-search input{padding:var(--st-search-padding, .5rem .5rem .5rem 2rem);border:var(--st-search-border, 1px solid #ccc);border-radius:var(--st-search-radius, 4px);background:var(--st-search-bg, #fff);font-size:var(--st-font-size, 14px);width:100%;color:var(--st-text-color, #333)}.st-toolbar .st-search i{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--st-search-icon-color, #999)}.st-toolbar .st-filters{display:flex;gap:1rem}.st-toolbar .st-filters select{padding:var(--st-filter-padding, .5rem);border:var(--st-filter-border, 1px solid #ccc);border-radius:var(--st-filter-radius, 4px);font-size:var(--st-filter-font-size, 14px);background:var(--st-filter-bg, #fff);color:var(--st-filter-color, #333)}.st-toolbar .st-actions{display:flex;gap:.5rem}.st-table-container{overflow-x:auto;overflow-y:visible;padding:var(--st-table-padding, 1rem)}.st-table-container::-webkit-scrollbar{width:var(--st-scrollbar-width, 8px);height:var(--st-scrollbar-height, 8px)}.st-table-container::-webkit-scrollbar-track{background:var(--st-scrollbar-track-bg, #f1f1f1);border-radius:var(--st-scrollbar-track-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb{background:var(--st-scrollbar-thumb-bg, #c1c1c1);border-radius:var(--st-scrollbar-thumb-radius, 4px)}.st-table-container::-webkit-scrollbar-thumb:hover{background:var(--st-scrollbar-thumb-hover-bg, #a8a8a8)}.st-table-container.has-sticky-header .st-table thead th{position:sticky;top:0;z-index:10;background:var(--st-header-bg, #f9f9f9);box-shadow:0 1px 2px -1px #0000001a}.st-table-container table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--st-font-size, 14px)}.st-table-container table thead{background:var(--st-header-bg, #f9f9f9)}.st-table-container table thead th{padding:.75rem 1rem;text-align:left;color:var(--st-header-color, #333);font-weight:var(--st-header-weight, 500);font-size:var(--st-header-size, 14px);text-transform:var(--st-header-transform, none);border-bottom:var(--st-header-border, 1px solid #eee);white-space:nowrap}.st-table-container table thead th.sortable{cursor:pointer}.st-table-container table thead th.sortable:hover{opacity:.8}.st-table-container table thead th .sort-icon{margin-left:.5rem}.st-table-container table thead th .sort-icon .sort-icon{margin-left:.5rem;font-size:var(--st-sort-icon-size, .8em)}.st-table-container table thead th.st-checkbox-col{width:40px}.st-table-container table thead th.sticky-col{position:sticky;z-index:3;background:var(--st-header-bg, #f9f9f9);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table thead th.sticky-col:first-child{left:0}.st-table-container table tbody tr{background:var(--st-row-bg, #fff)}.st-table-container table tbody tr td{padding:var(--st-cell-padding, 1rem);color:var(--st-text-color, #333);vertical-align:middle;border-bottom:var(--st-row-border, 1px solid #eee)}.st-table-container table tbody tr td.sticky-col{position:sticky;z-index:2;background:var(--st-row-bg, #fff);box-shadow:var(--st-sticky-shadow, 2px 0 5px -2px rgba(0, 0, 0, .1));border-right:var(--st-sticky-border-right, 1px solid rgba(0, 0, 0, .05))}.st-table-container table tbody tr td.sticky-col:first-child{left:0}.st-table-container table tbody tr:hover td,.st-table-container table tbody tr:hover td.sticky-col{background:var(--st-row-hover-bg, #f9f9f9)}.st-table-container table tbody tr.selected td,.st-table-container table tbody tr.selected td.sticky-col{background:var(--st-row-selected-bg, #f3e5f5)}.st-table-container table tbody tr .clickable-cell{cursor:pointer;transition:background .2s}.st-table-container table tbody tr .clickable-cell:hover{background:var(--st-cell-hover-bg, #f0f0f0)!important}input[type=checkbox]{accent-color:var(--st-checkbox-color, #6200EE);width:var(--st-checkbox-size, 16px);height:var(--st-checkbox-size, 16px);cursor:pointer}.st-badge{display:inline-block;padding:var(--st-badge-padding, 4px 12px);border-radius:var(--st-badge-radius, 12px);font-size:var(--st-badge-font-size, 12px);font-weight:var(--st-badge-font-weight, 500);text-align:center;white-space:nowrap}.st-badge.badge-success{background:var(--st-badge-success-bg, #e8f5e9);color:var(--st-badge-success-color, #2e7d32)}.st-badge.badge-warning{background:var(--st-badge-warning-bg, #fff3e0);color:var(--st-badge-warning-color, #ef6c00)}.st-badge.badge-danger{background:var(--st-badge-danger-bg, #ffebee);color:var(--st-badge-danger-color, #c62828)}.st-badge.badge-info{background:var(--st-badge-info-bg, #e3f2fd);color:var(--st-badge-info-color, #1565c0)}.st-badge.badge-neutral{background:var(--st-badge-neutral-bg, #f5f5f5);color:var(--st-badge-neutral-color, #616161)}.st-row-actions .action-buttons{display:flex;gap:.5rem;align-items:center}.st-action-icon{margin-right:var(--st-action-icon-margin, 8px)}.st-dropdown-container{position:relative;display:inline-block}.st-dropdown-btn{background:transparent;border:none;cursor:pointer;font-size:1.1rem;padding:4px 8px;color:var(--st-text-color, #333);border-radius:4px}.st-dropdown-btn:hover{background:#0000000d}.st-dropdown-menu{min-width:150px;background:var(--st-card-bg, #fff);border:1px solid var(--border-color, #e0e0e0);border-radius:4px;box-shadow:0 4px 12px #00000026;z-index:9999;display:flex;flex-direction:column;padding:4px 0;margin-top:4px}.st-dropdown-item{background:transparent;border:none;padding:8px 16px;text-align:left;cursor:pointer;display:flex;align-items:center;font-size:14px;color:var(--st-text-color, #333);transition:background .2s}.st-dropdown-item:hover{background:#0000000d}.st-dropdown-item .st-action-icon{margin-right:8px;width:16px;text-align:center}.no-data{padding:2rem;color:var(--st-no-data-color, #888);text-align:center}.st-pagination{padding:var(--st-pagination-padding, 1rem);border-top:var(--st-pagination-border-top, none)}@media(max-width:768px){.st-toolbar{flex-direction:column;align-items:stretch}.st-toolbar .st-search,.st-toolbar .st-filters,.st-toolbar .st-actions,.st-toolbar .st-search input{width:100%}}.st-table-container{position:relative;min-height:200px}.st-table-container .st-table.loading-data{opacity:.5;pointer-events:none}.st-table-container .st-check-loader{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:10}.st-table-container .st-check-loader .spinner{width:40px;height:40px;border:4px solid var(--st-spinner-border-color, rgba(0, 0, 0, .1));border-left-color:var(--st-loader-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
9802
10026
|
}], ctorParameters: () => [{ type: i3.HttpClient }, { type: i1$4.Router }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], propDecorators: { config: [{
|
|
9803
10027
|
type: Input
|
|
10028
|
+
}], tableData: [{
|
|
10029
|
+
type: Input
|
|
10030
|
+
}], totalItemsCount: [{
|
|
10031
|
+
type: Input
|
|
9804
10032
|
}], action: [{
|
|
9805
10033
|
type: Output
|
|
9806
10034
|
}], topAction: [{
|
|
@@ -9811,6 +10039,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9811
10039
|
type: Output
|
|
9812
10040
|
}], columnClick: [{
|
|
9813
10041
|
type: Output
|
|
10042
|
+
}], sortChange: [{
|
|
10043
|
+
type: Output
|
|
10044
|
+
}], pageChange: [{
|
|
10045
|
+
type: Output
|
|
10046
|
+
}], searchChange: [{
|
|
10047
|
+
type: Output
|
|
9814
10048
|
}], stickyHeaders: [{
|
|
9815
10049
|
type: ViewChildren,
|
|
9816
10050
|
args: ['stickyHeader']
|
|
@@ -9825,12 +10059,14 @@ class SmartTableModule {
|
|
|
9825
10059
|
FormsModule,
|
|
9826
10060
|
PaginationModule,
|
|
9827
10061
|
ButtonModule,
|
|
9828
|
-
MaterialModule
|
|
10062
|
+
MaterialModule,
|
|
10063
|
+
ConfirmationModalModule], exports: [SmartTableComponent] });
|
|
9829
10064
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, imports: [CommonModule,
|
|
9830
10065
|
FormsModule,
|
|
9831
10066
|
PaginationModule,
|
|
9832
10067
|
ButtonModule,
|
|
9833
|
-
MaterialModule
|
|
10068
|
+
MaterialModule,
|
|
10069
|
+
ConfirmationModalModule] });
|
|
9834
10070
|
}
|
|
9835
10071
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SmartTableModule, decorators: [{
|
|
9836
10072
|
type: NgModule,
|
|
@@ -9843,7 +10079,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
9843
10079
|
FormsModule,
|
|
9844
10080
|
PaginationModule,
|
|
9845
10081
|
ButtonModule,
|
|
9846
|
-
MaterialModule
|
|
10082
|
+
MaterialModule,
|
|
10083
|
+
ConfirmationModalModule
|
|
9847
10084
|
],
|
|
9848
10085
|
exports: [
|
|
9849
10086
|
SmartTableComponent
|