@seniorsistemas/components-ai 2.4.0 → 2.4.1
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/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +32 -80
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-date.component.mjs +212 -82
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-datetime.component.mjs +211 -87
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-time.component.mjs +185 -62
- package/fesm2022/seniorsistemas-components-ai.mjs +627 -301
- package/fesm2022/seniorsistemas-components-ai.mjs.map +1 -1
- package/lib/components/dynamic-form/fields/dynamic-field-date.component.d.ts +36 -4
- package/lib/components/dynamic-form/fields/dynamic-field-datetime.component.d.ts +34 -4
- package/lib/components/dynamic-form/fields/dynamic-field-time.component.d.ts +30 -2
- package/package.json +1 -1
|
@@ -13,9 +13,9 @@ import * as i2$1 from '@angular/forms';
|
|
|
13
13
|
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
14
14
|
import * as i4 from 'primeng/dialog';
|
|
15
15
|
import { DialogModule } from 'primeng/dialog';
|
|
16
|
-
import * as
|
|
16
|
+
import * as i7 from 'primeng/button';
|
|
17
17
|
import { ButtonModule } from 'primeng/button';
|
|
18
|
-
import * as i7 from 'primeng/radiobutton';
|
|
18
|
+
import * as i7$1 from 'primeng/radiobutton';
|
|
19
19
|
import { RadioButtonModule } from 'primeng/radiobutton';
|
|
20
20
|
import * as i8 from 'primeng/checkbox';
|
|
21
21
|
import { CheckboxModule } from 'primeng/checkbox';
|
|
@@ -27,14 +27,14 @@ import * as i2$2 from 'primeng/api';
|
|
|
27
27
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
28
28
|
import * as i5 from 'primeng/progressbar';
|
|
29
29
|
import { ProgressBarModule } from 'primeng/progressbar';
|
|
30
|
-
import * as i6
|
|
30
|
+
import * as i6 from 'primeng/tag';
|
|
31
31
|
import { TagModule } from 'primeng/tag';
|
|
32
32
|
import * as i1$2 from '@angular/router';
|
|
33
33
|
import { NavigationEnd, Router } from '@angular/router';
|
|
34
34
|
import * as i2$3 from '@angular/cdk/drag-drop';
|
|
35
35
|
import { moveItemInArray, transferArrayItem, DragDropModule } from '@angular/cdk/drag-drop';
|
|
36
36
|
import { CardModule } from 'primeng/card';
|
|
37
|
-
import * as
|
|
37
|
+
import * as i8$1 from 'primeng/tooltip';
|
|
38
38
|
import { TooltipModule } from 'primeng/tooltip';
|
|
39
39
|
import * as i6$2 from 'primeng/panel';
|
|
40
40
|
import { PanelModule } from 'primeng/panel';
|
|
@@ -44,13 +44,13 @@ import * as i4$1 from 'primeng/inputtext';
|
|
|
44
44
|
import { InputTextModule } from 'primeng/inputtext';
|
|
45
45
|
import * as i3 from 'primeng/inputnumber';
|
|
46
46
|
import { InputNumberModule } from 'primeng/inputnumber';
|
|
47
|
-
import * as
|
|
47
|
+
import * as i5$1 from 'primeng/inputmask';
|
|
48
48
|
import { InputMaskModule } from 'primeng/inputmask';
|
|
49
|
-
import * as
|
|
49
|
+
import * as i6$1 from 'primeng/calendar';
|
|
50
50
|
import { CalendarModule } from 'primeng/calendar';
|
|
51
51
|
import * as i3$1 from 'primeng/dropdown';
|
|
52
52
|
import { DropdownModule } from 'primeng/dropdown';
|
|
53
|
-
import * as i8$
|
|
53
|
+
import * as i8$2 from 'primeng/table';
|
|
54
54
|
import { TableModule } from 'primeng/table';
|
|
55
55
|
import { OverlayPanelModule } from 'primeng/overlaypanel';
|
|
56
56
|
import { InputTextarea } from 'primeng/inputtextarea';
|
|
@@ -2294,7 +2294,7 @@ class ExportDialogComponent {
|
|
|
2294
2294
|
doc.save(fileName);
|
|
2295
2295
|
}
|
|
2296
2296
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDialogComponent, deps: [{ token: TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2297
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ExportDialogComponent, isStandalone: true, selector: "sia-export-dialog", inputs: { visible: "visible", allRecords: "allRecords", selectedRecords: "selectedRecords", statusLabels: "statusLabels", translationPrefix: "translationPrefix", availableColumns: "availableColumns" }, outputs: { visibleChange: "visibleChange" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [(visible)]=\"visible\"\n (onHide)=\"onHide()\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '700px' }\"\n styleClass=\"export-dialog\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"custom-header\">\n <i class=\"pi pi-download header-icon\"></i>\n <span>{{ 'design.components_ai.export_data_title' | translate }}</span>\n </div>\n </ng-template>\n\n <div class=\"export-content\">\n <!-- Formato de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-file\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_format_title' | translate }}</h3>\n </div>\n <div class=\"format-options\">\n <div\n *ngFor=\"let format of formats\"\n class=\"format-card\"\n [class.selected]=\"exportFormat === format.value\"\n (click)=\"exportFormat = format.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"format.value\"\n [(ngModel)]=\"exportFormat\"\n [inputId]=\"format.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\" [class.excel]=\"format.value === 'xlsx'\" [class.pdf]=\"format.value === 'pdf'\">\n <i class=\"pi\" [ngClass]=\"format.icon\"></i>\n </div>\n <div class=\"card-info\">\n <label [for]=\"format.value\" class=\"card-label\">{{ format.label }}</label>\n <span class=\"card-description\">{{ format.description }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Escopo de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-filter\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_scope_title' | translate }}</h3>\n </div>\n <div class=\"scope-options\">\n <div\n *ngFor=\"let scope of scopes\"\n class=\"scope-card\"\n [class.selected]=\"exportScope === scope.value\"\n [class.disabled]=\"scope.value === 'selected' && selectedRecords.length === 0\"\n (click)=\"scope.value === 'selected' && selectedRecords.length === 0 ? null : exportScope = scope.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"scope.value\"\n [(ngModel)]=\"exportScope\"\n [inputId]=\"scope.value\"\n [disabled]=\"scope.value === 'selected' && selectedRecords.length === 0\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi\" [ngClass]=\"scope.icon\"></i>\n </div>\n <div class=\"card-info\">\n <label [for]=\"scope.value\" class=\"card-label\">{{ scope.label }}</label>\n <span class=\"card-description\">{{ scope.description }}</span>\n <span class=\"card-count\">\n <i class=\"pi pi-circle-fill\"></i>\n {{ scope.value === 'all' ? allRecords.length : selectedRecords.length }} {{ 'design.components_ai.export_records_count' | translate }}\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Sele\u00E7\u00E3o de Colunas -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-table\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_columns_title' | translate }}</h3>\n <div class=\"column-actions\">\n <button type=\"button\" class=\"action-link\" (click)=\"selectAllColumns()\">\n {{ 'design.components_ai.export_select_all_columns' | translate }}\n </button>\n <span class=\"separator\">|</span>\n <button type=\"button\" class=\"action-link\" (click)=\"deselectAllColumns()\">\n {{ 'design.components_ai.export_clear_selection' | translate }}\n </button>\n </div>\n </div>\n <div class=\"columns-grid\">\n <div\n *ngFor=\"let column of columns\"\n class=\"column-item\"\n [class.selected]=\"column.selected\"\n (click)=\"column.selected = !column.selected\"\n >\n <p-checkbox\n [(ngModel)]=\"column.selected\"\n [binary]=\"true\"\n [inputId]=\"column.field\"\n ></p-checkbox>\n <label [for]=\"column.field\" class=\"column-label\">\n {{ column.header }}\n </label>\n </div>\n </div>\n <div class=\"columns-summary\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ selectedColumnsCount }} {{ 'design.components_ai.export_columns_summary' | translate }} {{ columns.length }} {{ 'design.components_ai.export_columns_selected' | translate }}</span>\n </div>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button\n [label]=\"'design.components_ai.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onHide()\"\n ></p-button>\n <p-button\n [label]=\"'design.components_ai.export_button' | translate\"\n icon=\"pi pi-download\"\n [disabled]=\"!canExport\"\n (onClick)=\"export()\"\n ></p-button>\n </ng-template>\n</p-dialog>\n", styles: ["::ng-deep .export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.export-section .section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.export-section .section-header .section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.export-section .section-header .section-icon i{font-size:18px;color:var(--p-primary-500)}.export-section .section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800);flex:1}.export-section .section-header .column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.export-section .section-header .column-actions .action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.export-section .section-header .column-actions .action-link:hover{color:var(--p-primary-500)}.export-section .section-header .column-actions .separator{color:var(--neutral-color-300);font-weight:400}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.format-card .card-radio ::ng-deep .p-radiobutton .p-radiobutton-box{width:20px;height:20px;border-width:2px}.format-card .card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1}.format-card .card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%)}.format-card .card-icon.excel i{color:#107c41;font-size:26px}.format-card .card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.format-card .card-icon.pdf i{color:#dc2626;font-size:26px}.format-card .card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.format-card .card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800);cursor:pointer;margin:0}.format-card .card-description{font-size:13px;color:var(--neutral-color-600);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card:hover:not(.disabled):before{opacity:1}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.scope-card.disabled:hover{border-color:#e5e7eb;box-shadow:none}.scope-card .card-radio ::ng-deep .p-radiobutton .p-radiobutton-box{width:20px;height:20px;border-width:2px}.scope-card .card-icon{width:48px;height:48px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%);border-radius:12px;transition:all .3s;position:relative;z-index:1}.scope-card .card-icon i{font-size:22px;color:var(--p-primary-500);transition:all .3s}.scope-card .card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.scope-card .card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800);cursor:pointer;margin:0}.scope-card .card-description{font-size:13px;color:var(--neutral-color-600);line-height:1.4}.scope-card .card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.scope-card .card-count i{font-size:6px}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-item ::ng-deep .p-checkbox .p-checkbox-box{width:20px;height:20px;border-width:2px}.column-item .column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700);font-weight:600}.columns-summary i{color:var(--p-primary-500);font-size:18px}@media (max-width: 768px){::ng-deep .export-dialog .p-dialog{width:95vw!important;margin:0}.dialog-header{padding:28px 24px}.dialog-header .header-icon-wrapper{width:56px;height:56px}.dialog-header .header-icon-wrapper i{font-size:28px}.dialog-header .header-text h2{font-size:24px}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i7.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i8.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DividerModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2297
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ExportDialogComponent, isStandalone: true, selector: "sia-export-dialog", inputs: { visible: "visible", allRecords: "allRecords", selectedRecords: "selectedRecords", statusLabels: "statusLabels", translationPrefix: "translationPrefix", availableColumns: "availableColumns" }, outputs: { visibleChange: "visibleChange" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [(visible)]=\"visible\"\n (onHide)=\"onHide()\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '700px' }\"\n styleClass=\"export-dialog\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"custom-header\">\n <i class=\"pi pi-download header-icon\"></i>\n <span>{{ 'design.components_ai.export_data_title' | translate }}</span>\n </div>\n </ng-template>\n\n <div class=\"export-content\">\n <!-- Formato de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-file\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_format_title' | translate }}</h3>\n </div>\n <div class=\"format-options\">\n <div\n *ngFor=\"let format of formats\"\n class=\"format-card\"\n [class.selected]=\"exportFormat === format.value\"\n (click)=\"exportFormat = format.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"format.value\"\n [(ngModel)]=\"exportFormat\"\n [inputId]=\"format.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\" [class.excel]=\"format.value === 'xlsx'\" [class.pdf]=\"format.value === 'pdf'\">\n <i class=\"pi\" [ngClass]=\"format.icon\"></i>\n </div>\n <div class=\"card-info\">\n <label [for]=\"format.value\" class=\"card-label\">{{ format.label }}</label>\n <span class=\"card-description\">{{ format.description }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Escopo de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-filter\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_scope_title' | translate }}</h3>\n </div>\n <div class=\"scope-options\">\n <div\n *ngFor=\"let scope of scopes\"\n class=\"scope-card\"\n [class.selected]=\"exportScope === scope.value\"\n [class.disabled]=\"scope.value === 'selected' && selectedRecords.length === 0\"\n (click)=\"scope.value === 'selected' && selectedRecords.length === 0 ? null : exportScope = scope.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"scope.value\"\n [(ngModel)]=\"exportScope\"\n [inputId]=\"scope.value\"\n [disabled]=\"scope.value === 'selected' && selectedRecords.length === 0\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi\" [ngClass]=\"scope.icon\"></i>\n </div>\n <div class=\"card-info\">\n <label [for]=\"scope.value\" class=\"card-label\">{{ scope.label }}</label>\n <span class=\"card-description\">{{ scope.description }}</span>\n <span class=\"card-count\">\n <i class=\"pi pi-circle-fill\"></i>\n {{ scope.value === 'all' ? allRecords.length : selectedRecords.length }} {{ 'design.components_ai.export_records_count' | translate }}\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Sele\u00E7\u00E3o de Colunas -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\">\n <i class=\"pi pi-table\"></i>\n </div>\n <h3>{{ 'design.components_ai.export_columns_title' | translate }}</h3>\n <div class=\"column-actions\">\n <button type=\"button\" class=\"action-link\" (click)=\"selectAllColumns()\">\n {{ 'design.components_ai.export_select_all_columns' | translate }}\n </button>\n <span class=\"separator\">|</span>\n <button type=\"button\" class=\"action-link\" (click)=\"deselectAllColumns()\">\n {{ 'design.components_ai.export_clear_selection' | translate }}\n </button>\n </div>\n </div>\n <div class=\"columns-grid\">\n <div\n *ngFor=\"let column of columns\"\n class=\"column-item\"\n [class.selected]=\"column.selected\"\n (click)=\"column.selected = !column.selected\"\n >\n <p-checkbox\n [(ngModel)]=\"column.selected\"\n [binary]=\"true\"\n [inputId]=\"column.field\"\n ></p-checkbox>\n <label [for]=\"column.field\" class=\"column-label\">\n {{ column.header }}\n </label>\n </div>\n </div>\n <div class=\"columns-summary\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ selectedColumnsCount }} {{ 'design.components_ai.export_columns_summary' | translate }} {{ columns.length }} {{ 'design.components_ai.export_columns_selected' | translate }}</span>\n </div>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button\n [label]=\"'design.components_ai.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onHide()\"\n ></p-button>\n <p-button\n [label]=\"'design.components_ai.export_button' | translate\"\n icon=\"pi pi-download\"\n [disabled]=\"!canExport\"\n (onClick)=\"export()\"\n ></p-button>\n </ng-template>\n</p-dialog>\n", styles: ["::ng-deep .export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.export-section .section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.export-section .section-header .section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.export-section .section-header .section-icon i{font-size:18px;color:var(--p-primary-500)}.export-section .section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800);flex:1}.export-section .section-header .column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.export-section .section-header .column-actions .action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.export-section .section-header .column-actions .action-link:hover{color:var(--p-primary-500)}.export-section .section-header .column-actions .separator{color:var(--neutral-color-300);font-weight:400}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.format-card .card-radio ::ng-deep .p-radiobutton .p-radiobutton-box{width:20px;height:20px;border-width:2px}.format-card .card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1}.format-card .card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%)}.format-card .card-icon.excel i{color:#107c41;font-size:26px}.format-card .card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.format-card .card-icon.pdf i{color:#dc2626;font-size:26px}.format-card .card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.format-card .card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800);cursor:pointer;margin:0}.format-card .card-description{font-size:13px;color:var(--neutral-color-600);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card:hover:not(.disabled):before{opacity:1}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.scope-card.disabled:hover{border-color:#e5e7eb;box-shadow:none}.scope-card .card-radio ::ng-deep .p-radiobutton .p-radiobutton-box{width:20px;height:20px;border-width:2px}.scope-card .card-icon{width:48px;height:48px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%);border-radius:12px;transition:all .3s;position:relative;z-index:1}.scope-card .card-icon i{font-size:22px;color:var(--p-primary-500);transition:all .3s}.scope-card .card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.scope-card .card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800);cursor:pointer;margin:0}.scope-card .card-description{font-size:13px;color:var(--neutral-color-600);line-height:1.4}.scope-card .card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.scope-card .card-count i{font-size:6px}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-item ::ng-deep .p-checkbox .p-checkbox-box{width:20px;height:20px;border-width:2px}.column-item .column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50) 0%,var(--p-primary-100) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700);font-weight:600}.columns-summary i{color:var(--p-primary-500);font-size:18px}@media (max-width: 768px){::ng-deep .export-dialog .p-dialog{width:95vw!important;margin:0}.dialog-header{padding:28px 24px}.dialog-header .header-icon-wrapper{width:56px;height:56px}.dialog-header .header-icon-wrapper i{font-size:28px}.dialog-header .header-text h2{font-size:24px}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i7$1.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i8.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DividerModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2298
2298
|
}
|
|
2299
2299
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDialogComponent, decorators: [{
|
|
2300
2300
|
type: Component,
|
|
@@ -2442,7 +2442,7 @@ class BulkDeleteDialogComponent {
|
|
|
2442
2442
|
}
|
|
2443
2443
|
}
|
|
2444
2444
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BulkDeleteDialogComponent, deps: [{ token: TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2445
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: BulkDeleteDialogComponent, isStandalone: true, selector: "sia-bulk-delete-dialog", inputs: { visible: "visible", stages: "stages", service: "service", entityNameField: "entityNameField", entityCodeField: "entityCodeField", translationPrefix: "translationPrefix" }, outputs: { visibleChange: "visibleChange", onComplete: "onComplete" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [(visible)]=\"visible\"\n [modal]=\"true\"\n [closable]=\"canClose\"\n [closeOnEscape]=\"canClose\"\n [dismissableMask]=\"false\"\n [style]=\"{ width: '700px', maxWidth: '90vw' }\"\n (onHide)=\"onHide()\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"dialog-header\">\n <i class=\"pi pi-trash header-icon\"></i>\n <h2>{{ 'design.components_ai.bulk_delete_title' | translate }}</h2>\n </div>\n </ng-template>\n\n <div class=\"dialog-content\">\n <!-- Summary -->\n @if (!isProcessing && !isCompleted) {\n <div class=\"summary-section\">\n <p class=\"summary-text\">\n <i class=\"pi pi-exclamation-triangle warning-icon\"></i>\n <span [innerHTML]=\"'design.components_ai.bulk_delete_warning' | translate:{ count: stages.length }\"></span>\n </p>\n <p class=\"summary-description\">\n {{ 'design.components_ai.bulk_delete_description' | translate }}\n </p>\n </div>\n }\n\n <!-- Progress Bar -->\n @if (isProcessing || isCompleted) {\n <div class=\"progress-section\">\n <div class=\"progress-info\">\n <span class=\"progress-label\">{{ 'design.components_ai.bulk_delete_progress' | translate }}</span>\n <span class=\"progress-count\">{{ currentIndex }} / {{ deleteStatuses.length }}</span>\n </div>\n <p-progressBar \n [value]=\"progress\" \n [showValue]=\"false\"\n styleClass=\"custom-progress\"\n ></p-progressBar>\n \n <div class=\"progress-stats\">\n <div class=\"stat success\">\n <i class=\"pi pi-check-circle\"></i>\n <span>{{ successCount }} {{ 'design.components_ai.bulk_delete_success_count' | translate }}</span>\n </div>\n @if (errorCount > 0) {\n <div class=\"stat error\">\n <i class=\"pi pi-times-circle\"></i>\n <span>{{ errorCount }} {{ 'design.components_ai.bulk_delete_error_count' | translate }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Status List -->\n @if (isProcessing || isCompleted) {\n <div class=\"status-list\">\n @for (item of deleteStatuses; track item.entity) {\n <div class=\"status-item\">\n <div class=\"status-info\">\n <i [class]=\"getStatusIcon(item.status)\" class=\"status-icon\"></i>\n <div class=\"status-details\">\n <span class=\"stage-name\">{{ item.entity[entityNameField] }}</span>\n @if (item.entity[entityCodeField]) {\n <span class=\"stage-code\">{{ 'design.components_ai.bulk_delete_code_label' | translate }}: {{ item.entity[entityCodeField] }}</span>\n }\n </div>\n </div>\n <div class=\"status-badge\">\n <p-tag \n [value]=\"getStatusLabel(item.status)\" \n [severity]=\"getStatusSeverity(item.status)\"\n >\n @if (item.status === 'processing') {\n <i class=\"pi pi-spin pi-spinner\"></i>\n }\n </p-tag>\n @if (item.status === 'error' && item.errorMessage) {\n <small class=\"error-message\">\n {{ item.errorMessage }}\n </small>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Completion Message -->\n @if (isCompleted) {\n <div class=\"completion-section\">\n <div class=\"completion-message\" [class.has-errors]=\"errorCount > 0\">\n <i [class]=\"errorCount > 0 ? 'pi pi-exclamation-circle' : 'pi pi-check-circle'\" class=\"completion-icon\"></i>\n @if (errorCount === 0) {\n <p>\n {{ 'design.components_ai.bulk_delete_success_message' | translate }}\n </p>\n }\n @if (errorCount > 0) {\n <p>\n {{ 'design.components_ai.bulk_delete_completed_with_errors' | translate:{ count: errorCount } }}\n </p>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n @if (!isProcessing && !isCompleted) {\n <p-button\n [label]=\"'design.components_ai.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onClose()\"\n ></p-button>\n <p-button\n [label]=\"'design.components_ai.bulk_delete_confirm' | translate\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n (onClick)=\"startDeletion()\"\n ></p-button>\n }\n @if (isCompleted) {\n <p-button\n [label]=\"'design.components_ai.close' | translate\"\n icon=\"pi pi-check\"\n (onClick)=\"onClose()\"\n ></p-button>\n }\n </div>\n </ng-template>\n</p-dialog>\n", styles: [".dialog-header{display:flex;align-items:center;gap:12px}.dialog-header .header-icon{font-size:24px;color:#ef4444}.dialog-header h2{margin:0;font-size:20px;font-weight:700;color:var(--neutral-color-800)}.dialog-content{padding:8px 0}.summary-section{padding:20px;background:linear-gradient(135deg,#fef3c7,#fde68a);border-radius:12px;border:1px solid #fbbf24;margin-bottom:24px}.summary-section .summary-text{display:flex;align-items:center;gap:12px;margin:0 0 12px;font-size:16px;color:var(--neutral-color-800)}.summary-section .summary-text .warning-icon{font-size:24px;color:#f59e0b}.summary-section .summary-text strong{color:#d97706}.summary-section .summary-description{margin:0;font-size:14px;color:var(--neutral-color-600);padding-left:36px}.progress-section{margin-bottom:24px}.progress-section .progress-info{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.progress-section .progress-info .progress-label{font-weight:600;font-size:14px;color:var(--neutral-color-800)}.progress-section .progress-info .progress-count{font-size:14px;color:var(--neutral-color-600);font-weight:500}.progress-section .progress-stats{display:flex;gap:20px;margin-top:12px}.progress-section .progress-stats .stat{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:500}.progress-section .progress-stats .stat.success{color:#10b981}.progress-section .progress-stats .stat.success i{font-size:18px}.progress-section .progress-stats .stat.error{color:#ef4444}.progress-section .progress-stats .stat.error i{font-size:18px}.status-list{max-height:400px;overflow-y:auto;border:1px solid var(--p-surface-200);border-radius:12px;padding:12px;background-color:#fafafa}.status-list .status-item{display:flex;justify-content:space-between;align-items:center;padding:12px;background-color:#fff;border-radius:8px;margin-bottom:8px;transition:all .2s ease}.status-list .status-item:last-child{margin-bottom:0}.status-list .status-item:hover{box-shadow:0 2px 8px #00000014}.status-list .status-item .status-info{display:flex;align-items:center;gap:12px;flex:1}.status-list .status-item .status-info .status-icon{font-size:20px}.status-list .status-item .status-info .status-icon.pi-clock{color:var(--neutral-color-400)}.status-list .status-item .status-info .status-icon.pi-spinner{color:#3b82f6}.status-list .status-item .status-info .status-icon.pi-check{color:#10b981}.status-list .status-item .status-info .status-icon.pi-times{color:#ef4444}.status-list .status-item .status-info .status-details{display:flex;flex-direction:column;gap:4px}.status-list .status-item .status-info .status-details .stage-name{font-weight:600;font-size:14px;color:var(--neutral-color-800)}.status-list .status-item .status-info .status-details .stage-code{font-size:12px;color:var(--neutral-color-500)}.status-list .status-item .status-badge{display:flex;flex-direction:column;align-items:flex-end;gap:4px}.status-list .status-item .status-badge .error-message{font-size:11px;color:#ef4444;max-width:200px;text-align:right}.completion-section{margin-top:24px}.completion-section .completion-message{padding:20px;background:linear-gradient(135deg,#d1fae5,#a7f3d0);border-radius:12px;border:1px solid #10b981;display:flex;align-items:center;gap:16px}.completion-section .completion-message.has-errors{background:linear-gradient(135deg,#fee2e2,#fecaca);border-color:#ef4444}.completion-section .completion-message.has-errors .completion-icon{color:#ef4444}.completion-section .completion-message .completion-icon{font-size:32px;color:#10b981}.completion-section .completion-message p{margin:0;font-size:16px;font-weight:600;color:var(--neutral-color-800)}.dialog-footer{display:flex;justify-content:flex-end;gap:12px}::ng-deep .custom-progress{height:12px;border-radius:6px}::ng-deep .custom-progress .p-progressbar-value{background:linear-gradient(90deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);border-radius:6px}.status-list::-webkit-scrollbar{width:8px}.status-list::-webkit-scrollbar-track{background:var(--p-surface-100);border-radius:4px}.status-list::-webkit-scrollbar-thumb{background:var(--neutral-color-400);border-radius:4px}.status-list::-webkit-scrollbar-thumb:hover{background:var(--neutral-color-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i5.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i6$1.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2445
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: BulkDeleteDialogComponent, isStandalone: true, selector: "sia-bulk-delete-dialog", inputs: { visible: "visible", stages: "stages", service: "service", entityNameField: "entityNameField", entityCodeField: "entityCodeField", translationPrefix: "translationPrefix" }, outputs: { visibleChange: "visibleChange", onComplete: "onComplete" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [(visible)]=\"visible\"\n [modal]=\"true\"\n [closable]=\"canClose\"\n [closeOnEscape]=\"canClose\"\n [dismissableMask]=\"false\"\n [style]=\"{ width: '700px', maxWidth: '90vw' }\"\n (onHide)=\"onHide()\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"dialog-header\">\n <i class=\"pi pi-trash header-icon\"></i>\n <h2>{{ 'design.components_ai.bulk_delete_title' | translate }}</h2>\n </div>\n </ng-template>\n\n <div class=\"dialog-content\">\n <!-- Summary -->\n @if (!isProcessing && !isCompleted) {\n <div class=\"summary-section\">\n <p class=\"summary-text\">\n <i class=\"pi pi-exclamation-triangle warning-icon\"></i>\n <span [innerHTML]=\"'design.components_ai.bulk_delete_warning' | translate:{ count: stages.length }\"></span>\n </p>\n <p class=\"summary-description\">\n {{ 'design.components_ai.bulk_delete_description' | translate }}\n </p>\n </div>\n }\n\n <!-- Progress Bar -->\n @if (isProcessing || isCompleted) {\n <div class=\"progress-section\">\n <div class=\"progress-info\">\n <span class=\"progress-label\">{{ 'design.components_ai.bulk_delete_progress' | translate }}</span>\n <span class=\"progress-count\">{{ currentIndex }} / {{ deleteStatuses.length }}</span>\n </div>\n <p-progressBar \n [value]=\"progress\" \n [showValue]=\"false\"\n styleClass=\"custom-progress\"\n ></p-progressBar>\n \n <div class=\"progress-stats\">\n <div class=\"stat success\">\n <i class=\"pi pi-check-circle\"></i>\n <span>{{ successCount }} {{ 'design.components_ai.bulk_delete_success_count' | translate }}</span>\n </div>\n @if (errorCount > 0) {\n <div class=\"stat error\">\n <i class=\"pi pi-times-circle\"></i>\n <span>{{ errorCount }} {{ 'design.components_ai.bulk_delete_error_count' | translate }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Status List -->\n @if (isProcessing || isCompleted) {\n <div class=\"status-list\">\n @for (item of deleteStatuses; track item.entity) {\n <div class=\"status-item\">\n <div class=\"status-info\">\n <i [class]=\"getStatusIcon(item.status)\" class=\"status-icon\"></i>\n <div class=\"status-details\">\n <span class=\"stage-name\">{{ item.entity[entityNameField] }}</span>\n @if (item.entity[entityCodeField]) {\n <span class=\"stage-code\">{{ 'design.components_ai.bulk_delete_code_label' | translate }}: {{ item.entity[entityCodeField] }}</span>\n }\n </div>\n </div>\n <div class=\"status-badge\">\n <p-tag \n [value]=\"getStatusLabel(item.status)\" \n [severity]=\"getStatusSeverity(item.status)\"\n >\n @if (item.status === 'processing') {\n <i class=\"pi pi-spin pi-spinner\"></i>\n }\n </p-tag>\n @if (item.status === 'error' && item.errorMessage) {\n <small class=\"error-message\">\n {{ item.errorMessage }}\n </small>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Completion Message -->\n @if (isCompleted) {\n <div class=\"completion-section\">\n <div class=\"completion-message\" [class.has-errors]=\"errorCount > 0\">\n <i [class]=\"errorCount > 0 ? 'pi pi-exclamation-circle' : 'pi pi-check-circle'\" class=\"completion-icon\"></i>\n @if (errorCount === 0) {\n <p>\n {{ 'design.components_ai.bulk_delete_success_message' | translate }}\n </p>\n }\n @if (errorCount > 0) {\n <p>\n {{ 'design.components_ai.bulk_delete_completed_with_errors' | translate:{ count: errorCount } }}\n </p>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n @if (!isProcessing && !isCompleted) {\n <p-button\n [label]=\"'design.components_ai.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onClose()\"\n ></p-button>\n <p-button\n [label]=\"'design.components_ai.bulk_delete_confirm' | translate\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n (onClick)=\"startDeletion()\"\n ></p-button>\n }\n @if (isCompleted) {\n <p-button\n [label]=\"'design.components_ai.close' | translate\"\n icon=\"pi pi-check\"\n (onClick)=\"onClose()\"\n ></p-button>\n }\n </div>\n </ng-template>\n</p-dialog>\n", styles: [".dialog-header{display:flex;align-items:center;gap:12px}.dialog-header .header-icon{font-size:24px;color:#ef4444}.dialog-header h2{margin:0;font-size:20px;font-weight:700;color:var(--neutral-color-800)}.dialog-content{padding:8px 0}.summary-section{padding:20px;background:linear-gradient(135deg,#fef3c7,#fde68a);border-radius:12px;border:1px solid #fbbf24;margin-bottom:24px}.summary-section .summary-text{display:flex;align-items:center;gap:12px;margin:0 0 12px;font-size:16px;color:var(--neutral-color-800)}.summary-section .summary-text .warning-icon{font-size:24px;color:#f59e0b}.summary-section .summary-text strong{color:#d97706}.summary-section .summary-description{margin:0;font-size:14px;color:var(--neutral-color-600);padding-left:36px}.progress-section{margin-bottom:24px}.progress-section .progress-info{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.progress-section .progress-info .progress-label{font-weight:600;font-size:14px;color:var(--neutral-color-800)}.progress-section .progress-info .progress-count{font-size:14px;color:var(--neutral-color-600);font-weight:500}.progress-section .progress-stats{display:flex;gap:20px;margin-top:12px}.progress-section .progress-stats .stat{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:500}.progress-section .progress-stats .stat.success{color:#10b981}.progress-section .progress-stats .stat.success i{font-size:18px}.progress-section .progress-stats .stat.error{color:#ef4444}.progress-section .progress-stats .stat.error i{font-size:18px}.status-list{max-height:400px;overflow-y:auto;border:1px solid var(--p-surface-200);border-radius:12px;padding:12px;background-color:#fafafa}.status-list .status-item{display:flex;justify-content:space-between;align-items:center;padding:12px;background-color:#fff;border-radius:8px;margin-bottom:8px;transition:all .2s ease}.status-list .status-item:last-child{margin-bottom:0}.status-list .status-item:hover{box-shadow:0 2px 8px #00000014}.status-list .status-item .status-info{display:flex;align-items:center;gap:12px;flex:1}.status-list .status-item .status-info .status-icon{font-size:20px}.status-list .status-item .status-info .status-icon.pi-clock{color:var(--neutral-color-400)}.status-list .status-item .status-info .status-icon.pi-spinner{color:#3b82f6}.status-list .status-item .status-info .status-icon.pi-check{color:#10b981}.status-list .status-item .status-info .status-icon.pi-times{color:#ef4444}.status-list .status-item .status-info .status-details{display:flex;flex-direction:column;gap:4px}.status-list .status-item .status-info .status-details .stage-name{font-weight:600;font-size:14px;color:var(--neutral-color-800)}.status-list .status-item .status-info .status-details .stage-code{font-size:12px;color:var(--neutral-color-500)}.status-list .status-item .status-badge{display:flex;flex-direction:column;align-items:flex-end;gap:4px}.status-list .status-item .status-badge .error-message{font-size:11px;color:#ef4444;max-width:200px;text-align:right}.completion-section{margin-top:24px}.completion-section .completion-message{padding:20px;background:linear-gradient(135deg,#d1fae5,#a7f3d0);border-radius:12px;border:1px solid #10b981;display:flex;align-items:center;gap:16px}.completion-section .completion-message.has-errors{background:linear-gradient(135deg,#fee2e2,#fecaca);border-color:#ef4444}.completion-section .completion-message.has-errors .completion-icon{color:#ef4444}.completion-section .completion-message .completion-icon{font-size:32px;color:#10b981}.completion-section .completion-message p{margin:0;font-size:16px;font-weight:600;color:var(--neutral-color-800)}.dialog-footer{display:flex;justify-content:flex-end;gap:12px}::ng-deep .custom-progress{height:12px;border-radius:6px}::ng-deep .custom-progress .p-progressbar-value{background:linear-gradient(90deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);border-radius:6px}.status-list::-webkit-scrollbar{width:8px}.status-list::-webkit-scrollbar-track{background:var(--p-surface-100);border-radius:4px}.status-list::-webkit-scrollbar-thumb{background:var(--neutral-color-400);border-radius:4px}.status-list::-webkit-scrollbar-thumb:hover{background:var(--neutral-color-500)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i5.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2446
2446
|
}
|
|
2447
2447
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BulkDeleteDialogComponent, decorators: [{
|
|
2448
2448
|
type: Component,
|
|
@@ -3436,7 +3436,7 @@ class KanbanBoardComponent {
|
|
|
3436
3436
|
};
|
|
3437
3437
|
}
|
|
3438
3438
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KanbanBoardComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
3439
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: KanbanBoardComponent, isStandalone: true, selector: "sia-kanban-board", inputs: { columns: "columns", allowReorder: "allowReorder", allowDrag: "allowDrag", showAddButton: "showAddButton", showEditButton: "showEditButton", showDeleteButton: "showDeleteButton", canDeleteColumn: "canDeleteColumn", emptyMessage: "emptyMessage", minColumnWidth: "minColumnWidth", maxColumnWidth: "maxColumnWidth", showScrollHints: "showScrollHints", selectable: "selectable" }, outputs: { itemMoved: "itemMoved", itemClicked: "itemClicked", addItem: "addItem", editColumn: "editColumn", deleteColumn: "deleteColumn", selectionChange: "selectionChange" }, queries: [{ propertyName: "columnHeaderTemplate", first: true, predicate: ["columnHeaderTemplate"], descendants: true }, { propertyName: "itemTemplate", first: true, predicate: ["itemTemplate"], descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"kanban-board\">\n <!-- Scroll hint arrows -->\n <div class=\"kanban-scroll-controls\" *ngIf=\"showScrollHints && hasHorizontalScroll\">\n <button\n *ngIf=\"scrollPosition !== 'start'\"\n pButton\n type=\"button\"\n icon=\"pi pi-chevron-left\"\n [rounded]=\"true\"\n class=\"scroll-hint scroll-hint-left\"\n (click)=\"scrollLeft()\">\n </button>\n <button\n *ngIf=\"scrollPosition !== 'end'\"\n pButton\n type=\"button\"\n icon=\"pi pi-chevron-right\"\n [rounded]=\"true\"\n class=\"scroll-hint scroll-hint-right\"\n (click)=\"scrollRight()\">\n </button>\n </div>\n\n <!-- Scrollable columns container -->\n <div class=\"kanban-columns\" #scrollContainer (scroll)=\"onScroll()\">\n <div \n *ngFor=\"let column of columns\" \n class=\"kanban-column\"\n [style]=\"getColumnStyle(column)\">\n \n <!-- Column Header -->\n <div class=\"column-header\">\n <!-- Custom header template -->\n <ng-container *ngIf=\"columnHeaderTemplate; else defaultColumnHeader\"\n [ngTemplateOutlet]=\"columnHeaderTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\">\n </ng-container>\n\n <ng-template #defaultColumnHeader>\n <div class=\"column-title\">\n <i *ngIf=\"column.icon\" [class]=\"'pi ' + column.icon\"></i>\n <span>{{ column.title }}</span>\n <span class=\"item-count\">{{ column.items.length }}</span>\n </div>\n <div class=\"column-actions\">\n <button \n *ngIf=\"showAddButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-plus\" \n class=\"p-button-text p-button-sm p-button-rounded\"\n (click)=\"onAddItem(column)\"\n [pTooltip]=\"'Add item'\"\n tooltipPosition=\"top\">\n </button>\n <button \n *ngIf=\"showEditButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-pencil\" \n class=\"p-button-text p-button-sm p-button-rounded\"\n (click)=\"onEditColumn(column)\"\n [pTooltip]=\"'Edit column'\"\n tooltipPosition=\"top\">\n </button>\n <button \n *ngIf=\"canShowDeleteButton(column)\"\n pButton \n type=\"button\" \n icon=\"pi pi-trash\" \n class=\"p-button-text p-button-sm p-button-rounded p-button-danger\"\n (click)=\"onDeleteColumn(column)\"\n [pTooltip]=\"'Delete column'\"\n tooltipPosition=\"top\">\n </button>\n </div>\n </ng-template>\n </div>\n\n <!-- Column Content -->\n <div \n class=\"column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"columnIds\"\n (cdkDropListDropped)=\"onDrop($event, column)\">\n \n <!-- Items -->\n <div \n *ngFor=\"let item of column.items\"\n class=\"kanban-item\"\n [class.kanban-item--selected]=\"selectable && isSelected(item)\"\n cdkDrag\n [cdkDragDisabled]=\"!allowDrag\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n (click)=\"onItemClick(item)\">\n \n <!-- Custom item template with selection context -->\n <ng-container *ngIf=\"itemTemplate; else defaultItem\"\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"getItemContext(item, column)\">\n </ng-container>\n\n <ng-template #defaultItem>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div *ngIf=\"item.description\" class=\"item-description\">\n {{ item.description }}\n </div>\n <div *ngIf=\"item.tags && item.tags.length > 0\" class=\"item-tags\">\n <p-tag \n *ngFor=\"let tag of item.tags\"\n [value]=\"tag.label\"\n [severity]=\"tag.severity || 'secondary'\"\n styleClass=\"item-tag\">\n </p-tag>\n </div>\n </div>\n </ng-template>\n\n <!-- Drag Placeholder -->\n <div class=\"item-placeholder\" *cdkDragPlaceholder></div>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"column.items.length === 0\" class=\"empty-column\">\n <i class=\"pi pi-inbox\"></i>\n <p>{{ emptyMessage }}</p>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".kanban-board{position:relative;width:100%;height:100%;padding:1rem}.kanban-board .kanban-scroll-controls{position:absolute;inset:0;pointer-events:none;z-index:10}.kanban-board .kanban-scroll-controls .scroll-hint{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto;box-shadow:0 4px 12px #00000026;transition:all .3s ease}.kanban-board .kanban-scroll-controls .scroll-hint:hover{transform:translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}.kanban-board .kanban-scroll-controls .scroll-hint.scroll-hint-left{left:.5rem}.kanban-board .kanban-scroll-controls .scroll-hint.scroll-hint-right{right:.5rem}.kanban-board .kanban-columns{display:flex;gap:1rem;min-height:500px;padding-bottom:1rem;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}.kanban-board .kanban-columns::-webkit-scrollbar{height:6px}.kanban-board .kanban-columns::-webkit-scrollbar-track{background:transparent}.kanban-board .kanban-columns::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:3px}.kanban-board .kanban-columns::-webkit-scrollbar-thumb:hover{background:#94a3b880}.kanban-board .kanban-column{flex-shrink:0;display:flex;flex-direction:column;background:#fff;border-radius:8px;box-shadow:0 1px 3px #0000001a}.kanban-board .kanban-column .column-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e9ecef;background:#fafbfc;border-radius:8px 8px 0 0}.kanban-board .kanban-column .column-header .column-title{display:flex;align-items:center;gap:.5rem;font-weight:600;color:#2c3e50;font-size:.95rem}.kanban-board .kanban-column .column-header .column-title .pi{font-size:.875rem;color:#6c757d}.kanban-board .kanban-column .column-header .column-title .item-count{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;padding:0 .5rem;background:#e9ecef;border-radius:12px;font-size:.75rem;font-weight:600;color:#495057}.kanban-board .kanban-column .column-header .column-actions{display:flex;gap:.25rem}.kanban-board .kanban-column .column-content{flex:1;padding:.75rem;overflow-y:auto;min-height:200px}.kanban-board .kanban-column .column-content .kanban-item{background:#fff;border:1px solid #e9ecef;border-radius:6px;padding:.875rem;margin-bottom:.75rem;cursor:pointer;transition:all .2s ease;box-shadow:0 1px 2px #0000000d}.kanban-board .kanban-column .column-content .kanban-item:hover{border-color:#007bff;box-shadow:0 2px 8px #007bff26;transform:translateY(-1px)}.kanban-board .kanban-column .column-content .kanban-item:last-child{margin-bottom:0}.kanban-board .kanban-column .column-content .kanban-item.kanban-item--selected{border-left:3px solid #007bff;background:#f0f7ff}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-title{font-weight:500;color:#2c3e50;font-size:.875rem;margin-bottom:.5rem;line-height:1.4}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-description{font-size:.8rem;color:#6c757d;margin-bottom:.5rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-tags{display:flex;flex-wrap:wrap;gap:.375rem;margin-top:.5rem}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-tags ::ng-deep .item-tag{font-size:.7rem;padding:.25rem .5rem}.kanban-board .kanban-column .column-content .kanban-item .item-placeholder{background:#e9ecef;border:2px dashed #adb5bd;border-radius:6px;min-height:80px}.kanban-board .kanban-column .column-content .empty-column{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1rem;color:#adb5bd;text-align:center}.kanban-board .kanban-column .column-content .empty-column .pi{font-size:2.5rem;margin-bottom:.5rem;opacity:.5}.kanban-board .kanban-column .column-content .empty-column p{font-size:.875rem;margin:0}::ng-deep .cdk-drag-preview{background:#fff;border:1px solid #007bff;border-radius:6px;padding:.875rem;box-shadow:0 4px 12px #007bff4d;opacity:.9;cursor:grabbing}::ng-deep .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}::ng-deep .cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@media (max-width: 768px){.kanban-board .kanban-columns{flex-direction:column}.kanban-board .kanban-column{min-width:100%!important;max-width:100%!important}.kanban-board .kanban-scroll-controls{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: CardModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i6$1.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] });
|
|
3439
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: KanbanBoardComponent, isStandalone: true, selector: "sia-kanban-board", inputs: { columns: "columns", allowReorder: "allowReorder", allowDrag: "allowDrag", showAddButton: "showAddButton", showEditButton: "showEditButton", showDeleteButton: "showDeleteButton", canDeleteColumn: "canDeleteColumn", emptyMessage: "emptyMessage", minColumnWidth: "minColumnWidth", maxColumnWidth: "maxColumnWidth", showScrollHints: "showScrollHints", selectable: "selectable" }, outputs: { itemMoved: "itemMoved", itemClicked: "itemClicked", addItem: "addItem", editColumn: "editColumn", deleteColumn: "deleteColumn", selectionChange: "selectionChange" }, queries: [{ propertyName: "columnHeaderTemplate", first: true, predicate: ["columnHeaderTemplate"], descendants: true }, { propertyName: "itemTemplate", first: true, predicate: ["itemTemplate"], descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"kanban-board\">\n <!-- Scroll hint arrows -->\n <div class=\"kanban-scroll-controls\" *ngIf=\"showScrollHints && hasHorizontalScroll\">\n <button\n *ngIf=\"scrollPosition !== 'start'\"\n pButton\n type=\"button\"\n icon=\"pi pi-chevron-left\"\n [rounded]=\"true\"\n class=\"scroll-hint scroll-hint-left\"\n (click)=\"scrollLeft()\">\n </button>\n <button\n *ngIf=\"scrollPosition !== 'end'\"\n pButton\n type=\"button\"\n icon=\"pi pi-chevron-right\"\n [rounded]=\"true\"\n class=\"scroll-hint scroll-hint-right\"\n (click)=\"scrollRight()\">\n </button>\n </div>\n\n <!-- Scrollable columns container -->\n <div class=\"kanban-columns\" #scrollContainer (scroll)=\"onScroll()\">\n <div \n *ngFor=\"let column of columns\" \n class=\"kanban-column\"\n [style]=\"getColumnStyle(column)\">\n \n <!-- Column Header -->\n <div class=\"column-header\">\n <!-- Custom header template -->\n <ng-container *ngIf=\"columnHeaderTemplate; else defaultColumnHeader\"\n [ngTemplateOutlet]=\"columnHeaderTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\">\n </ng-container>\n\n <ng-template #defaultColumnHeader>\n <div class=\"column-title\">\n <i *ngIf=\"column.icon\" [class]=\"'pi ' + column.icon\"></i>\n <span>{{ column.title }}</span>\n <span class=\"item-count\">{{ column.items.length }}</span>\n </div>\n <div class=\"column-actions\">\n <button \n *ngIf=\"showAddButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-plus\" \n class=\"p-button-text p-button-sm p-button-rounded\"\n (click)=\"onAddItem(column)\"\n [pTooltip]=\"'Add item'\"\n tooltipPosition=\"top\">\n </button>\n <button \n *ngIf=\"showEditButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-pencil\" \n class=\"p-button-text p-button-sm p-button-rounded\"\n (click)=\"onEditColumn(column)\"\n [pTooltip]=\"'Edit column'\"\n tooltipPosition=\"top\">\n </button>\n <button \n *ngIf=\"canShowDeleteButton(column)\"\n pButton \n type=\"button\" \n icon=\"pi pi-trash\" \n class=\"p-button-text p-button-sm p-button-rounded p-button-danger\"\n (click)=\"onDeleteColumn(column)\"\n [pTooltip]=\"'Delete column'\"\n tooltipPosition=\"top\">\n </button>\n </div>\n </ng-template>\n </div>\n\n <!-- Column Content -->\n <div \n class=\"column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"columnIds\"\n (cdkDropListDropped)=\"onDrop($event, column)\">\n \n <!-- Items -->\n <div \n *ngFor=\"let item of column.items\"\n class=\"kanban-item\"\n [class.kanban-item--selected]=\"selectable && isSelected(item)\"\n cdkDrag\n [cdkDragDisabled]=\"!allowDrag\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n (click)=\"onItemClick(item)\">\n \n <!-- Custom item template with selection context -->\n <ng-container *ngIf=\"itemTemplate; else defaultItem\"\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"getItemContext(item, column)\">\n </ng-container>\n\n <ng-template #defaultItem>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div *ngIf=\"item.description\" class=\"item-description\">\n {{ item.description }}\n </div>\n <div *ngIf=\"item.tags && item.tags.length > 0\" class=\"item-tags\">\n <p-tag \n *ngFor=\"let tag of item.tags\"\n [value]=\"tag.label\"\n [severity]=\"tag.severity || 'secondary'\"\n styleClass=\"item-tag\">\n </p-tag>\n </div>\n </div>\n </ng-template>\n\n <!-- Drag Placeholder -->\n <div class=\"item-placeholder\" *cdkDragPlaceholder></div>\n </div>\n\n <!-- Empty State -->\n <div *ngIf=\"column.items.length === 0\" class=\"empty-column\">\n <i class=\"pi pi-inbox\"></i>\n <p>{{ emptyMessage }}</p>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".kanban-board{position:relative;width:100%;height:100%;padding:1rem}.kanban-board .kanban-scroll-controls{position:absolute;inset:0;pointer-events:none;z-index:10}.kanban-board .kanban-scroll-controls .scroll-hint{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto;box-shadow:0 4px 12px #00000026;transition:all .3s ease}.kanban-board .kanban-scroll-controls .scroll-hint:hover{transform:translateY(-50%) scale(1.1);box-shadow:0 6px 16px #0003}.kanban-board .kanban-scroll-controls .scroll-hint.scroll-hint-left{left:.5rem}.kanban-board .kanban-scroll-controls .scroll-hint.scroll-hint-right{right:.5rem}.kanban-board .kanban-columns{display:flex;gap:1rem;min-height:500px;padding-bottom:1rem;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}.kanban-board .kanban-columns::-webkit-scrollbar{height:6px}.kanban-board .kanban-columns::-webkit-scrollbar-track{background:transparent}.kanban-board .kanban-columns::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:3px}.kanban-board .kanban-columns::-webkit-scrollbar-thumb:hover{background:#94a3b880}.kanban-board .kanban-column{flex-shrink:0;display:flex;flex-direction:column;background:#fff;border-radius:8px;box-shadow:0 1px 3px #0000001a}.kanban-board .kanban-column .column-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e9ecef;background:#fafbfc;border-radius:8px 8px 0 0}.kanban-board .kanban-column .column-header .column-title{display:flex;align-items:center;gap:.5rem;font-weight:600;color:#2c3e50;font-size:.95rem}.kanban-board .kanban-column .column-header .column-title .pi{font-size:.875rem;color:#6c757d}.kanban-board .kanban-column .column-header .column-title .item-count{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;padding:0 .5rem;background:#e9ecef;border-radius:12px;font-size:.75rem;font-weight:600;color:#495057}.kanban-board .kanban-column .column-header .column-actions{display:flex;gap:.25rem}.kanban-board .kanban-column .column-content{flex:1;padding:.75rem;overflow-y:auto;min-height:200px}.kanban-board .kanban-column .column-content .kanban-item{background:#fff;border:1px solid #e9ecef;border-radius:6px;padding:.875rem;margin-bottom:.75rem;cursor:pointer;transition:all .2s ease;box-shadow:0 1px 2px #0000000d}.kanban-board .kanban-column .column-content .kanban-item:hover{border-color:#007bff;box-shadow:0 2px 8px #007bff26;transform:translateY(-1px)}.kanban-board .kanban-column .column-content .kanban-item:last-child{margin-bottom:0}.kanban-board .kanban-column .column-content .kanban-item.kanban-item--selected{border-left:3px solid #007bff;background:#f0f7ff}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-title{font-weight:500;color:#2c3e50;font-size:.875rem;margin-bottom:.5rem;line-height:1.4}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-description{font-size:.8rem;color:#6c757d;margin-bottom:.5rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-tags{display:flex;flex-wrap:wrap;gap:.375rem;margin-top:.5rem}.kanban-board .kanban-column .column-content .kanban-item .item-content .item-tags ::ng-deep .item-tag{font-size:.7rem;padding:.25rem .5rem}.kanban-board .kanban-column .column-content .kanban-item .item-placeholder{background:#e9ecef;border:2px dashed #adb5bd;border-radius:6px;min-height:80px}.kanban-board .kanban-column .column-content .empty-column{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem 1rem;color:#adb5bd;text-align:center}.kanban-board .kanban-column .column-content .empty-column .pi{font-size:2.5rem;margin-bottom:.5rem;opacity:.5}.kanban-board .kanban-column .column-content .empty-column p{font-size:.875rem;margin:0}::ng-deep .cdk-drag-preview{background:#fff;border:1px solid #007bff;border-radius:6px;padding:.875rem;box-shadow:0 4px 12px #007bff4d;opacity:.9;cursor:grabbing}::ng-deep .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}::ng-deep .cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@media (max-width: 768px){.kanban-board .kanban-columns{flex-direction:column}.kanban-board .kanban-column{min-width:100%!important;max-width:100%!important}.kanban-board .kanban-scroll-controls{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i7.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: CardModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i6.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] });
|
|
3440
3440
|
}
|
|
3441
3441
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KanbanBoardComponent, decorators: [{
|
|
3442
3442
|
type: Component,
|
|
@@ -3682,7 +3682,7 @@ class StepsComponent {
|
|
|
3682
3682
|
this.visibleSteps = this.steps.slice(this.visibleStartIndex, this.visibleEndIndex + 1);
|
|
3683
3683
|
}
|
|
3684
3684
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StepsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3685
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: StepsComponent, isStandalone: true, selector: "sia-steps", inputs: { steps: "steps", activeIndex: "activeIndex", readonly: "readonly", maxVisible: "maxVisible", stepMinWidth: "stepMinWidth", animated: "animated", navigationMode: "navigationMode", colorScheme: "colorScheme", styleClass: "styleClass" }, outputs: { activeIndexChange: "activeIndexChange", stepClick: "stepClick" }, viewQueries: [{ propertyName: "stepsContainer", first: true, predicate: ["stepsContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"sia-steps-wrapper\" [class]=\"styleClass\" [class.animated]=\"animated\"\n [class.theme-success]=\"colorScheme === 'success'\"\n [class.theme-danger]=\"colorScheme === 'danger'\"\n [class.theme-warning]=\"colorScheme === 'warning'\"\n [class.theme-info]=\"colorScheme === 'info'\"\n #stepsContainer>\n <!-- Bot\u00E3o de navega\u00E7\u00E3o esquerda -->\n <button\n *ngIf=\"hasOverflowLeft\"\n class=\"sia-steps-nav sia-steps-nav-left\"\n (click)=\"navigateLeft()\"\n [attr.aria-label]=\"'Anterior (' + hiddenLeftCount + ' ocultos)'\"\n type=\"button\">\n <span class=\"nav-badge\">{{ hiddenLeftCount }}</span>\n <i class=\"pi pi-chevron-left\"></i>\n </button>\n\n <!-- Steps vis\u00EDveis -->\n <div class=\"sia-steps-content\" [class.has-overflow-left]=\"hasOverflowLeft\" [class.has-overflow-right]=\"hasOverflowRight\">\n <div class=\"sia-steps-list\">\n <ng-container *ngFor=\"let step of visibleSteps; let i = index; let first = first; let last = last; trackBy: trackByIndex\">\n <!-- Conector (n\u00E3o aparece antes do primeiro) -->\n <div *ngIf=\"!first\" class=\"sia-step-connector\" [class.completed]=\"getStepState(i) === 'completed' || getStepState(i - 1) === 'completed'\">\n <div class=\"connector-line\"></div>\n </div>\n\n <!-- Step item -->\n <div\n class=\"sia-step-item\"\n [class.active]=\"getStepState(i) === 'active'\"\n [class.completed]=\"getStepState(i) === 'completed'\"\n [class.pending]=\"getStepState(i) === 'pending'\"\n [class.disabled]=\"step.disabled\"\n [class.clickable]=\"!readonly && !step.disabled\"\n [class]=\"step.styleClass || ''\"\n [pTooltip]=\"step.label\"\n tooltipPosition=\"top\"\n (click)=\"onStepClick(step, i)\"\n [attr.role]=\"readonly ? 'listitem' : 'button'\"\n [attr.aria-current]=\"getStepState(i) === 'active' ? 'step' : null\"\n [attr.aria-disabled]=\"step.disabled || readonly\">\n \n <!-- \u00CDcone/n\u00FAmero do step -->\n <div class=\"sia-step-marker\">\n <i *ngIf=\"getStepState(i) === 'completed' && !step.icon\" class=\"pi pi-check\"></i>\n <i *ngIf=\"step.icon && getStepState(i) !== 'completed'\" [class]=\"'pi ' + step.icon\"></i>\n <span *ngIf=\"!step.icon && getStepState(i) !== 'completed'\">{{ getRealIndex(i) + 1 }}</span>\n </div>\n\n <!-- Label do step -->\n <div class=\"sia-step-label\">\n <span class=\"label-text\">{{ step.label }}</span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Bot\u00E3o de navega\u00E7\u00E3o direita -->\n <button\n *ngIf=\"hasOverflowRight\"\n class=\"sia-steps-nav sia-steps-nav-right\"\n (click)=\"navigateRight()\"\n [attr.aria-label]=\"'Pr\u00F3ximo (' + hiddenRightCount + ' ocultos)'\"\n type=\"button\">\n <i class=\"pi pi-chevron-right\"></i>\n <span class=\"nav-badge\">{{ hiddenRightCount }}</span>\n </button>\n</div>\n", styles: [":host{display:block;width:100%}.sia-steps-wrapper{display:flex;align-items:center;width:100%;gap:4px;position:relative}.sia-steps-nav{display:flex;align-items:center;gap:4px;background:var(--p-surface-100, #f1f5f9);border:1px solid var(--p-surface-200, #e2e8f0);border-radius:8px;padding:6px 10px;cursor:pointer;color:var(--p-text-secondary-color, #64748b);font-size:12px;font-weight:500;transition:all .2s ease;flex-shrink:0;min-width:36px;justify-content:center}.sia-steps-nav:hover{background:var(--p-primary-50, #eff6ff);border-color:var(--p-primary-200, #bfdbfe);color:var(--p-primary-600, #2563eb)}.sia-steps-nav:active{transform:scale(.95)}.sia-steps-nav .nav-badge{background:var(--p-primary-100, #dbeafe);color:var(--p-primary-700, #1d4ed8);border-radius:10px;padding:1px 6px;font-size:11px;font-weight:600;line-height:1.4}.sia-steps-nav i{font-size:12px}.sia-steps-content{flex:1;overflow:hidden;min-width:0}.sia-steps-content.has-overflow-left{mask-image:linear-gradient(to right,transparent 0%,black 5%)}.sia-steps-content.has-overflow-right{mask-image:linear-gradient(to left,transparent 0%,black 5%)}.sia-steps-content.has-overflow-left.has-overflow-right{mask-image:linear-gradient(to right,transparent 0%,black 5%,black 95%,transparent 100%)}.sia-steps-list{display:flex;align-items:center;justify-content:center;padding:8px 4px}.sia-step-connector{flex:0 0 auto;width:32px;display:flex;align-items:center;justify-content:center}.sia-step-connector .connector-line{width:100%;height:2px;background:var(--p-surface-300, #cbd5e1);border-radius:1px;transition:background .3s ease}.sia-step-connector.completed .connector-line{background:var(--p-primary-400, #60a5fa)}.sia-step-item{display:flex;flex-direction:column;align-items:center;gap:6px;padding:8px 12px;border-radius:10px;transition:all .25s ease;min-width:80px;max-width:160px;position:relative}.sia-step-item.clickable{cursor:pointer}.sia-step-item.clickable:hover{background:var(--p-surface-50, #f8fafc);transform:translateY(-1px)}.sia-step-item.disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.sia-step-item.pending .sia-step-marker{background:var(--p-surface-100, #f1f5f9);border-color:var(--p-surface-300, #cbd5e1);color:var(--p-text-secondary-color, #64748b)}.sia-step-item.pending .sia-step-label .label-text{color:var(--p-text-secondary-color, #64748b)}.sia-step-item.active .sia-step-marker{background:var(--p-primary-500, #3b82f6);border-color:var(--p-primary-500, #3b82f6);color:#fff;box-shadow:0 0 0 4px var(--p-primary-100, #dbeafe);transform:scale(1.1)}.sia-step-item.active .sia-step-label .label-text{color:var(--p-primary-700, #1d4ed8);font-weight:600}.sia-step-item.completed .sia-step-marker{background:var(--p-primary-100, #dbeafe);border-color:var(--p-primary-300, #93c5fd);color:var(--p-primary-600, #2563eb)}.sia-step-item.completed .sia-step-label .label-text{color:var(--p-text-color, #1e293b)}.sia-step-marker{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;border:2px solid;font-size:13px;font-weight:600;transition:all .3s ease;flex-shrink:0}.sia-step-marker i{font-size:14px}.sia-step-label{text-align:center;max-width:100%;overflow:hidden}.sia-step-label .label-text{display:block;font-size:12px;font-weight:500;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--p-text-secondary-color, #64748b);transition:color .2s ease,font-weight .2s ease}.sia-steps-wrapper.animated .sia-steps-list{transition:transform .3s ease}.sia-steps-wrapper.animated .sia-step-item{animation:stepFadeIn .25s ease forwards}@keyframes stepFadeIn{0%{opacity:.6;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.sia-steps-wrapper.theme-success .sia-step-connector.completed .connector-line{background:var(--p-green-400, #4ade80)}.sia-steps-wrapper.theme-success .sia-step-item.active .sia-step-marker{background:var(--p-green-500, #22c55e);border-color:var(--p-green-500, #22c55e);box-shadow:0 0 0 4px var(--p-green-100, #dcfce7)}.sia-steps-wrapper.theme-success .sia-step-item.active .sia-step-label .label-text{color:var(--p-green-700, #15803d)}.sia-steps-wrapper.theme-success .sia-step-item.completed .sia-step-marker{background:var(--p-green-100, #dcfce7);border-color:var(--p-green-300, #86efac);color:var(--p-green-600, #16a34a)}.sia-steps-wrapper.theme-danger .sia-step-connector.completed .connector-line{background:var(--p-red-400, #f87171)}.sia-steps-wrapper.theme-danger .sia-step-item.active .sia-step-marker{background:var(--p-red-500, #ef4444);border-color:var(--p-red-500, #ef4444);box-shadow:0 0 0 4px var(--p-red-100, #fee2e2)}.sia-steps-wrapper.theme-danger .sia-step-item.active .sia-step-label .label-text{color:var(--p-red-700, #b91c1c)}.sia-steps-wrapper.theme-danger .sia-step-item.completed .sia-step-marker{background:var(--p-red-100, #fee2e2);border-color:var(--p-red-300, #fca5a5);color:var(--p-red-600, #dc2626)}.sia-steps-wrapper.theme-warning .sia-step-connector.completed .connector-line{background:var(--p-orange-400, #fb923c)}.sia-steps-wrapper.theme-warning .sia-step-item.active .sia-step-marker{background:var(--p-orange-500, #f97316);border-color:var(--p-orange-500, #f97316);box-shadow:0 0 0 4px var(--p-orange-100, #ffedd5)}.sia-steps-wrapper.theme-warning .sia-step-item.active .sia-step-label .label-text{color:var(--p-orange-700, #c2410c)}.sia-steps-wrapper.theme-warning .sia-step-item.completed .sia-step-marker{background:var(--p-orange-100, #ffedd5);border-color:var(--p-orange-300, #fdba74);color:var(--p-orange-600, #ea580c)}.sia-steps-wrapper.theme-info .sia-step-connector.completed .connector-line{background:var(--p-cyan-400, #22d3ee)}.sia-steps-wrapper.theme-info .sia-step-item.active .sia-step-marker{background:var(--p-cyan-500, #06b6d4);border-color:var(--p-cyan-500, #06b6d4);box-shadow:0 0 0 4px var(--p-cyan-100, #cffafe)}.sia-steps-wrapper.theme-info .sia-step-item.active .sia-step-label .label-text{color:var(--p-cyan-700, #0e7490)}.sia-steps-wrapper.theme-info .sia-step-item.completed .sia-step-marker{background:var(--p-cyan-100, #cffafe);border-color:var(--p-cyan-300, #67e8f9);color:var(--p-cyan-600, #0891b2)}@media (max-width: 576px){.sia-step-item{min-width:60px;max-width:100px;padding:6px 8px}.sia-step-marker{width:30px;height:30px;font-size:11px}.sia-step-marker i{font-size:12px}.sia-step-label .label-text{font-size:11px}.sia-step-connector{width:20px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3685
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: StepsComponent, isStandalone: true, selector: "sia-steps", inputs: { steps: "steps", activeIndex: "activeIndex", readonly: "readonly", maxVisible: "maxVisible", stepMinWidth: "stepMinWidth", animated: "animated", navigationMode: "navigationMode", colorScheme: "colorScheme", styleClass: "styleClass" }, outputs: { activeIndexChange: "activeIndexChange", stepClick: "stepClick" }, viewQueries: [{ propertyName: "stepsContainer", first: true, predicate: ["stepsContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"sia-steps-wrapper\" [class]=\"styleClass\" [class.animated]=\"animated\"\n [class.theme-success]=\"colorScheme === 'success'\"\n [class.theme-danger]=\"colorScheme === 'danger'\"\n [class.theme-warning]=\"colorScheme === 'warning'\"\n [class.theme-info]=\"colorScheme === 'info'\"\n #stepsContainer>\n <!-- Bot\u00E3o de navega\u00E7\u00E3o esquerda -->\n <button\n *ngIf=\"hasOverflowLeft\"\n class=\"sia-steps-nav sia-steps-nav-left\"\n (click)=\"navigateLeft()\"\n [attr.aria-label]=\"'Anterior (' + hiddenLeftCount + ' ocultos)'\"\n type=\"button\">\n <span class=\"nav-badge\">{{ hiddenLeftCount }}</span>\n <i class=\"pi pi-chevron-left\"></i>\n </button>\n\n <!-- Steps vis\u00EDveis -->\n <div class=\"sia-steps-content\" [class.has-overflow-left]=\"hasOverflowLeft\" [class.has-overflow-right]=\"hasOverflowRight\">\n <div class=\"sia-steps-list\">\n <ng-container *ngFor=\"let step of visibleSteps; let i = index; let first = first; let last = last; trackBy: trackByIndex\">\n <!-- Conector (n\u00E3o aparece antes do primeiro) -->\n <div *ngIf=\"!first\" class=\"sia-step-connector\" [class.completed]=\"getStepState(i) === 'completed' || getStepState(i - 1) === 'completed'\">\n <div class=\"connector-line\"></div>\n </div>\n\n <!-- Step item -->\n <div\n class=\"sia-step-item\"\n [class.active]=\"getStepState(i) === 'active'\"\n [class.completed]=\"getStepState(i) === 'completed'\"\n [class.pending]=\"getStepState(i) === 'pending'\"\n [class.disabled]=\"step.disabled\"\n [class.clickable]=\"!readonly && !step.disabled\"\n [class]=\"step.styleClass || ''\"\n [pTooltip]=\"step.label\"\n tooltipPosition=\"top\"\n (click)=\"onStepClick(step, i)\"\n [attr.role]=\"readonly ? 'listitem' : 'button'\"\n [attr.aria-current]=\"getStepState(i) === 'active' ? 'step' : null\"\n [attr.aria-disabled]=\"step.disabled || readonly\">\n \n <!-- \u00CDcone/n\u00FAmero do step -->\n <div class=\"sia-step-marker\">\n <i *ngIf=\"getStepState(i) === 'completed' && !step.icon\" class=\"pi pi-check\"></i>\n <i *ngIf=\"step.icon && getStepState(i) !== 'completed'\" [class]=\"'pi ' + step.icon\"></i>\n <span *ngIf=\"!step.icon && getStepState(i) !== 'completed'\">{{ getRealIndex(i) + 1 }}</span>\n </div>\n\n <!-- Label do step -->\n <div class=\"sia-step-label\">\n <span class=\"label-text\">{{ step.label }}</span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Bot\u00E3o de navega\u00E7\u00E3o direita -->\n <button\n *ngIf=\"hasOverflowRight\"\n class=\"sia-steps-nav sia-steps-nav-right\"\n (click)=\"navigateRight()\"\n [attr.aria-label]=\"'Pr\u00F3ximo (' + hiddenRightCount + ' ocultos)'\"\n type=\"button\">\n <i class=\"pi pi-chevron-right\"></i>\n <span class=\"nav-badge\">{{ hiddenRightCount }}</span>\n </button>\n</div>\n", styles: [":host{display:block;width:100%}.sia-steps-wrapper{display:flex;align-items:center;width:100%;gap:4px;position:relative}.sia-steps-nav{display:flex;align-items:center;gap:4px;background:var(--p-surface-100, #f1f5f9);border:1px solid var(--p-surface-200, #e2e8f0);border-radius:8px;padding:6px 10px;cursor:pointer;color:var(--p-text-secondary-color, #64748b);font-size:12px;font-weight:500;transition:all .2s ease;flex-shrink:0;min-width:36px;justify-content:center}.sia-steps-nav:hover{background:var(--p-primary-50, #eff6ff);border-color:var(--p-primary-200, #bfdbfe);color:var(--p-primary-600, #2563eb)}.sia-steps-nav:active{transform:scale(.95)}.sia-steps-nav .nav-badge{background:var(--p-primary-100, #dbeafe);color:var(--p-primary-700, #1d4ed8);border-radius:10px;padding:1px 6px;font-size:11px;font-weight:600;line-height:1.4}.sia-steps-nav i{font-size:12px}.sia-steps-content{flex:1;overflow:hidden;min-width:0}.sia-steps-content.has-overflow-left{mask-image:linear-gradient(to right,transparent 0%,black 5%)}.sia-steps-content.has-overflow-right{mask-image:linear-gradient(to left,transparent 0%,black 5%)}.sia-steps-content.has-overflow-left.has-overflow-right{mask-image:linear-gradient(to right,transparent 0%,black 5%,black 95%,transparent 100%)}.sia-steps-list{display:flex;align-items:center;justify-content:center;padding:8px 4px}.sia-step-connector{flex:0 0 auto;width:32px;display:flex;align-items:center;justify-content:center}.sia-step-connector .connector-line{width:100%;height:2px;background:var(--p-surface-300, #cbd5e1);border-radius:1px;transition:background .3s ease}.sia-step-connector.completed .connector-line{background:var(--p-primary-400, #60a5fa)}.sia-step-item{display:flex;flex-direction:column;align-items:center;gap:6px;padding:8px 12px;border-radius:10px;transition:all .25s ease;min-width:80px;max-width:160px;position:relative}.sia-step-item.clickable{cursor:pointer}.sia-step-item.clickable:hover{background:var(--p-surface-50, #f8fafc);transform:translateY(-1px)}.sia-step-item.disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.sia-step-item.pending .sia-step-marker{background:var(--p-surface-100, #f1f5f9);border-color:var(--p-surface-300, #cbd5e1);color:var(--p-text-secondary-color, #64748b)}.sia-step-item.pending .sia-step-label .label-text{color:var(--p-text-secondary-color, #64748b)}.sia-step-item.active .sia-step-marker{background:var(--p-primary-500, #3b82f6);border-color:var(--p-primary-500, #3b82f6);color:#fff;box-shadow:0 0 0 4px var(--p-primary-100, #dbeafe);transform:scale(1.1)}.sia-step-item.active .sia-step-label .label-text{color:var(--p-primary-700, #1d4ed8);font-weight:600}.sia-step-item.completed .sia-step-marker{background:var(--p-primary-100, #dbeafe);border-color:var(--p-primary-300, #93c5fd);color:var(--p-primary-600, #2563eb)}.sia-step-item.completed .sia-step-label .label-text{color:var(--p-text-color, #1e293b)}.sia-step-marker{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;border:2px solid;font-size:13px;font-weight:600;transition:all .3s ease;flex-shrink:0}.sia-step-marker i{font-size:14px}.sia-step-label{text-align:center;max-width:100%;overflow:hidden}.sia-step-label .label-text{display:block;font-size:12px;font-weight:500;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--p-text-secondary-color, #64748b);transition:color .2s ease,font-weight .2s ease}.sia-steps-wrapper.animated .sia-steps-list{transition:transform .3s ease}.sia-steps-wrapper.animated .sia-step-item{animation:stepFadeIn .25s ease forwards}@keyframes stepFadeIn{0%{opacity:.6;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.sia-steps-wrapper.theme-success .sia-step-connector.completed .connector-line{background:var(--p-green-400, #4ade80)}.sia-steps-wrapper.theme-success .sia-step-item.active .sia-step-marker{background:var(--p-green-500, #22c55e);border-color:var(--p-green-500, #22c55e);box-shadow:0 0 0 4px var(--p-green-100, #dcfce7)}.sia-steps-wrapper.theme-success .sia-step-item.active .sia-step-label .label-text{color:var(--p-green-700, #15803d)}.sia-steps-wrapper.theme-success .sia-step-item.completed .sia-step-marker{background:var(--p-green-100, #dcfce7);border-color:var(--p-green-300, #86efac);color:var(--p-green-600, #16a34a)}.sia-steps-wrapper.theme-danger .sia-step-connector.completed .connector-line{background:var(--p-red-400, #f87171)}.sia-steps-wrapper.theme-danger .sia-step-item.active .sia-step-marker{background:var(--p-red-500, #ef4444);border-color:var(--p-red-500, #ef4444);box-shadow:0 0 0 4px var(--p-red-100, #fee2e2)}.sia-steps-wrapper.theme-danger .sia-step-item.active .sia-step-label .label-text{color:var(--p-red-700, #b91c1c)}.sia-steps-wrapper.theme-danger .sia-step-item.completed .sia-step-marker{background:var(--p-red-100, #fee2e2);border-color:var(--p-red-300, #fca5a5);color:var(--p-red-600, #dc2626)}.sia-steps-wrapper.theme-warning .sia-step-connector.completed .connector-line{background:var(--p-orange-400, #fb923c)}.sia-steps-wrapper.theme-warning .sia-step-item.active .sia-step-marker{background:var(--p-orange-500, #f97316);border-color:var(--p-orange-500, #f97316);box-shadow:0 0 0 4px var(--p-orange-100, #ffedd5)}.sia-steps-wrapper.theme-warning .sia-step-item.active .sia-step-label .label-text{color:var(--p-orange-700, #c2410c)}.sia-steps-wrapper.theme-warning .sia-step-item.completed .sia-step-marker{background:var(--p-orange-100, #ffedd5);border-color:var(--p-orange-300, #fdba74);color:var(--p-orange-600, #ea580c)}.sia-steps-wrapper.theme-info .sia-step-connector.completed .connector-line{background:var(--p-cyan-400, #22d3ee)}.sia-steps-wrapper.theme-info .sia-step-item.active .sia-step-marker{background:var(--p-cyan-500, #06b6d4);border-color:var(--p-cyan-500, #06b6d4);box-shadow:0 0 0 4px var(--p-cyan-100, #cffafe)}.sia-steps-wrapper.theme-info .sia-step-item.active .sia-step-label .label-text{color:var(--p-cyan-700, #0e7490)}.sia-steps-wrapper.theme-info .sia-step-item.completed .sia-step-marker{background:var(--p-cyan-100, #cffafe);border-color:var(--p-cyan-300, #67e8f9);color:var(--p-cyan-600, #0891b2)}@media (max-width: 576px){.sia-step-item{min-width:60px;max-width:100px;padding:6px 8px}.sia-step-marker{width:30px;height:30px;font-size:11px}.sia-step-marker i{font-size:12px}.sia-step-label .label-text{font-size:11px}.sia-step-connector{width:20px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3686
3686
|
}
|
|
3687
3687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StepsComponent, decorators: [{
|
|
3688
3688
|
type: Component,
|
|
@@ -4326,6 +4326,13 @@ const DATE_MASK_CONFIGS = {
|
|
|
4326
4326
|
'en-US': { mask: '99/99/9999', placeholder: 'mm/dd/yyyy', format: 'mdy' },
|
|
4327
4327
|
'es-ES': { mask: '99/99/9999', placeholder: 'dd/mm/aaaa', format: 'dmy' }
|
|
4328
4328
|
};
|
|
4329
|
+
/**
|
|
4330
|
+
* DynamicFieldDateComponent
|
|
4331
|
+
*
|
|
4332
|
+
* O FormControl.value SEMPRE armazena a data no formato ISO: "yyyy-MM-dd" (ex: "2026-05-18").
|
|
4333
|
+
* A variável `displayValue` mantém o valor formatado no locale do usuário para exibição no input.
|
|
4334
|
+
* Isso garante que qualquer componente que acesse form.value receba o valor pronto para o backend.
|
|
4335
|
+
*/
|
|
4329
4336
|
class DynamicFieldDateComponent extends DynamicFieldBaseComponent {
|
|
4330
4337
|
localeService;
|
|
4331
4338
|
cdr;
|
|
@@ -4333,9 +4340,14 @@ class DynamicFieldDateComponent extends DynamicFieldBaseComponent {
|
|
|
4333
4340
|
currentDateFormat = 'dd/mm/yy';
|
|
4334
4341
|
dateMask = '99/99/9999';
|
|
4335
4342
|
calendarValue = null;
|
|
4343
|
+
/** Valor de exibição no formato locale (ex: "18/05/2026" para pt-BR) */
|
|
4344
|
+
displayValue = null;
|
|
4345
|
+
/** Controla a renderização do p-calendar (só existe no DOM quando necessário) */
|
|
4346
|
+
showCalendar = false;
|
|
4336
4347
|
langSub;
|
|
4337
4348
|
valueSub;
|
|
4338
4349
|
currentLocale = 'pt-BR';
|
|
4350
|
+
updatingFromControl = false;
|
|
4339
4351
|
constructor(translationService, localeService, cdr) {
|
|
4340
4352
|
super(translationService);
|
|
4341
4353
|
this.localeService = localeService;
|
|
@@ -4344,71 +4356,163 @@ class DynamicFieldDateComponent extends DynamicFieldBaseComponent {
|
|
|
4344
4356
|
ngOnInit() {
|
|
4345
4357
|
this.currentLocale = this.translationService.getCurrentLanguage();
|
|
4346
4358
|
this.updateDateFormat();
|
|
4347
|
-
this.initializeValue();
|
|
4348
|
-
this.langSub = this.translationService.currentLanguage$.subscribe((lang) => {
|
|
4349
|
-
this.currentLocale = lang;
|
|
4350
|
-
this.updateDateFormat();
|
|
4351
|
-
this.convertValueToNewLocale();
|
|
4352
|
-
});
|
|
4353
4359
|
const control = this.form.get(this.field.field);
|
|
4354
4360
|
if (control) {
|
|
4361
|
+
// Inicializar displayValue a partir do valor ISO do control
|
|
4362
|
+
this.syncDisplayFromControl(control.value);
|
|
4363
|
+
// Observar mudanças externas no control (patchValue, setValue)
|
|
4355
4364
|
this.valueSub = control.valueChanges.subscribe(value => {
|
|
4356
|
-
if (
|
|
4357
|
-
|
|
4365
|
+
if (this.updatingFromControl) {
|
|
4366
|
+
return;
|
|
4358
4367
|
}
|
|
4368
|
+
this.syncDisplayFromControl(value);
|
|
4359
4369
|
});
|
|
4360
4370
|
}
|
|
4371
|
+
this.langSub = this.translationService.currentLanguage$.subscribe((lang) => {
|
|
4372
|
+
this.currentLocale = lang;
|
|
4373
|
+
this.updateDateFormat();
|
|
4374
|
+
// Re-formatar o display com o novo locale
|
|
4375
|
+
const ctrl = this.form.get(this.field.field);
|
|
4376
|
+
if (ctrl) {
|
|
4377
|
+
this.syncDisplayFromControl(ctrl.value);
|
|
4378
|
+
}
|
|
4379
|
+
});
|
|
4361
4380
|
}
|
|
4362
4381
|
ngOnDestroy() {
|
|
4363
4382
|
this.langSub?.unsubscribe();
|
|
4364
4383
|
this.valueSub?.unsubscribe();
|
|
4365
4384
|
}
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4385
|
+
/**
|
|
4386
|
+
* Sincroniza o displayValue a partir do valor ISO do FormControl.
|
|
4387
|
+
* Aceita: "yyyy-MM-dd", Date, locale string "dd/MM/yyyy", ou null.
|
|
4388
|
+
*/
|
|
4389
|
+
syncDisplayFromControl(value) {
|
|
4390
|
+
if (!value) {
|
|
4391
|
+
this.displayValue = null;
|
|
4392
|
+
return;
|
|
4393
|
+
}
|
|
4394
|
+
if (value instanceof Date) {
|
|
4395
|
+
// Converte Date para ISO no control e atualiza display
|
|
4396
|
+
const iso = this.dateToIso(value);
|
|
4397
|
+
this.setControlValue(iso);
|
|
4398
|
+
this.displayValue = this.isoToLocale(iso);
|
|
4399
|
+
return;
|
|
4400
|
+
}
|
|
4401
|
+
const s = String(value);
|
|
4402
|
+
// Já está em formato ISO (yyyy-MM-dd)
|
|
4403
|
+
if (s.match(/^\d{4}-\d{2}-\d{2}/)) {
|
|
4404
|
+
const isoDate = s.substring(0, 10);
|
|
4405
|
+
this.displayValue = this.isoToLocale(isoDate);
|
|
4406
|
+
return;
|
|
4370
4407
|
}
|
|
4408
|
+
// Está em formato locale (dd/MM/yyyy ou MM/dd/yyyy)
|
|
4409
|
+
if (s.match(/^\d{2}\/\d{2}\/\d{4}$/)) {
|
|
4410
|
+
const iso = this.localeToIso(s);
|
|
4411
|
+
if (iso) {
|
|
4412
|
+
this.setControlValue(iso);
|
|
4413
|
+
this.displayValue = s;
|
|
4414
|
+
}
|
|
4415
|
+
else {
|
|
4416
|
+
this.displayValue = s;
|
|
4417
|
+
}
|
|
4418
|
+
return;
|
|
4419
|
+
}
|
|
4420
|
+
// Valor incompleto ou com máscara
|
|
4421
|
+
this.displayValue = s.includes('_') ? null : null;
|
|
4371
4422
|
}
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
this.
|
|
4375
|
-
this.currentDateFormat = this.field?.dateFormat || this.localeService.getPrimeNGDateFormat();
|
|
4423
|
+
/** Chamado quando o usuário completa a digitação da máscara */
|
|
4424
|
+
onDisplayValueComplete() {
|
|
4425
|
+
this.syncControlFromDisplay();
|
|
4376
4426
|
}
|
|
4377
|
-
|
|
4427
|
+
/** Chamado quando o input perde foco */
|
|
4428
|
+
onDisplayValueBlur() {
|
|
4429
|
+
this.syncControlFromDisplay();
|
|
4430
|
+
}
|
|
4431
|
+
/**
|
|
4432
|
+
* Converte o displayValue (locale) para ISO e seta no FormControl.
|
|
4433
|
+
*/
|
|
4434
|
+
syncControlFromDisplay() {
|
|
4378
4435
|
const control = this.form.get(this.field.field);
|
|
4379
|
-
if (
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4436
|
+
if (!control) {
|
|
4437
|
+
return;
|
|
4438
|
+
}
|
|
4439
|
+
if (!this.displayValue || this.displayValue.includes('_')) {
|
|
4440
|
+
this.setControlValue(null);
|
|
4441
|
+
control.markAsDirty();
|
|
4442
|
+
return;
|
|
4443
|
+
}
|
|
4444
|
+
const iso = this.localeToIso(this.displayValue);
|
|
4445
|
+
if (iso) {
|
|
4446
|
+
this.setControlValue(iso);
|
|
4447
|
+
control.markAsDirty();
|
|
4384
4448
|
}
|
|
4385
4449
|
}
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
const
|
|
4389
|
-
|
|
4450
|
+
/** Seta o valor no control sem disparar o subscriber interno */
|
|
4451
|
+
setControlValue(value) {
|
|
4452
|
+
const control = this.form.get(this.field.field);
|
|
4453
|
+
if (!control) {
|
|
4454
|
+
return;
|
|
4455
|
+
}
|
|
4456
|
+
this.updatingFromControl = true;
|
|
4457
|
+
control.setValue(value, { emitEvent: true });
|
|
4458
|
+
this.updatingFromControl = false;
|
|
4459
|
+
}
|
|
4460
|
+
// ==================== CONVERSÕES ====================
|
|
4461
|
+
/** Converte ISO "yyyy-MM-dd" para locale string */
|
|
4462
|
+
isoToLocale(iso) {
|
|
4463
|
+
const [year, month, day] = iso.split('-');
|
|
4390
4464
|
const config = DATE_MASK_CONFIGS[this.currentLocale] || DATE_MASK_CONFIGS['pt-BR'];
|
|
4391
4465
|
return config.format === 'mdy' ? `${month}/${day}/${year}` : `${day}/${month}/${year}`;
|
|
4392
4466
|
}
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
if (parts.length !== 3)
|
|
4467
|
+
/** Converte locale string para ISO "yyyy-MM-dd" */
|
|
4468
|
+
localeToIso(locale) {
|
|
4469
|
+
const parts = locale.split('/');
|
|
4470
|
+
if (parts.length !== 3) {
|
|
4398
4471
|
return null;
|
|
4472
|
+
}
|
|
4399
4473
|
const config = DATE_MASK_CONFIGS[this.currentLocale] || DATE_MASK_CONFIGS['pt-BR'];
|
|
4400
|
-
const [p0, p1, p2] = parts
|
|
4474
|
+
const [p0, p1, p2] = parts;
|
|
4401
4475
|
const [day, month, year] = config.format === 'mdy' ? [p1, p0, p2] : [p0, p1, p2];
|
|
4402
|
-
|
|
4476
|
+
const d = parseInt(day, 10);
|
|
4477
|
+
const m = parseInt(month, 10);
|
|
4478
|
+
const y = parseInt(year, 10);
|
|
4479
|
+
if (isNaN(d) || isNaN(m) || isNaN(y) || m < 1 || m > 12 || d < 1 || d > 31) {
|
|
4480
|
+
return null;
|
|
4481
|
+
}
|
|
4482
|
+
return `${year}-${month}-${day}`;
|
|
4483
|
+
}
|
|
4484
|
+
/** Converte Date para ISO "yyyy-MM-dd" */
|
|
4485
|
+
dateToIso(date) {
|
|
4486
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
4487
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
4488
|
+
const year = String(date.getFullYear());
|
|
4489
|
+
return `${year}-${month}-${day}`;
|
|
4490
|
+
}
|
|
4491
|
+
/** Converte locale string para Date */
|
|
4492
|
+
localeToDate(value) {
|
|
4493
|
+
const iso = this.localeToIso(value);
|
|
4494
|
+
if (!iso) {
|
|
4403
4495
|
return null;
|
|
4496
|
+
}
|
|
4497
|
+
const [year, month, day] = iso.split('-').map(p => parseInt(p, 10));
|
|
4404
4498
|
const date = new Date(year, month - 1, day);
|
|
4405
4499
|
return isNaN(date.getTime()) ? null : date;
|
|
4406
4500
|
}
|
|
4501
|
+
// ==================== CALENDAR ====================
|
|
4502
|
+
updateDateFormat() {
|
|
4503
|
+
const config = DATE_MASK_CONFIGS[this.currentLocale] || DATE_MASK_CONFIGS['pt-BR'];
|
|
4504
|
+
this.dateMask = config.mask;
|
|
4505
|
+
this.currentDateFormat = this.field?.dateFormat || this.localeService.getPrimeNGDateFormat();
|
|
4506
|
+
}
|
|
4407
4507
|
toggleCalendar(event) {
|
|
4408
4508
|
event.stopPropagation();
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4509
|
+
if (this.displayValue && !this.displayValue.includes('_')) {
|
|
4510
|
+
this.calendarValue = this.localeToDate(this.displayValue);
|
|
4511
|
+
}
|
|
4512
|
+
else {
|
|
4513
|
+
this.calendarValue = new Date();
|
|
4514
|
+
}
|
|
4515
|
+
this.showCalendar = true;
|
|
4412
4516
|
setTimeout(() => {
|
|
4413
4517
|
if (this.calendarPicker && this.calendarPicker.inputfieldViewChild) {
|
|
4414
4518
|
this.calendarPicker.inputfieldViewChild.nativeElement.click();
|
|
@@ -4416,39 +4520,53 @@ class DynamicFieldDateComponent extends DynamicFieldBaseComponent {
|
|
|
4416
4520
|
});
|
|
4417
4521
|
}
|
|
4418
4522
|
onCalendarSelect(date) {
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4523
|
+
if (date) {
|
|
4524
|
+
const iso = this.dateToIso(date);
|
|
4525
|
+
this.displayValue = this.isoToLocale(iso);
|
|
4526
|
+
this.setControlValue(iso);
|
|
4527
|
+
const control = this.form.get(this.field.field);
|
|
4528
|
+
if (control) {
|
|
4529
|
+
control.markAsDirty();
|
|
4530
|
+
}
|
|
4423
4531
|
}
|
|
4424
4532
|
}
|
|
4425
4533
|
onCalendarClear() {
|
|
4534
|
+
this.displayValue = null;
|
|
4535
|
+
this.setControlValue(null);
|
|
4426
4536
|
const control = this.form.get(this.field.field);
|
|
4427
4537
|
if (control) {
|
|
4428
|
-
control.setValue(null);
|
|
4429
4538
|
control.markAsDirty();
|
|
4430
4539
|
}
|
|
4431
4540
|
}
|
|
4541
|
+
isControlDisabled() {
|
|
4542
|
+
const control = this.form.get(this.field.field);
|
|
4543
|
+
return control ? control.disabled : false;
|
|
4544
|
+
}
|
|
4432
4545
|
getPlaceholder() {
|
|
4433
|
-
if (this.field.placeholder)
|
|
4546
|
+
if (this.field.placeholder) {
|
|
4434
4547
|
return this.field.placeholder;
|
|
4548
|
+
}
|
|
4435
4549
|
return DATE_MASK_CONFIGS[this.currentLocale]?.placeholder || 'dd/mm/aaaa';
|
|
4436
4550
|
}
|
|
4437
4551
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldDateComponent, deps: [{ token: TranslationService }, { token: LocaleService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4438
4552
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFieldDateComponent, isStandalone: true, selector: "sia-dynamic-field-date", viewQueries: [{ propertyName: "calendarPicker", first: true, predicate: ["calendarPicker"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
4439
4553
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
4440
|
-
<div
|
|
4554
|
+
<div class="date-field">
|
|
4441
4555
|
<div class="date-input-group">
|
|
4442
4556
|
<p-inputmask
|
|
4443
4557
|
[inputId]="field.field"
|
|
4444
|
-
[
|
|
4558
|
+
[(ngModel)]="displayValue"
|
|
4559
|
+
[ngModelOptions]="{standalone: true}"
|
|
4445
4560
|
[mask]="dateMask"
|
|
4446
4561
|
[placeholder]="getPlaceholder()"
|
|
4447
4562
|
slotChar="_"
|
|
4448
4563
|
[autoClear]="false"
|
|
4449
4564
|
styleClass="date-input"
|
|
4450
4565
|
[class.ng-invalid]="isFieldInvalid()"
|
|
4451
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
4566
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
4567
|
+
[disabled]="isControlDisabled()"
|
|
4568
|
+
(onComplete)="onDisplayValueComplete()"
|
|
4569
|
+
(onBlur)="onDisplayValueBlur()">
|
|
4452
4570
|
</p-inputmask>
|
|
4453
4571
|
<div class="date-buttons">
|
|
4454
4572
|
<p-button
|
|
@@ -4462,28 +4580,31 @@ class DynamicFieldDateComponent extends DynamicFieldBaseComponent {
|
|
|
4462
4580
|
size="small">
|
|
4463
4581
|
</p-button>
|
|
4464
4582
|
</div>
|
|
4583
|
+
<p-calendar
|
|
4584
|
+
*ngIf="showCalendar"
|
|
4585
|
+
#calendarPicker
|
|
4586
|
+
[(ngModel)]="calendarValue"
|
|
4587
|
+
[ngModelOptions]="{standalone: true}"
|
|
4588
|
+
[dateFormat]="currentDateFormat"
|
|
4589
|
+
[showButtonBar]="true"
|
|
4590
|
+
[appendTo]="'body'"
|
|
4591
|
+
[inline]="false"
|
|
4592
|
+
[showIcon]="false"
|
|
4593
|
+
(onSelect)="onCalendarSelect($event)"
|
|
4594
|
+
(onClearClick)="onCalendarClear()"
|
|
4595
|
+
(onHide)="showCalendar = false"
|
|
4596
|
+
styleClass="hidden-calendar-input"
|
|
4597
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
4598
|
+
</p-calendar>
|
|
4465
4599
|
</div>
|
|
4466
|
-
<p-calendar
|
|
4467
|
-
#calendarPicker
|
|
4468
|
-
[(ngModel)]="calendarValue"
|
|
4469
|
-
[dateFormat]="currentDateFormat"
|
|
4470
|
-
[showButtonBar]="true"
|
|
4471
|
-
[appendTo]="'body'"
|
|
4472
|
-
[inline]="false"
|
|
4473
|
-
[showIcon]="false"
|
|
4474
|
-
(onSelect)="onCalendarSelect($event)"
|
|
4475
|
-
(onClearClick)="onCalendarClear()"
|
|
4476
|
-
styleClass="hidden-calendar-input">
|
|
4477
|
-
</p-calendar>
|
|
4478
4600
|
</div>
|
|
4479
4601
|
</sia-dynamic-field-wrapper>
|
|
4480
|
-
`, isInline: true, styles: [".date-field{width:100%;position:relative}.date-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.date-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
4602
|
+
`, isInline: true, styles: [".date-field{width:100%;position:relative}.date-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.date-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "component", type: i5$1.InputMask, selector: "p-inputmask, p-inputMask, p-input-mask", inputs: ["type", "slotChar", "autoClear", "showClear", "style", "inputId", "styleClass", "placeholder", "size", "maxlength", "tabindex", "title", "variant", "ariaLabel", "ariaLabelledBy", "ariaRequired", "disabled", "readonly", "unmask", "name", "required", "characterPattern", "autofocus", "autoFocus", "autocomplete", "keepBuffer", "mask"], outputs: ["onComplete", "onFocus", "onBlur", "onInput", "onKeydown", "onClear"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "component", type: i6$1.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "fluid", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DynamicFieldWrapperComponent, selector: "sia-dynamic-field-wrapper", inputs: ["field", "form", "mode"] }] });
|
|
4481
4603
|
}
|
|
4482
4604
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldDateComponent, decorators: [{
|
|
4483
4605
|
type: Component,
|
|
4484
4606
|
args: [{ selector: 'sia-dynamic-field-date', standalone: true, imports: [
|
|
4485
4607
|
CommonModule,
|
|
4486
|
-
ReactiveFormsModule,
|
|
4487
4608
|
FormsModule,
|
|
4488
4609
|
InputMaskModule,
|
|
4489
4610
|
CalendarModule,
|
|
@@ -4492,18 +4613,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4492
4613
|
DynamicFieldWrapperComponent
|
|
4493
4614
|
], template: `
|
|
4494
4615
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
4495
|
-
<div
|
|
4616
|
+
<div class="date-field">
|
|
4496
4617
|
<div class="date-input-group">
|
|
4497
4618
|
<p-inputmask
|
|
4498
4619
|
[inputId]="field.field"
|
|
4499
|
-
[
|
|
4620
|
+
[(ngModel)]="displayValue"
|
|
4621
|
+
[ngModelOptions]="{standalone: true}"
|
|
4500
4622
|
[mask]="dateMask"
|
|
4501
4623
|
[placeholder]="getPlaceholder()"
|
|
4502
4624
|
slotChar="_"
|
|
4503
4625
|
[autoClear]="false"
|
|
4504
4626
|
styleClass="date-input"
|
|
4505
4627
|
[class.ng-invalid]="isFieldInvalid()"
|
|
4506
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
4628
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
4629
|
+
[disabled]="isControlDisabled()"
|
|
4630
|
+
(onComplete)="onDisplayValueComplete()"
|
|
4631
|
+
(onBlur)="onDisplayValueBlur()">
|
|
4507
4632
|
</p-inputmask>
|
|
4508
4633
|
<div class="date-buttons">
|
|
4509
4634
|
<p-button
|
|
@@ -4517,22 +4642,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4517
4642
|
size="small">
|
|
4518
4643
|
</p-button>
|
|
4519
4644
|
</div>
|
|
4645
|
+
<p-calendar
|
|
4646
|
+
*ngIf="showCalendar"
|
|
4647
|
+
#calendarPicker
|
|
4648
|
+
[(ngModel)]="calendarValue"
|
|
4649
|
+
[ngModelOptions]="{standalone: true}"
|
|
4650
|
+
[dateFormat]="currentDateFormat"
|
|
4651
|
+
[showButtonBar]="true"
|
|
4652
|
+
[appendTo]="'body'"
|
|
4653
|
+
[inline]="false"
|
|
4654
|
+
[showIcon]="false"
|
|
4655
|
+
(onSelect)="onCalendarSelect($event)"
|
|
4656
|
+
(onClearClick)="onCalendarClear()"
|
|
4657
|
+
(onHide)="showCalendar = false"
|
|
4658
|
+
styleClass="hidden-calendar-input"
|
|
4659
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
4660
|
+
</p-calendar>
|
|
4520
4661
|
</div>
|
|
4521
|
-
<p-calendar
|
|
4522
|
-
#calendarPicker
|
|
4523
|
-
[(ngModel)]="calendarValue"
|
|
4524
|
-
[dateFormat]="currentDateFormat"
|
|
4525
|
-
[showButtonBar]="true"
|
|
4526
|
-
[appendTo]="'body'"
|
|
4527
|
-
[inline]="false"
|
|
4528
|
-
[showIcon]="false"
|
|
4529
|
-
(onSelect)="onCalendarSelect($event)"
|
|
4530
|
-
(onClearClick)="onCalendarClear()"
|
|
4531
|
-
styleClass="hidden-calendar-input">
|
|
4532
|
-
</p-calendar>
|
|
4533
4662
|
</div>
|
|
4534
4663
|
</sia-dynamic-field-wrapper>
|
|
4535
|
-
`, styles: [".date-field{width:100%;position:relative}.date-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.date-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
4664
|
+
`, styles: [".date-field{width:100%;position:relative}.date-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.date-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"] }]
|
|
4536
4665
|
}], ctorParameters: () => [{ type: TranslationService }, { type: LocaleService }, { type: i0.ChangeDetectorRef }], propDecorators: { calendarPicker: [{
|
|
4537
4666
|
type: ViewChild,
|
|
4538
4667
|
args: ['calendarPicker']
|
|
@@ -4543,6 +4672,13 @@ const DATETIME_MASK_CONFIGS = {
|
|
|
4543
4672
|
'en-US': { mask: '99/99/9999 99:99', placeholder: 'mm/dd/yyyy HH:mm', format: 'mdy' },
|
|
4544
4673
|
'es-ES': { mask: '99/99/9999 99:99', placeholder: 'dd/mm/aaaa HH:mm', format: 'dmy' }
|
|
4545
4674
|
};
|
|
4675
|
+
/**
|
|
4676
|
+
* DynamicFieldDatetimeComponent
|
|
4677
|
+
*
|
|
4678
|
+
* O FormControl.value SEMPRE armazena o datetime no formato ISO: "yyyy-MM-ddTHH:mm:ss.sssZ".
|
|
4679
|
+
* A variável `displayValue` mantém o valor formatado no locale do usuário para exibição no input.
|
|
4680
|
+
* Isso garante que qualquer componente que acesse form.value receba o valor pronto para o backend.
|
|
4681
|
+
*/
|
|
4546
4682
|
class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
4547
4683
|
localeService;
|
|
4548
4684
|
cdr;
|
|
@@ -4550,9 +4686,14 @@ class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
|
4550
4686
|
currentDateFormat = 'dd/mm/yy';
|
|
4551
4687
|
datetimeMask = '99/99/9999 99:99';
|
|
4552
4688
|
calendarValue = null;
|
|
4689
|
+
/** Valor de exibição no formato locale (ex: "18/05/2026 14:30" para pt-BR) */
|
|
4690
|
+
displayValue = null;
|
|
4691
|
+
/** Controla a renderização do p-calendar (só existe no DOM quando necessário) */
|
|
4692
|
+
showCalendar = false;
|
|
4553
4693
|
langSub;
|
|
4554
4694
|
valueSub;
|
|
4555
4695
|
currentLocale = 'pt-BR';
|
|
4696
|
+
updatingFromControl = false;
|
|
4556
4697
|
constructor(translationService, localeService, cdr) {
|
|
4557
4698
|
super(translationService);
|
|
4558
4699
|
this.localeService = localeService;
|
|
@@ -4561,46 +4702,111 @@ class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
|
4561
4702
|
ngOnInit() {
|
|
4562
4703
|
this.currentLocale = this.translationService.getCurrentLanguage();
|
|
4563
4704
|
this.updateDatetimeFormat();
|
|
4564
|
-
this.initializeValue();
|
|
4565
|
-
this.langSub = this.translationService.currentLanguage$.subscribe((lang) => {
|
|
4566
|
-
this.currentLocale = lang;
|
|
4567
|
-
this.updateDatetimeFormat();
|
|
4568
|
-
this.convertValueToNewLocale();
|
|
4569
|
-
});
|
|
4570
4705
|
const control = this.form.get(this.field.field);
|
|
4571
4706
|
if (control) {
|
|
4707
|
+
// Inicializar displayValue a partir do valor ISO do control
|
|
4708
|
+
this.syncDisplayFromControl(control.value);
|
|
4709
|
+
// Observar mudanças externas no control (patchValue, setValue)
|
|
4572
4710
|
this.valueSub = control.valueChanges.subscribe(value => {
|
|
4573
|
-
if (
|
|
4574
|
-
|
|
4711
|
+
if (this.updatingFromControl) {
|
|
4712
|
+
return;
|
|
4575
4713
|
}
|
|
4714
|
+
this.syncDisplayFromControl(value);
|
|
4576
4715
|
});
|
|
4577
4716
|
}
|
|
4717
|
+
this.langSub = this.translationService.currentLanguage$.subscribe((lang) => {
|
|
4718
|
+
this.currentLocale = lang;
|
|
4719
|
+
this.updateDatetimeFormat();
|
|
4720
|
+
// Re-formatar o display com o novo locale
|
|
4721
|
+
const ctrl = this.form.get(this.field.field);
|
|
4722
|
+
if (ctrl) {
|
|
4723
|
+
this.syncDisplayFromControl(ctrl.value);
|
|
4724
|
+
}
|
|
4725
|
+
});
|
|
4578
4726
|
}
|
|
4579
4727
|
ngOnDestroy() {
|
|
4580
4728
|
this.langSub?.unsubscribe();
|
|
4581
4729
|
this.valueSub?.unsubscribe();
|
|
4582
4730
|
}
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4731
|
+
/**
|
|
4732
|
+
* Sincroniza o displayValue a partir do valor ISO do FormControl.
|
|
4733
|
+
* Aceita: ISO string, Date, locale string, ou null.
|
|
4734
|
+
*/
|
|
4735
|
+
syncDisplayFromControl(value) {
|
|
4736
|
+
if (!value) {
|
|
4737
|
+
this.displayValue = null;
|
|
4738
|
+
return;
|
|
4587
4739
|
}
|
|
4740
|
+
if (value instanceof Date) {
|
|
4741
|
+
const iso = value.toISOString();
|
|
4742
|
+
this.setControlValue(iso);
|
|
4743
|
+
this.displayValue = this.isoToLocale(value);
|
|
4744
|
+
return;
|
|
4745
|
+
}
|
|
4746
|
+
const s = String(value);
|
|
4747
|
+
// ISO datetime string (contém T)
|
|
4748
|
+
if (s.includes('T')) {
|
|
4749
|
+
const d = new Date(s);
|
|
4750
|
+
if (!isNaN(d.getTime())) {
|
|
4751
|
+
this.displayValue = this.isoToLocale(d);
|
|
4752
|
+
}
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
// Formato locale "dd/MM/yyyy HH:mm" ou "MM/dd/yyyy HH:mm"
|
|
4756
|
+
if (s.match(/^\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}$/)) {
|
|
4757
|
+
const iso = this.localeToIso(s);
|
|
4758
|
+
if (iso) {
|
|
4759
|
+
this.setControlValue(iso);
|
|
4760
|
+
this.displayValue = s;
|
|
4761
|
+
}
|
|
4762
|
+
else {
|
|
4763
|
+
this.displayValue = s;
|
|
4764
|
+
}
|
|
4765
|
+
return;
|
|
4766
|
+
}
|
|
4767
|
+
// Valor incompleto
|
|
4768
|
+
this.displayValue = s.includes('_') ? null : null;
|
|
4588
4769
|
}
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
this.
|
|
4592
|
-
this.currentDateFormat = this.field?.dateFormat || this.localeService.getPrimeNGDateFormat();
|
|
4770
|
+
/** Chamado quando o usuário completa a digitação da máscara */
|
|
4771
|
+
onDisplayValueComplete() {
|
|
4772
|
+
this.syncControlFromDisplay();
|
|
4593
4773
|
}
|
|
4594
|
-
|
|
4774
|
+
/** Chamado quando o input perde foco */
|
|
4775
|
+
onDisplayValueBlur() {
|
|
4776
|
+
this.syncControlFromDisplay();
|
|
4777
|
+
}
|
|
4778
|
+
/**
|
|
4779
|
+
* Converte o displayValue (locale) para ISO e seta no FormControl.
|
|
4780
|
+
*/
|
|
4781
|
+
syncControlFromDisplay() {
|
|
4595
4782
|
const control = this.form.get(this.field.field);
|
|
4596
|
-
if (
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4783
|
+
if (!control) {
|
|
4784
|
+
return;
|
|
4785
|
+
}
|
|
4786
|
+
if (!this.displayValue || this.displayValue.includes('_')) {
|
|
4787
|
+
this.setControlValue(null);
|
|
4788
|
+
control.markAsDirty();
|
|
4789
|
+
return;
|
|
4790
|
+
}
|
|
4791
|
+
const iso = this.localeToIso(this.displayValue);
|
|
4792
|
+
if (iso) {
|
|
4793
|
+
this.setControlValue(iso);
|
|
4794
|
+
control.markAsDirty();
|
|
4601
4795
|
}
|
|
4602
4796
|
}
|
|
4603
|
-
|
|
4797
|
+
/** Seta o valor no control sem disparar o subscriber interno */
|
|
4798
|
+
setControlValue(value) {
|
|
4799
|
+
const control = this.form.get(this.field.field);
|
|
4800
|
+
if (!control) {
|
|
4801
|
+
return;
|
|
4802
|
+
}
|
|
4803
|
+
this.updatingFromControl = true;
|
|
4804
|
+
control.setValue(value, { emitEvent: true });
|
|
4805
|
+
this.updatingFromControl = false;
|
|
4806
|
+
}
|
|
4807
|
+
// ==================== CONVERSÕES ====================
|
|
4808
|
+
/** Converte Date para locale display string */
|
|
4809
|
+
isoToLocale(date) {
|
|
4604
4810
|
const day = String(date.getDate()).padStart(2, '0');
|
|
4605
4811
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
4606
4812
|
const year = String(date.getFullYear());
|
|
@@ -4611,33 +4817,54 @@ class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
|
4611
4817
|
? `${month}/${day}/${year} ${hours}:${minutes}`
|
|
4612
4818
|
: `${day}/${month}/${year} ${hours}:${minutes}`;
|
|
4613
4819
|
}
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
if (parts.length !== 2)
|
|
4820
|
+
/** Converte locale string para ISO datetime string */
|
|
4821
|
+
localeToIso(locale) {
|
|
4822
|
+
const parts = locale.split(' ');
|
|
4823
|
+
if (parts.length !== 2) {
|
|
4619
4824
|
return null;
|
|
4825
|
+
}
|
|
4620
4826
|
const dateParts = parts[0].split('/');
|
|
4621
4827
|
const timeParts = parts[1].split(':');
|
|
4622
|
-
if (dateParts.length !== 3 || timeParts.length !== 2)
|
|
4828
|
+
if (dateParts.length !== 3 || timeParts.length !== 2) {
|
|
4623
4829
|
return null;
|
|
4830
|
+
}
|
|
4624
4831
|
const config = DATETIME_MASK_CONFIGS[this.currentLocale] || DATETIME_MASK_CONFIGS['pt-BR'];
|
|
4625
4832
|
const [p0, p1, p2] = dateParts.map(p => parseInt(p, 10));
|
|
4626
4833
|
const [day, month, year] = config.format === 'mdy' ? [p1, p0, p2] : [p0, p1, p2];
|
|
4627
4834
|
const hours = parseInt(timeParts[0], 10);
|
|
4628
4835
|
const minutes = parseInt(timeParts[1], 10);
|
|
4629
|
-
if (isNaN(day) || isNaN(month) || isNaN(year) || isNaN(hours) || isNaN(minutes))
|
|
4836
|
+
if (isNaN(day) || isNaN(month) || isNaN(year) || isNaN(hours) || isNaN(minutes)) {
|
|
4630
4837
|
return null;
|
|
4631
|
-
|
|
4838
|
+
}
|
|
4839
|
+
if (month < 1 || month > 12 || day < 1 || day > 31 || hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
|
|
4632
4840
|
return null;
|
|
4841
|
+
}
|
|
4633
4842
|
const date = new Date(year, month - 1, day, hours, minutes);
|
|
4634
|
-
return isNaN(date.getTime()) ? null : date;
|
|
4843
|
+
return isNaN(date.getTime()) ? null : date.toISOString();
|
|
4844
|
+
}
|
|
4845
|
+
/** Converte locale string para Date */
|
|
4846
|
+
localeToDate(value) {
|
|
4847
|
+
const iso = this.localeToIso(value);
|
|
4848
|
+
if (!iso) {
|
|
4849
|
+
return null;
|
|
4850
|
+
}
|
|
4851
|
+
return new Date(iso);
|
|
4852
|
+
}
|
|
4853
|
+
// ==================== CALENDAR ====================
|
|
4854
|
+
updateDatetimeFormat() {
|
|
4855
|
+
const config = DATETIME_MASK_CONFIGS[this.currentLocale] || DATETIME_MASK_CONFIGS['pt-BR'];
|
|
4856
|
+
this.datetimeMask = config.mask;
|
|
4857
|
+
this.currentDateFormat = this.field?.dateFormat || this.localeService.getPrimeNGDateFormat();
|
|
4635
4858
|
}
|
|
4636
4859
|
toggleCalendar(event) {
|
|
4637
4860
|
event.stopPropagation();
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4861
|
+
if (this.displayValue && !this.displayValue.includes('_')) {
|
|
4862
|
+
this.calendarValue = this.localeToDate(this.displayValue);
|
|
4863
|
+
}
|
|
4864
|
+
else {
|
|
4865
|
+
this.calendarValue = new Date();
|
|
4866
|
+
}
|
|
4867
|
+
this.showCalendar = true;
|
|
4641
4868
|
setTimeout(() => {
|
|
4642
4869
|
if (this.calendarPicker && this.calendarPicker.inputfieldViewChild) {
|
|
4643
4870
|
this.calendarPicker.inputfieldViewChild.nativeElement.click();
|
|
@@ -4645,39 +4872,53 @@ class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
|
4645
4872
|
});
|
|
4646
4873
|
}
|
|
4647
4874
|
onCalendarSelect(date) {
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4875
|
+
if (date) {
|
|
4876
|
+
const iso = date.toISOString();
|
|
4877
|
+
this.displayValue = this.isoToLocale(date);
|
|
4878
|
+
this.setControlValue(iso);
|
|
4879
|
+
const control = this.form.get(this.field.field);
|
|
4880
|
+
if (control) {
|
|
4881
|
+
control.markAsDirty();
|
|
4882
|
+
}
|
|
4652
4883
|
}
|
|
4653
4884
|
}
|
|
4654
4885
|
onCalendarClear() {
|
|
4886
|
+
this.displayValue = null;
|
|
4887
|
+
this.setControlValue(null);
|
|
4655
4888
|
const control = this.form.get(this.field.field);
|
|
4656
4889
|
if (control) {
|
|
4657
|
-
control.setValue(null);
|
|
4658
4890
|
control.markAsDirty();
|
|
4659
4891
|
}
|
|
4660
4892
|
}
|
|
4893
|
+
isControlDisabled() {
|
|
4894
|
+
const control = this.form.get(this.field.field);
|
|
4895
|
+
return control ? control.disabled : false;
|
|
4896
|
+
}
|
|
4661
4897
|
getPlaceholder() {
|
|
4662
|
-
if (this.field.placeholder)
|
|
4898
|
+
if (this.field.placeholder) {
|
|
4663
4899
|
return this.field.placeholder;
|
|
4900
|
+
}
|
|
4664
4901
|
return DATETIME_MASK_CONFIGS[this.currentLocale]?.placeholder || 'dd/mm/aaaa HH:mm';
|
|
4665
4902
|
}
|
|
4666
4903
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldDatetimeComponent, deps: [{ token: TranslationService }, { token: LocaleService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4667
4904
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFieldDatetimeComponent, isStandalone: true, selector: "sia-dynamic-field-datetime", viewQueries: [{ propertyName: "calendarPicker", first: true, predicate: ["calendarPicker"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
4668
4905
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
4669
|
-
<div
|
|
4906
|
+
<div class="datetime-field">
|
|
4670
4907
|
<div class="datetime-input-group">
|
|
4671
4908
|
<p-inputmask
|
|
4672
4909
|
[inputId]="field.field"
|
|
4673
|
-
[
|
|
4910
|
+
[(ngModel)]="displayValue"
|
|
4911
|
+
[ngModelOptions]="{standalone: true}"
|
|
4674
4912
|
[mask]="datetimeMask"
|
|
4675
4913
|
[placeholder]="getPlaceholder()"
|
|
4676
4914
|
slotChar="_"
|
|
4677
4915
|
[autoClear]="false"
|
|
4678
4916
|
styleClass="datetime-input"
|
|
4679
4917
|
[class.ng-invalid]="isFieldInvalid()"
|
|
4680
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
4918
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
4919
|
+
[disabled]="isControlDisabled()"
|
|
4920
|
+
(onComplete)="onDisplayValueComplete()"
|
|
4921
|
+
(onBlur)="onDisplayValueBlur()">
|
|
4681
4922
|
</p-inputmask>
|
|
4682
4923
|
<div class="datetime-buttons">
|
|
4683
4924
|
<p-button
|
|
@@ -4691,31 +4932,34 @@ class DynamicFieldDatetimeComponent extends DynamicFieldBaseComponent {
|
|
|
4691
4932
|
size="small">
|
|
4692
4933
|
</p-button>
|
|
4693
4934
|
</div>
|
|
4935
|
+
<p-calendar
|
|
4936
|
+
*ngIf="showCalendar"
|
|
4937
|
+
#calendarPicker
|
|
4938
|
+
[(ngModel)]="calendarValue"
|
|
4939
|
+
[ngModelOptions]="{standalone: true}"
|
|
4940
|
+
[dateFormat]="currentDateFormat"
|
|
4941
|
+
[showTime]="true"
|
|
4942
|
+
[showSeconds]="false"
|
|
4943
|
+
[hourFormat]="'24'"
|
|
4944
|
+
[showButtonBar]="true"
|
|
4945
|
+
[appendTo]="'body'"
|
|
4946
|
+
[inline]="false"
|
|
4947
|
+
[showIcon]="false"
|
|
4948
|
+
(onSelect)="onCalendarSelect($event)"
|
|
4949
|
+
(onClearClick)="onCalendarClear()"
|
|
4950
|
+
(onHide)="showCalendar = false"
|
|
4951
|
+
styleClass="hidden-calendar-input"
|
|
4952
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
4953
|
+
</p-calendar>
|
|
4694
4954
|
</div>
|
|
4695
|
-
<p-calendar
|
|
4696
|
-
#calendarPicker
|
|
4697
|
-
[(ngModel)]="calendarValue"
|
|
4698
|
-
[dateFormat]="currentDateFormat"
|
|
4699
|
-
[showTime]="true"
|
|
4700
|
-
[showSeconds]="false"
|
|
4701
|
-
[hourFormat]="'24'"
|
|
4702
|
-
[showButtonBar]="true"
|
|
4703
|
-
[appendTo]="'body'"
|
|
4704
|
-
[inline]="false"
|
|
4705
|
-
[showIcon]="false"
|
|
4706
|
-
(onSelect)="onCalendarSelect($event)"
|
|
4707
|
-
(onClearClick)="onCalendarClear()"
|
|
4708
|
-
styleClass="hidden-calendar-input">
|
|
4709
|
-
</p-calendar>
|
|
4710
4955
|
</div>
|
|
4711
4956
|
</sia-dynamic-field-wrapper>
|
|
4712
|
-
`, isInline: true, styles: [".datetime-field{width:100%;position:relative}.datetime-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.datetime-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
4957
|
+
`, isInline: true, styles: [".datetime-field{width:100%;position:relative}.datetime-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.datetime-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "component", type: i5$1.InputMask, selector: "p-inputmask, p-inputMask, p-input-mask", inputs: ["type", "slotChar", "autoClear", "showClear", "style", "inputId", "styleClass", "placeholder", "size", "maxlength", "tabindex", "title", "variant", "ariaLabel", "ariaLabelledBy", "ariaRequired", "disabled", "readonly", "unmask", "name", "required", "characterPattern", "autofocus", "autoFocus", "autocomplete", "keepBuffer", "mask"], outputs: ["onComplete", "onFocus", "onBlur", "onInput", "onKeydown", "onClear"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "component", type: i6$1.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "fluid", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DynamicFieldWrapperComponent, selector: "sia-dynamic-field-wrapper", inputs: ["field", "form", "mode"] }] });
|
|
4713
4958
|
}
|
|
4714
4959
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldDatetimeComponent, decorators: [{
|
|
4715
4960
|
type: Component,
|
|
4716
4961
|
args: [{ selector: 'sia-dynamic-field-datetime', standalone: true, imports: [
|
|
4717
4962
|
CommonModule,
|
|
4718
|
-
ReactiveFormsModule,
|
|
4719
4963
|
FormsModule,
|
|
4720
4964
|
InputMaskModule,
|
|
4721
4965
|
CalendarModule,
|
|
@@ -4724,18 +4968,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4724
4968
|
DynamicFieldWrapperComponent
|
|
4725
4969
|
], template: `
|
|
4726
4970
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
4727
|
-
<div
|
|
4971
|
+
<div class="datetime-field">
|
|
4728
4972
|
<div class="datetime-input-group">
|
|
4729
4973
|
<p-inputmask
|
|
4730
4974
|
[inputId]="field.field"
|
|
4731
|
-
[
|
|
4975
|
+
[(ngModel)]="displayValue"
|
|
4976
|
+
[ngModelOptions]="{standalone: true}"
|
|
4732
4977
|
[mask]="datetimeMask"
|
|
4733
4978
|
[placeholder]="getPlaceholder()"
|
|
4734
4979
|
slotChar="_"
|
|
4735
4980
|
[autoClear]="false"
|
|
4736
4981
|
styleClass="datetime-input"
|
|
4737
4982
|
[class.ng-invalid]="isFieldInvalid()"
|
|
4738
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
4983
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
4984
|
+
[disabled]="isControlDisabled()"
|
|
4985
|
+
(onComplete)="onDisplayValueComplete()"
|
|
4986
|
+
(onBlur)="onDisplayValueBlur()">
|
|
4739
4987
|
</p-inputmask>
|
|
4740
4988
|
<div class="datetime-buttons">
|
|
4741
4989
|
<p-button
|
|
@@ -4749,25 +4997,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4749
4997
|
size="small">
|
|
4750
4998
|
</p-button>
|
|
4751
4999
|
</div>
|
|
5000
|
+
<p-calendar
|
|
5001
|
+
*ngIf="showCalendar"
|
|
5002
|
+
#calendarPicker
|
|
5003
|
+
[(ngModel)]="calendarValue"
|
|
5004
|
+
[ngModelOptions]="{standalone: true}"
|
|
5005
|
+
[dateFormat]="currentDateFormat"
|
|
5006
|
+
[showTime]="true"
|
|
5007
|
+
[showSeconds]="false"
|
|
5008
|
+
[hourFormat]="'24'"
|
|
5009
|
+
[showButtonBar]="true"
|
|
5010
|
+
[appendTo]="'body'"
|
|
5011
|
+
[inline]="false"
|
|
5012
|
+
[showIcon]="false"
|
|
5013
|
+
(onSelect)="onCalendarSelect($event)"
|
|
5014
|
+
(onClearClick)="onCalendarClear()"
|
|
5015
|
+
(onHide)="showCalendar = false"
|
|
5016
|
+
styleClass="hidden-calendar-input"
|
|
5017
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
5018
|
+
</p-calendar>
|
|
4752
5019
|
</div>
|
|
4753
|
-
<p-calendar
|
|
4754
|
-
#calendarPicker
|
|
4755
|
-
[(ngModel)]="calendarValue"
|
|
4756
|
-
[dateFormat]="currentDateFormat"
|
|
4757
|
-
[showTime]="true"
|
|
4758
|
-
[showSeconds]="false"
|
|
4759
|
-
[hourFormat]="'24'"
|
|
4760
|
-
[showButtonBar]="true"
|
|
4761
|
-
[appendTo]="'body'"
|
|
4762
|
-
[inline]="false"
|
|
4763
|
-
[showIcon]="false"
|
|
4764
|
-
(onSelect)="onCalendarSelect($event)"
|
|
4765
|
-
(onClearClick)="onCalendarClear()"
|
|
4766
|
-
styleClass="hidden-calendar-input">
|
|
4767
|
-
</p-calendar>
|
|
4768
5020
|
</div>
|
|
4769
5021
|
</sia-dynamic-field-wrapper>
|
|
4770
|
-
`, styles: [".datetime-field{width:100%;position:relative}.datetime-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.datetime-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
5022
|
+
`, styles: [".datetime-field{width:100%;position:relative}.datetime-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.datetime-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"] }]
|
|
4771
5023
|
}], ctorParameters: () => [{ type: TranslationService }, { type: LocaleService }, { type: i0.ChangeDetectorRef }], propDecorators: { calendarPicker: [{
|
|
4772
5024
|
type: ViewChild,
|
|
4773
5025
|
args: ['calendarPicker']
|
|
@@ -5568,7 +5820,7 @@ class DynamicFieldLookupComponent {
|
|
|
5568
5820
|
</div>
|
|
5569
5821
|
</p-dialog>
|
|
5570
5822
|
</sia-dynamic-field-wrapper>
|
|
5571
|
-
`, isInline: true, styles: [".lookup-field{width:100%;position:relative}.lookup-input-group{position:relative;width:100%;.lookup-display{width:100%;cursor:pointer;height:2.857rem;padding:.75rem 4rem .75rem .75rem;font-size:1rem;line-height:1.5;box-sizing:border-box;display:flex;align-items:center;&:focus{outline:none}&:hover{background:transparent}}.lookup-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}.autocomplete-suggestions{position:absolute;top:100%;left:0;right:0;z-index:1000;background:var(--p-surface-0, #fff);border:1px solid var(--p-surface-300, #d1d5db);border-top:none;border-radius:0 0 6px 6px;max-height:200px;overflow-y:auto;box-shadow:0 4px 6px #0000001a;.suggestion-item{padding:.625rem .75rem;cursor:pointer;font-size:.875rem;color:var(--p-text-color, #333);transition:background .15s;&:hover{background:var(--p-surface-100, #f3f4f6)}&.suggestion-loading{color:var(--p-text-muted-color, #999);cursor:default;font-style:italic}}}}.lookup-dialog-content{height:100%;display:flex;flex-direction:column;padding:0;.search-wrapper{position:relative;margin-bottom:16px;width:100%;.search-input-full{width:100%;padding-right:5.5rem}.search-buttons-inside{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;::ng-deep .p-button{width:2.5rem!important;height:2.5rem!important}}}.lookup-table{flex:1;.empty-state{text-align:center;padding:32px;color:var(--p-text-color-secondary);i{font-size:48px;margin-bottom:16px;display:block}p{margin:8px 0;font-size:16px}small{font-size:14px}}}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type:
|
|
5823
|
+
`, isInline: true, styles: [".lookup-field{width:100%;position:relative}.lookup-input-group{position:relative;width:100%;.lookup-display{width:100%;cursor:pointer;height:2.857rem;padding:.75rem 4rem .75rem .75rem;font-size:1rem;line-height:1.5;box-sizing:border-box;display:flex;align-items:center;&:focus{outline:none}&:hover{background:transparent}}.lookup-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}.autocomplete-suggestions{position:absolute;top:100%;left:0;right:0;z-index:1000;background:var(--p-surface-0, #fff);border:1px solid var(--p-surface-300, #d1d5db);border-top:none;border-radius:0 0 6px 6px;max-height:200px;overflow-y:auto;box-shadow:0 4px 6px #0000001a;.suggestion-item{padding:.625rem .75rem;cursor:pointer;font-size:.875rem;color:var(--p-text-color, #333);transition:background .15s;&:hover{background:var(--p-surface-100, #f3f4f6)}&.suggestion-loading{color:var(--p-text-muted-color, #999);cursor:default;font-style:italic}}}}.lookup-dialog-content{height:100%;display:flex;flex-direction:column;padding:0;.search-wrapper{position:relative;margin-bottom:16px;width:100%;.search-input-full{width:100%;padding-right:5.5rem}.search-buttons-inside{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;::ng-deep .p-button{width:2.5rem!important;height:2.5rem!important}}}.lookup-table{flex:1;.empty-state{text-align:center;padding:32px;color:var(--p-text-color-secondary);i{font-size:48px;margin-bottom:16px;display:block}p{margin:8px 0;font-size:16px}small{font-size:14px}}}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i8$2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i8$2.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldWrapperComponent, selector: "sia-dynamic-field-wrapper", inputs: ["field", "form", "mode"] }, { kind: "directive", type: TableLoadingDirective, selector: "p-table[siaTableLoading]", inputs: ["loading", "siaLoadingVariant", "siaLoadingColor", "siaLoadingSize"] }] });
|
|
5572
5824
|
}
|
|
5573
5825
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldLookupComponent, decorators: [{
|
|
5574
5826
|
type: Component,
|
|
@@ -5813,81 +6065,191 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5813
6065
|
`, styles: ["textarea{width:100%;resize:vertical}\n"] }]
|
|
5814
6066
|
}], ctorParameters: () => [{ type: TranslationService }] });
|
|
5815
6067
|
|
|
6068
|
+
/**
|
|
6069
|
+
* DynamicFieldTimeComponent
|
|
6070
|
+
*
|
|
6071
|
+
* O FormControl.value armazena o horário no formato "HH:mm" (ex: "14:30").
|
|
6072
|
+
* A variável `displayValue` mantém o valor formatado para exibição no input.
|
|
6073
|
+
* Aceita valores de entrada em "HH:mm" ou "HH:mm:ss" (truncando os segundos).
|
|
6074
|
+
*/
|
|
5816
6075
|
class DynamicFieldTimeComponent extends DynamicFieldBaseComponent {
|
|
5817
6076
|
timePicker;
|
|
5818
|
-
|
|
6077
|
+
/** Valor de exibição "HH:mm" */
|
|
6078
|
+
displayValue = null;
|
|
6079
|
+
/** Valor do picker (Date) */
|
|
6080
|
+
pickerValue = null;
|
|
6081
|
+
/** Controla a renderização do p-calendar */
|
|
6082
|
+
showPicker = false;
|
|
5819
6083
|
valueSub;
|
|
6084
|
+
updatingFromControl = false;
|
|
5820
6085
|
constructor(translationService) {
|
|
5821
6086
|
super(translationService);
|
|
5822
6087
|
}
|
|
5823
6088
|
ngOnInit() {
|
|
5824
6089
|
const control = this.form.get(this.field.field);
|
|
5825
6090
|
if (control) {
|
|
5826
|
-
|
|
5827
|
-
control.setValue(this.dateToTimeString(control.value), { emitEvent: false });
|
|
5828
|
-
}
|
|
6091
|
+
this.syncDisplayFromControl(control.value);
|
|
5829
6092
|
this.valueSub = control.valueChanges.subscribe(value => {
|
|
5830
|
-
if (
|
|
5831
|
-
|
|
6093
|
+
if (this.updatingFromControl) {
|
|
6094
|
+
return;
|
|
5832
6095
|
}
|
|
6096
|
+
this.syncDisplayFromControl(value);
|
|
5833
6097
|
});
|
|
5834
6098
|
}
|
|
5835
6099
|
}
|
|
5836
6100
|
ngOnDestroy() {
|
|
5837
6101
|
this.valueSub?.unsubscribe();
|
|
5838
6102
|
}
|
|
6103
|
+
/**
|
|
6104
|
+
* Sincroniza o displayValue a partir do valor do FormControl.
|
|
6105
|
+
* Aceita: "HH:mm", "HH:mm:ss", Date, ou null.
|
|
6106
|
+
*/
|
|
6107
|
+
syncDisplayFromControl(value) {
|
|
6108
|
+
if (!value) {
|
|
6109
|
+
this.displayValue = null;
|
|
6110
|
+
return;
|
|
6111
|
+
}
|
|
6112
|
+
if (value instanceof Date) {
|
|
6113
|
+
const timeStr = this.dateToTimeString(value);
|
|
6114
|
+
this.setControlValue(timeStr);
|
|
6115
|
+
this.displayValue = timeStr;
|
|
6116
|
+
return;
|
|
6117
|
+
}
|
|
6118
|
+
const s = String(value);
|
|
6119
|
+
// "HH:mm:ss" → truncar para "HH:mm"
|
|
6120
|
+
if (s.match(/^\d{2}:\d{2}:\d{2}$/)) {
|
|
6121
|
+
const short = s.substring(0, 5);
|
|
6122
|
+
this.displayValue = short;
|
|
6123
|
+
this.setControlValue(short);
|
|
6124
|
+
return;
|
|
6125
|
+
}
|
|
6126
|
+
// "HH:mm" → usar direto
|
|
6127
|
+
if (s.match(/^\d{2}:\d{2}$/)) {
|
|
6128
|
+
this.displayValue = s;
|
|
6129
|
+
return;
|
|
6130
|
+
}
|
|
6131
|
+
// Valor incompleto
|
|
6132
|
+
this.displayValue = null;
|
|
6133
|
+
}
|
|
6134
|
+
/** Chamado quando o usuário completa a digitação da máscara */
|
|
6135
|
+
onDisplayValueComplete() {
|
|
6136
|
+
this.syncControlFromDisplay();
|
|
6137
|
+
}
|
|
6138
|
+
/** Chamado quando o input perde foco */
|
|
6139
|
+
onDisplayValueBlur() {
|
|
6140
|
+
this.syncControlFromDisplay();
|
|
6141
|
+
}
|
|
6142
|
+
/** Converte o displayValue para o FormControl */
|
|
6143
|
+
syncControlFromDisplay() {
|
|
6144
|
+
const control = this.form.get(this.field.field);
|
|
6145
|
+
if (!control) {
|
|
6146
|
+
return;
|
|
6147
|
+
}
|
|
6148
|
+
if (!this.displayValue || this.displayValue.includes('_')) {
|
|
6149
|
+
this.setControlValue(null);
|
|
6150
|
+
control.markAsDirty();
|
|
6151
|
+
return;
|
|
6152
|
+
}
|
|
6153
|
+
// Validar HH:mm
|
|
6154
|
+
if (this.isValidTime(this.displayValue)) {
|
|
6155
|
+
this.setControlValue(this.displayValue);
|
|
6156
|
+
control.markAsDirty();
|
|
6157
|
+
}
|
|
6158
|
+
}
|
|
6159
|
+
/** Seta o valor no control sem disparar o subscriber interno */
|
|
6160
|
+
setControlValue(value) {
|
|
6161
|
+
const control = this.form.get(this.field.field);
|
|
6162
|
+
if (!control) {
|
|
6163
|
+
return;
|
|
6164
|
+
}
|
|
6165
|
+
this.updatingFromControl = true;
|
|
6166
|
+
control.setValue(value, { emitEvent: true });
|
|
6167
|
+
this.updatingFromControl = false;
|
|
6168
|
+
}
|
|
6169
|
+
// ==================== CONVERSÕES ====================
|
|
5839
6170
|
dateToTimeString(date) {
|
|
5840
6171
|
return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
|
|
5841
6172
|
}
|
|
5842
|
-
|
|
5843
|
-
if (!value || value.includes('_'))
|
|
6173
|
+
timeStringToDate(value) {
|
|
6174
|
+
if (!value || value.includes('_')) {
|
|
5844
6175
|
return null;
|
|
6176
|
+
}
|
|
5845
6177
|
const parts = value.split(':');
|
|
5846
|
-
if (parts.length
|
|
6178
|
+
if (parts.length < 2) {
|
|
5847
6179
|
return null;
|
|
6180
|
+
}
|
|
5848
6181
|
const hours = parseInt(parts[0], 10);
|
|
5849
6182
|
const minutes = parseInt(parts[1], 10);
|
|
5850
|
-
if (isNaN(hours) || isNaN(minutes) || hours < 0 || hours > 23 || minutes < 0 || minutes > 59)
|
|
6183
|
+
if (isNaN(hours) || isNaN(minutes) || hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
|
|
5851
6184
|
return null;
|
|
6185
|
+
}
|
|
5852
6186
|
const d = new Date();
|
|
5853
6187
|
d.setHours(hours, minutes, 0, 0);
|
|
5854
6188
|
return d;
|
|
5855
6189
|
}
|
|
6190
|
+
isValidTime(value) {
|
|
6191
|
+
const parts = value.split(':');
|
|
6192
|
+
if (parts.length !== 2) {
|
|
6193
|
+
return false;
|
|
6194
|
+
}
|
|
6195
|
+
const h = parseInt(parts[0], 10);
|
|
6196
|
+
const m = parseInt(parts[1], 10);
|
|
6197
|
+
return !isNaN(h) && !isNaN(m) && h >= 0 && h <= 23 && m >= 0 && m <= 59;
|
|
6198
|
+
}
|
|
6199
|
+
// ==================== TIME PICKER ====================
|
|
5856
6200
|
toggleTimePicker(event) {
|
|
5857
6201
|
event.stopPropagation();
|
|
5858
|
-
|
|
5859
|
-
|
|
6202
|
+
if (this.displayValue && !this.displayValue.includes('_')) {
|
|
6203
|
+
this.pickerValue = this.timeStringToDate(this.displayValue);
|
|
6204
|
+
}
|
|
6205
|
+
else {
|
|
6206
|
+
this.pickerValue = new Date();
|
|
6207
|
+
}
|
|
6208
|
+
this.showPicker = true;
|
|
5860
6209
|
setTimeout(() => {
|
|
5861
|
-
if (this.timePicker) {
|
|
5862
|
-
this.timePicker.
|
|
6210
|
+
if (this.timePicker && this.timePicker.inputfieldViewChild) {
|
|
6211
|
+
this.timePicker.inputfieldViewChild.nativeElement.click();
|
|
5863
6212
|
}
|
|
5864
6213
|
});
|
|
5865
6214
|
}
|
|
5866
6215
|
onTimeSelect(date) {
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
6216
|
+
if (date) {
|
|
6217
|
+
const timeStr = this.dateToTimeString(date);
|
|
6218
|
+
this.displayValue = timeStr;
|
|
6219
|
+
this.setControlValue(timeStr);
|
|
6220
|
+
const control = this.form.get(this.field.field);
|
|
6221
|
+
if (control) {
|
|
6222
|
+
control.markAsDirty();
|
|
6223
|
+
}
|
|
5871
6224
|
}
|
|
5872
6225
|
}
|
|
6226
|
+
isControlDisabled() {
|
|
6227
|
+
const control = this.form.get(this.field.field);
|
|
6228
|
+
return control ? control.disabled : false;
|
|
6229
|
+
}
|
|
5873
6230
|
getPlaceholder() {
|
|
5874
6231
|
return this.field.placeholder || 'HH:mm';
|
|
5875
6232
|
}
|
|
5876
6233
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldTimeComponent, deps: [{ token: TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5877
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFieldTimeComponent, isStandalone: true, selector: "sia-dynamic-field-time", viewQueries: [{ propertyName: "timePicker", first: true, predicate: ["timePicker"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
6234
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFieldTimeComponent, isStandalone: true, selector: "sia-dynamic-field-time", host: { styleAttribute: "display: block; width: 100%;" }, viewQueries: [{ propertyName: "timePicker", first: true, predicate: ["timePicker"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
5878
6235
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
5879
|
-
<div
|
|
6236
|
+
<div class="time-field">
|
|
5880
6237
|
<div class="time-input-group">
|
|
5881
6238
|
<p-inputmask
|
|
5882
6239
|
[inputId]="field.field"
|
|
5883
|
-
[
|
|
6240
|
+
[(ngModel)]="displayValue"
|
|
6241
|
+
[ngModelOptions]="{standalone: true}"
|
|
5884
6242
|
mask="99:99"
|
|
5885
6243
|
[placeholder]="getPlaceholder()"
|
|
5886
6244
|
slotChar="_"
|
|
5887
6245
|
[autoClear]="false"
|
|
5888
|
-
styleClass="time-input"
|
|
6246
|
+
styleClass="time-input w-full"
|
|
6247
|
+
[style]="{'width': '100%', 'display': 'block'}"
|
|
5889
6248
|
[class.ng-invalid]="isFieldInvalid()"
|
|
5890
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
6249
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
6250
|
+
[disabled]="isControlDisabled()"
|
|
6251
|
+
(onComplete)="onDisplayValueComplete()"
|
|
6252
|
+
(onBlur)="onDisplayValueBlur()">
|
|
5891
6253
|
</p-inputmask>
|
|
5892
6254
|
<div class="time-buttons">
|
|
5893
6255
|
<p-button
|
|
@@ -5901,28 +6263,31 @@ class DynamicFieldTimeComponent extends DynamicFieldBaseComponent {
|
|
|
5901
6263
|
size="small">
|
|
5902
6264
|
</p-button>
|
|
5903
6265
|
</div>
|
|
6266
|
+
<p-calendar
|
|
6267
|
+
*ngIf="showPicker"
|
|
6268
|
+
#timePicker
|
|
6269
|
+
[(ngModel)]="pickerValue"
|
|
6270
|
+
[ngModelOptions]="{standalone: true}"
|
|
6271
|
+
[timeOnly]="true"
|
|
6272
|
+
[showSeconds]="false"
|
|
6273
|
+
[hourFormat]="'24'"
|
|
6274
|
+
[appendTo]="'body'"
|
|
6275
|
+
[inline]="false"
|
|
6276
|
+
[showIcon]="false"
|
|
6277
|
+
(onSelect)="onTimeSelect($event)"
|
|
6278
|
+
(onHide)="showPicker = false"
|
|
6279
|
+
styleClass="hidden-calendar-input"
|
|
6280
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
6281
|
+
</p-calendar>
|
|
5904
6282
|
</div>
|
|
5905
|
-
<p-calendar
|
|
5906
|
-
#timePicker
|
|
5907
|
-
[(ngModel)]="timeValue"
|
|
5908
|
-
[timeOnly]="true"
|
|
5909
|
-
[showSeconds]="false"
|
|
5910
|
-
[hourFormat]="'24'"
|
|
5911
|
-
[appendTo]="'body'"
|
|
5912
|
-
[inline]="false"
|
|
5913
|
-
[showIcon]="false"
|
|
5914
|
-
(onSelect)="onTimeSelect($event)"
|
|
5915
|
-
styleClass="hidden-calendar-input">
|
|
5916
|
-
</p-calendar>
|
|
5917
6283
|
</div>
|
|
5918
6284
|
</sia-dynamic-field-wrapper>
|
|
5919
|
-
`, isInline: true, styles: [".time-field{width:100%;position:relative}.time-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.time-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
6285
|
+
`, isInline: true, styles: [".time-field{width:100%;position:relative}.time-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.time-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "component", type: i5$1.InputMask, selector: "p-inputmask, p-inputMask, p-input-mask", inputs: ["type", "slotChar", "autoClear", "showClear", "style", "inputId", "styleClass", "placeholder", "size", "maxlength", "tabindex", "title", "variant", "ariaLabel", "ariaLabelledBy", "ariaRequired", "disabled", "readonly", "unmask", "name", "required", "characterPattern", "autofocus", "autoFocus", "autocomplete", "keepBuffer", "mask"], outputs: ["onComplete", "onFocus", "onBlur", "onInput", "onKeydown", "onClear"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "component", type: i6$1.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "fluid", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DynamicFieldWrapperComponent, selector: "sia-dynamic-field-wrapper", inputs: ["field", "form", "mode"] }] });
|
|
5920
6286
|
}
|
|
5921
6287
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFieldTimeComponent, decorators: [{
|
|
5922
6288
|
type: Component,
|
|
5923
|
-
args: [{ selector: 'sia-dynamic-field-time', standalone: true, imports: [
|
|
6289
|
+
args: [{ selector: 'sia-dynamic-field-time', standalone: true, host: { style: 'display: block; width: 100%;' }, imports: [
|
|
5924
6290
|
CommonModule,
|
|
5925
|
-
ReactiveFormsModule,
|
|
5926
6291
|
FormsModule,
|
|
5927
6292
|
InputMaskModule,
|
|
5928
6293
|
CalendarModule,
|
|
@@ -5931,18 +6296,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5931
6296
|
DynamicFieldWrapperComponent
|
|
5932
6297
|
], template: `
|
|
5933
6298
|
<sia-dynamic-field-wrapper [field]="field" [form]="form" [mode]="mode">
|
|
5934
|
-
<div
|
|
6299
|
+
<div class="time-field">
|
|
5935
6300
|
<div class="time-input-group">
|
|
5936
6301
|
<p-inputmask
|
|
5937
6302
|
[inputId]="field.field"
|
|
5938
|
-
[
|
|
6303
|
+
[(ngModel)]="displayValue"
|
|
6304
|
+
[ngModelOptions]="{standalone: true}"
|
|
5939
6305
|
mask="99:99"
|
|
5940
6306
|
[placeholder]="getPlaceholder()"
|
|
5941
6307
|
slotChar="_"
|
|
5942
6308
|
[autoClear]="false"
|
|
5943
|
-
styleClass="time-input"
|
|
6309
|
+
styleClass="time-input w-full"
|
|
6310
|
+
[style]="{'width': '100%', 'display': 'block'}"
|
|
5944
6311
|
[class.ng-invalid]="isFieldInvalid()"
|
|
5945
|
-
[class.ng-dirty]="isFieldDirty()"
|
|
6312
|
+
[class.ng-dirty]="isFieldDirty()"
|
|
6313
|
+
[disabled]="isControlDisabled()"
|
|
6314
|
+
(onComplete)="onDisplayValueComplete()"
|
|
6315
|
+
(onBlur)="onDisplayValueBlur()">
|
|
5946
6316
|
</p-inputmask>
|
|
5947
6317
|
<div class="time-buttons">
|
|
5948
6318
|
<p-button
|
|
@@ -5956,22 +6326,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5956
6326
|
size="small">
|
|
5957
6327
|
</p-button>
|
|
5958
6328
|
</div>
|
|
6329
|
+
<p-calendar
|
|
6330
|
+
*ngIf="showPicker"
|
|
6331
|
+
#timePicker
|
|
6332
|
+
[(ngModel)]="pickerValue"
|
|
6333
|
+
[ngModelOptions]="{standalone: true}"
|
|
6334
|
+
[timeOnly]="true"
|
|
6335
|
+
[showSeconds]="false"
|
|
6336
|
+
[hourFormat]="'24'"
|
|
6337
|
+
[appendTo]="'body'"
|
|
6338
|
+
[inline]="false"
|
|
6339
|
+
[showIcon]="false"
|
|
6340
|
+
(onSelect)="onTimeSelect($event)"
|
|
6341
|
+
(onHide)="showPicker = false"
|
|
6342
|
+
styleClass="hidden-calendar-input"
|
|
6343
|
+
[style]="{'position': 'absolute', 'width': '0', 'height': '0', 'overflow': 'hidden', 'opacity': '0', 'pointer-events': 'none'}">
|
|
6344
|
+
</p-calendar>
|
|
5959
6345
|
</div>
|
|
5960
|
-
<p-calendar
|
|
5961
|
-
#timePicker
|
|
5962
|
-
[(ngModel)]="timeValue"
|
|
5963
|
-
[timeOnly]="true"
|
|
5964
|
-
[showSeconds]="false"
|
|
5965
|
-
[hourFormat]="'24'"
|
|
5966
|
-
[appendTo]="'body'"
|
|
5967
|
-
[inline]="false"
|
|
5968
|
-
[showIcon]="false"
|
|
5969
|
-
(onSelect)="onTimeSelect($event)"
|
|
5970
|
-
styleClass="hidden-calendar-input">
|
|
5971
|
-
</p-calendar>
|
|
5972
6346
|
</div>
|
|
5973
6347
|
</sia-dynamic-field-wrapper>
|
|
5974
|
-
`, styles: [".time-field{width:100%;position:relative}.time-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.time-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}
|
|
6348
|
+
`, styles: [".time-field{width:100%;position:relative}.time-input-group{position:relative;width:100%;::ng-deep p-inputmask{width:100%;display:block;input{width:100%;padding-right:2.5rem}}.time-buttons{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:flex;gap:2px;z-index:10}::ng-deep .p-button{width:2rem!important;height:2rem!important;min-width:2rem!important;min-height:2rem!important;padding:0!important;margin:0!important;display:flex!important;align-items:center!important;justify-content:center!important;box-sizing:border-box!important;.p-button-icon{margin:0!important;font-size:.875rem!important}.p-button-label{display:none!important}}}.hidden-calendar-input,::ng-deep .hidden-calendar-input{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;opacity:0!important;pointer-events:none!important;margin:0!important;padding:0!important;border:none!important;top:0;left:0;input{width:0!important;height:0!important;padding:0!important;border:none!important}}>p-calendar{position:absolute!important;width:0!important;height:0!important;overflow:hidden!important;pointer-events:none!important}\n"] }]
|
|
5975
6349
|
}], ctorParameters: () => [{ type: TranslationService }], propDecorators: { timePicker: [{
|
|
5976
6350
|
type: ViewChild,
|
|
5977
6351
|
args: ['timePicker']
|
|
@@ -6417,55 +6791,41 @@ class DynamicFormComponent {
|
|
|
6417
6791
|
processEntityData(entity) {
|
|
6418
6792
|
const data = { ...entity };
|
|
6419
6793
|
this.allFields.forEach(field => {
|
|
6794
|
+
// Date: pass ISO string directly — field component handles display conversion
|
|
6420
6795
|
if (field.type === 'date' && data[field.field]) {
|
|
6421
6796
|
const v = data[field.field];
|
|
6422
|
-
if (
|
|
6423
|
-
|
|
6424
|
-
const parts = v.substring(0, 10).split('-');
|
|
6425
|
-
if (parts.length === 3) {
|
|
6426
|
-
const [year, month, day] = parts;
|
|
6427
|
-
const locale = this.translationService.getCurrentLanguage();
|
|
6428
|
-
data[field.field] = locale === 'en-US'
|
|
6429
|
-
? `${month}/${day}/${year}`
|
|
6430
|
-
: `${day}/${month}/${year}`;
|
|
6431
|
-
}
|
|
6432
|
-
}
|
|
6433
|
-
else if (v instanceof Date) {
|
|
6434
|
-
const day = String(v.getDate()).padStart(2, '0');
|
|
6435
|
-
const month = String(v.getMonth() + 1).padStart(2, '0');
|
|
6436
|
-
const year = String(v.getFullYear());
|
|
6437
|
-
const locale = this.translationService.getCurrentLanguage();
|
|
6438
|
-
data[field.field] = locale === 'en-US'
|
|
6439
|
-
? `${month}/${day}/${year}`
|
|
6440
|
-
: `${day}/${month}/${year}`;
|
|
6797
|
+
if (v instanceof Date) {
|
|
6798
|
+
data[field.field] = `${v.getFullYear()}-${String(v.getMonth() + 1).padStart(2, '0')}-${String(v.getDate()).padStart(2, '0')}`;
|
|
6441
6799
|
}
|
|
6800
|
+
// String values (ISO "yyyy-MM-dd") are passed as-is to the field component
|
|
6442
6801
|
}
|
|
6802
|
+
// Time: normalize to "HH:mm" for the inputmask display
|
|
6443
6803
|
if (field.type === 'time' && data[field.field]) {
|
|
6444
6804
|
const v = data[field.field];
|
|
6445
|
-
if (
|
|
6805
|
+
if (v instanceof Date) {
|
|
6806
|
+
data[field.field] = `${String(v.getHours()).padStart(2, '0')}:${String(v.getMinutes()).padStart(2, '0')}`;
|
|
6807
|
+
}
|
|
6808
|
+
else if (typeof v === 'string') {
|
|
6446
6809
|
const parts = v.split(':');
|
|
6447
6810
|
if (parts.length >= 2) {
|
|
6448
6811
|
data[field.field] = `${parts[0].padStart(2, '0')}:${parts[1].padStart(2, '0')}`;
|
|
6449
6812
|
}
|
|
6450
6813
|
}
|
|
6451
|
-
else if (v instanceof Date) {
|
|
6452
|
-
data[field.field] = `${String(v.getHours()).padStart(2, '0')}:${String(v.getMinutes()).padStart(2, '0')}`;
|
|
6453
|
-
}
|
|
6454
6814
|
}
|
|
6815
|
+
// Datetime: normalize to ISO string — field component handles display conversion
|
|
6455
6816
|
if (field.type === 'datetime' && data[field.field]) {
|
|
6456
6817
|
const v = data[field.field];
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
const day = String(d.getDate()).padStart(2, '0');
|
|
6460
|
-
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
6461
|
-
const year = String(d.getFullYear());
|
|
6462
|
-
const hours = String(d.getHours()).padStart(2, '0');
|
|
6463
|
-
const minutes = String(d.getMinutes()).padStart(2, '0');
|
|
6464
|
-
const locale = this.translationService.getCurrentLanguage();
|
|
6465
|
-
data[field.field] = locale === 'en-US'
|
|
6466
|
-
? `${month}/${day}/${year} ${hours}:${minutes}`
|
|
6467
|
-
: `${day}/${month}/${year} ${hours}:${minutes}`;
|
|
6818
|
+
if (v instanceof Date) {
|
|
6819
|
+
data[field.field] = v.toISOString();
|
|
6468
6820
|
}
|
|
6821
|
+
else if (typeof v === 'string' && !v.includes('T')) {
|
|
6822
|
+
// Try to parse non-ISO string
|
|
6823
|
+
const d = new Date(v);
|
|
6824
|
+
if (!isNaN(d.getTime())) {
|
|
6825
|
+
data[field.field] = d.toISOString();
|
|
6826
|
+
}
|
|
6827
|
+
}
|
|
6828
|
+
// ISO strings with T are passed as-is
|
|
6469
6829
|
}
|
|
6470
6830
|
if (field.type === 'lookup' && data[field.field]) {
|
|
6471
6831
|
const v = data[field.field];
|
|
@@ -6514,49 +6874,26 @@ class DynamicFormComponent {
|
|
|
6514
6874
|
out[field.field] = null;
|
|
6515
6875
|
}
|
|
6516
6876
|
else if (field.type === 'date') {
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
const parts = v.split('/');
|
|
6520
|
-
const locale = this.translationService.getCurrentLanguage();
|
|
6521
|
-
const [day, month, year] = locale === 'en-US'
|
|
6522
|
-
? [parts[1], parts[0], parts[2]]
|
|
6523
|
-
: [parts[0], parts[1], parts[2]];
|
|
6524
|
-
out[field.field] = `${year}-${month}-${day}`;
|
|
6525
|
-
}
|
|
6526
|
-
else if (v instanceof Date) {
|
|
6527
|
-
out[field.field] = `${v.getFullYear()}-${String(v.getMonth() + 1).padStart(2, '0')}-${String(v.getDate()).padStart(2, '0')}`;
|
|
6528
|
-
}
|
|
6529
|
-
else if (!v || (typeof v === 'string' && v.includes('_'))) {
|
|
6877
|
+
// Value is already in ISO format "yyyy-MM-dd" from the field component
|
|
6878
|
+
if (!v || (typeof v === 'string' && v.includes('_'))) {
|
|
6530
6879
|
out[field.field] = null;
|
|
6531
6880
|
}
|
|
6532
6881
|
}
|
|
6533
6882
|
else if (field.type === 'time') {
|
|
6883
|
+
// Value is "HH:mm" from the inputmask — normalize to "HH:mm:ss" for backend
|
|
6534
6884
|
if (typeof v === 'string' && v.match(/^\d{2}:\d{2}$/)) {
|
|
6535
6885
|
out[field.field] = `${v}:00`;
|
|
6536
6886
|
}
|
|
6537
|
-
else if (v
|
|
6538
|
-
|
|
6887
|
+
else if (typeof v === 'string' && v.match(/^\d{2}:\d{2}:\d{2}$/)) {
|
|
6888
|
+
// Already ISO, keep as-is
|
|
6539
6889
|
}
|
|
6540
6890
|
else if (!v || (typeof v === 'string' && v.includes('_'))) {
|
|
6541
6891
|
out[field.field] = null;
|
|
6542
6892
|
}
|
|
6543
6893
|
}
|
|
6544
6894
|
else if (field.type === 'datetime') {
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
const [datePart, timePart] = v.split(' ');
|
|
6548
|
-
const dateParts = datePart.split('/');
|
|
6549
|
-
const locale = this.translationService.getCurrentLanguage();
|
|
6550
|
-
const [day, month, year] = locale === 'en-US'
|
|
6551
|
-
? [parseInt(dateParts[1], 10), parseInt(dateParts[0], 10), parseInt(dateParts[2], 10)]
|
|
6552
|
-
: [parseInt(dateParts[0], 10), parseInt(dateParts[1], 10), parseInt(dateParts[2], 10)];
|
|
6553
|
-
const [hours, minutes] = timePart.split(':').map(p => parseInt(p, 10));
|
|
6554
|
-
out[field.field] = new Date(year, month - 1, day, hours, minutes).toISOString();
|
|
6555
|
-
}
|
|
6556
|
-
else if (v instanceof Date) {
|
|
6557
|
-
out[field.field] = v.toISOString();
|
|
6558
|
-
}
|
|
6559
|
-
else if (!v || (typeof v === 'string' && v.includes('_'))) {
|
|
6895
|
+
// Value is already in ISO format from the field component
|
|
6896
|
+
if (!v || (typeof v === 'string' && v.includes('_'))) {
|
|
6560
6897
|
out[field.field] = null;
|
|
6561
6898
|
}
|
|
6562
6899
|
}
|
|
@@ -6716,17 +7053,8 @@ class DynamicFormComponent {
|
|
|
6716
7053
|
if (field?.type === 'lookup' && value && typeof value === 'object') {
|
|
6717
7054
|
control.setValue(value);
|
|
6718
7055
|
}
|
|
6719
|
-
else if (field?.type === 'date' && value && typeof value === 'string') {
|
|
6720
|
-
const parts = value.substring(0, 10).split('-');
|
|
6721
|
-
if (parts.length === 3) {
|
|
6722
|
-
const d = new Date(+parts[0], +parts[1] - 1, +parts[2]);
|
|
6723
|
-
control.setValue(!isNaN(d.getTime()) ? d : value);
|
|
6724
|
-
}
|
|
6725
|
-
else {
|
|
6726
|
-
control.setValue(value);
|
|
6727
|
-
}
|
|
6728
|
-
}
|
|
6729
7056
|
else {
|
|
7057
|
+
// Date, time, datetime values are already in ISO format in the control
|
|
6730
7058
|
control.setValue(value);
|
|
6731
7059
|
}
|
|
6732
7060
|
}
|
|
@@ -6752,9 +7080,7 @@ class DynamicFormComponent {
|
|
|
6752
7080
|
if (field?.type === 'lookup' && value && typeof value !== 'object') {
|
|
6753
7081
|
value = { id: value };
|
|
6754
7082
|
}
|
|
6755
|
-
|
|
6756
|
-
value = `${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(value.getDate()).padStart(2, '0')}`;
|
|
6757
|
-
}
|
|
7083
|
+
// Date, time, datetime values are already in ISO format from the field component
|
|
6758
7084
|
this.fieldSave.emit({ field: fieldName, value });
|
|
6759
7085
|
}
|
|
6760
7086
|
cancelInlineEdit() {
|
|
@@ -6843,7 +7169,7 @@ class DynamicFormComponent {
|
|
|
6843
7169
|
return String(value);
|
|
6844
7170
|
}
|
|
6845
7171
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, deps: [{ token: i2$1.FormBuilder }, { token: TranslationService }, { token: MaskService }, { token: LocaleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
6846
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFormComponent, isStandalone: true, selector: "sia-dynamic-form", inputs: { sections: "sections", entityData: "entityData", mode: "mode", displayMode: "displayMode", visible: "visible", dialogConfig: "dialogConfig", drawerConfig: "drawerConfig", showSubmitButton: "showSubmitButton", showCancelButton: "showCancelButton", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", submitButtonIcon: "submitButtonIcon", cancelButtonIcon: "cancelButtonIcon" }, outputs: { formReady: "formReady", formSubmit: "formSubmit", visibleChange: "visibleChange", onCancel: "onCancel", fieldSave: "fieldSave" }, usesOnChanges: true, ngImport: i0, template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i6$2.Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i9.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldTextComponent, selector: "sia-dynamic-field-text" }, { kind: "component", type: DynamicFieldNumberComponent, selector: "sia-dynamic-field-number" }, { kind: "component", type: DynamicFieldDateComponent, selector: "sia-dynamic-field-date" }, { kind: "component", type: DynamicFieldDatetimeComponent, selector: "sia-dynamic-field-datetime" }, { kind: "component", type: DynamicFieldDropdownComponent, selector: "sia-dynamic-field-dropdown" }, { kind: "component", type: DynamicFieldLookupComponent, selector: "sia-dynamic-field-lookup", inputs: ["field", "form", "formGroup", "mode"] }, { kind: "component", type: DynamicFieldTextareaComponent, selector: "sia-dynamic-field-textarea" }, { kind: "component", type: DynamicFieldTimeComponent, selector: "sia-dynamic-field-time" }, { kind: "component", type: DynamicFieldCheckboxComponent, selector: "sia-dynamic-field-checkbox" }, { kind: "component", type: DynamicFieldMultiselectComponent, selector: "sia-dynamic-field-multiselect" }, { kind: "component", type: DynamicFieldImageComponent, selector: "sia-dynamic-field-image" }] });
|
|
7172
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFormComponent, isStandalone: true, selector: "sia-dynamic-form", inputs: { sections: "sections", entityData: "entityData", mode: "mode", displayMode: "displayMode", visible: "visible", dialogConfig: "dialogConfig", drawerConfig: "drawerConfig", showSubmitButton: "showSubmitButton", showCancelButton: "showCancelButton", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", submitButtonIcon: "submitButtonIcon", cancelButtonIcon: "cancelButtonIcon" }, outputs: { formReady: "formReady", formSubmit: "formSubmit", visibleChange: "visibleChange", onCancel: "onCancel", fieldSave: "fieldSave" }, usesOnChanges: true, ngImport: i0, template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div{min-width:0;overflow:hidden}.dynamic-form .grid>div ::ng-deep>*{display:block;width:100%;min-width:0}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i6$2.Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i9.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldTextComponent, selector: "sia-dynamic-field-text" }, { kind: "component", type: DynamicFieldNumberComponent, selector: "sia-dynamic-field-number" }, { kind: "component", type: DynamicFieldDateComponent, selector: "sia-dynamic-field-date" }, { kind: "component", type: DynamicFieldDatetimeComponent, selector: "sia-dynamic-field-datetime" }, { kind: "component", type: DynamicFieldDropdownComponent, selector: "sia-dynamic-field-dropdown" }, { kind: "component", type: DynamicFieldLookupComponent, selector: "sia-dynamic-field-lookup", inputs: ["field", "form", "formGroup", "mode"] }, { kind: "component", type: DynamicFieldTextareaComponent, selector: "sia-dynamic-field-textarea" }, { kind: "component", type: DynamicFieldTimeComponent, selector: "sia-dynamic-field-time" }, { kind: "component", type: DynamicFieldCheckboxComponent, selector: "sia-dynamic-field-checkbox" }, { kind: "component", type: DynamicFieldMultiselectComponent, selector: "sia-dynamic-field-multiselect" }, { kind: "component", type: DynamicFieldImageComponent, selector: "sia-dynamic-field-image" }] });
|
|
6847
7173
|
}
|
|
6848
7174
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, decorators: [{
|
|
6849
7175
|
type: Component,
|
|
@@ -6866,7 +7192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6866
7192
|
DynamicFieldCheckboxComponent,
|
|
6867
7193
|
DynamicFieldMultiselectComponent,
|
|
6868
7194
|
DynamicFieldImageComponent
|
|
6869
|
-
], template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"] }]
|
|
7195
|
+
], template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div{min-width:0;overflow:hidden}.dynamic-form .grid>div ::ng-deep>*{display:block;width:100%;min-width:0}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"] }]
|
|
6870
7196
|
}], ctorParameters: () => [{ type: i2$1.FormBuilder }, { type: TranslationService }, { type: MaskService }, { type: LocaleService }], propDecorators: { sections: [{
|
|
6871
7197
|
type: Input
|
|
6872
7198
|
}], entityData: [{
|