@memberjunction/ng-entity-viewer 5.11.0 → 5.13.0

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.
Files changed (36) hide show
  1. package/dist/lib/aggregate-panel/aggregate-panel.component.js +2 -2
  2. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +2 -2
  3. package/dist/lib/confirm-dialog/confirm-dialog.component.js +2 -2
  4. package/dist/lib/duplicate-view-dialog/duplicate-view-dialog.component.js +2 -2
  5. package/dist/lib/entity-cards/entity-cards.component.js +4 -4
  6. package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
  7. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +26 -3
  8. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  9. package/dist/lib/entity-data-grid/entity-data-grid.component.js +196 -137
  10. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  11. package/dist/lib/entity-data-grid/models/grid-types.js +4 -4
  12. package/dist/lib/entity-data-grid/models/grid-types.js.map +1 -1
  13. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +2 -2
  14. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +5 -4
  15. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  16. package/dist/lib/entity-viewer/entity-viewer.component.js +46 -69
  17. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  18. package/dist/lib/pill/pill.component.js +2 -2
  19. package/dist/lib/pill/pill.component.js.map +1 -1
  20. package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +2 -2
  21. package/dist/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.js +2 -2
  22. package/dist/lib/view-config-panel/view-config-panel.component.js +2 -2
  23. package/dist/lib/view-header/view-header.component.js +2 -2
  24. package/dist/module.d.ts +15 -16
  25. package/dist/module.d.ts.map +1 -1
  26. package/dist/module.js +4 -6
  27. package/dist/module.js.map +1 -1
  28. package/dist/public-api.d.ts +0 -1
  29. package/dist/public-api.d.ts.map +1 -1
  30. package/dist/public-api.js +0 -1
  31. package/dist/public-api.js.map +1 -1
  32. package/package.json +10 -9
  33. package/dist/lib/pagination/pagination.component.d.ts +0 -60
  34. package/dist/lib/pagination/pagination.component.d.ts.map +0 -1
  35. package/dist/lib/pagination/pagination.component.js +0 -201
  36. package/dist/lib/pagination/pagination.component.js.map +0 -1
@@ -333,11 +333,11 @@ export class AggregatePanelComponent {
333
333
  i0.ɵɵconditional(ctx.Collapsible ? 6 : -1);
334
334
  i0.ɵɵadvance();
335
335
  i0.ɵɵconditional(!ctx.IsCollapsed ? 7 : -1);
336
- } }, dependencies: [i1.NgStyle], styles: ["\n\n\n.aggregate-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-panel-bg, #ffffff);\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n\n\n.position-right[_ngcontent-%COMP%] {\n height: 100%;\n border-left-width: 1px;\n border-radius: 0 8px 8px 0;\n}\n\n.position-bottom[_ngcontent-%COMP%] {\n width: 100%;\n border-top-width: 1px;\n border-radius: 0 0 8px 8px;\n}\n\n\n\n.collapsed[_ngcontent-%COMP%] .panel-content[_ngcontent-%COMP%] {\n display: none;\n}\n\n.collapsed.position-right[_ngcontent-%COMP%] {\n width: auto !important;\n min-width: auto !important;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-panel-header-bg, #f8f9fa);\n border-bottom: 1px solid var(--mj-border-color, #e0e0e0);\n cursor: pointer;\n user-select: none;\n}\n\n.panel-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-panel-header-hover-bg, #f0f1f2);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary, #333333);\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.loading-indicator[_ngcontent-%COMP%] {\n color: var(--mj-primary-color, #007bff);\n font-size: 14px;\n}\n\n.collapse-toggle[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-secondary, #666666);\n font-size: 12px;\n border-radius: 4px;\n transition: background-color 0.2s, color 0.2s;\n}\n\n.collapse-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-button-hover-bg, rgba(0, 0, 0, 0.05));\n color: var(--mj-text-primary, #333333);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n flex: 1;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: var(--mj-text-muted, #999999);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n\n\n.cards-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.layout-horizontal[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.layout-vertical[_ngcontent-%COMP%] {\n flex-direction: column;\n}\n\n.layout-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 12px;\n}\n\n\n\n.aggregate-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n background: var(--mj-card-bg, #ffffff);\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;\n}\n\n.aggregate-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-primary-color, #007bff);\n box-shadow: 0 2px 8px rgba(0, 123, 255, 0.15);\n transform: translateY(-1px);\n}\n\n\n\n.card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-icon-bg, #f0f4f8);\n border-radius: 8px;\n color: var(--mj-primary-color, #007bff);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.card-value[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary, #333333);\n line-height: 1.2;\n margin-bottom: 4px;\n word-break: break-word;\n}\n\n.card-value.loading[_ngcontent-%COMP%] {\n color: var(--mj-text-muted, #999999);\n}\n\n.card-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary, #666666);\n line-height: 1.3;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.style-success[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-success-color, #28a745);\n}\n\n.style-success[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-success-color, #28a745);\n}\n\n.style-success[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-success-bg, #d4edda);\n color: var(--mj-success-color, #28a745);\n}\n\n.style-warning[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-warning-color, #ffc107);\n}\n\n.style-warning[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-warning-dark, #856404);\n}\n\n.style-warning[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-warning-bg, #fff3cd);\n color: var(--mj-warning-dark, #856404);\n}\n\n.style-danger[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-danger-color, #dc3545);\n}\n\n.style-danger[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-danger-color, #dc3545);\n}\n\n.style-danger[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-danger-bg, #f8d7da);\n color: var(--mj-danger-color, #dc3545);\n}\n\n.style-info[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-info-color, #17a2b8);\n}\n\n.style-info[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-info-color, #17a2b8);\n}\n\n.style-info[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-info-bg, #d1ecf1);\n color: var(--mj-info-color, #17a2b8);\n}\n\n.style-muted[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-muted-color, #6c757d);\n}\n\n.style-muted[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-muted-color, #6c757d);\n}\n\n.style-muted[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-muted-bg, #e9ecef);\n color: var(--mj-muted-color, #6c757d);\n}\n\n\n\n.position-bottom[_ngcontent-%COMP%] .cards-container.layout-vertical[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.position-bottom[_ngcontent-%COMP%] .cards-container.layout-vertical[_ngcontent-%COMP%] .aggregate-card[_ngcontent-%COMP%] {\n flex: 1 1 200px;\n max-width: 300px;\n}\n\n\n\n@media (prefers-color-scheme: dark) {\n .aggregate-panel[_ngcontent-%COMP%] {\n --mj-panel-bg: #1e1e1e;\n --mj-panel-header-bg: #252525;\n --mj-panel-header-hover-bg: #2a2a2a;\n --mj-border-color: #3c3c3c;\n --mj-text-primary: #ffffff;\n --mj-text-secondary: #b0b0b0;\n --mj-text-muted: #808080;\n --mj-card-bg: #252525;\n --mj-icon-bg: #333333;\n }\n}"] });
336
+ } }, dependencies: [i1.NgStyle], styles: ["\n\n\n.aggregate-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n\n\n.position-right[_ngcontent-%COMP%] {\n height: 100%;\n border-left-width: 1px;\n border-radius: 0 8px 8px 0;\n}\n\n.position-bottom[_ngcontent-%COMP%] {\n width: 100%;\n border-top-width: 1px;\n border-radius: 0 0 8px 8px;\n}\n\n\n\n.collapsed[_ngcontent-%COMP%] .panel-content[_ngcontent-%COMP%] {\n display: none;\n}\n\n.collapsed.position-right[_ngcontent-%COMP%] {\n width: auto !important;\n min-width: auto !important;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n}\n\n.panel-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.loading-indicator[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.collapse-toggle[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 12px;\n border-radius: 4px;\n transition: background-color 0.2s, color 0.2s;\n}\n\n.collapse-toggle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-primary);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n flex: 1;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n\n\n.cards-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.layout-horizontal[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.layout-vertical[_ngcontent-%COMP%] {\n flex-direction: column;\n}\n\n.layout-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 12px;\n}\n\n\n\n.aggregate-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;\n}\n\n.aggregate-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n transform: translateY(-1px);\n}\n\n\n\n.card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.card-value[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n margin-bottom: 4px;\n word-break: break-word;\n}\n\n.card-value.loading[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n\n.card-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.style-success[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.style-success[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.style-success[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.style-warning[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.style-warning[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text);\n}\n\n.style-warning[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.style-danger[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.style-danger[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.style-danger[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.style-info[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.style-info[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.style-info[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.style-muted[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-text-muted);\n}\n\n.style-muted[_ngcontent-%COMP%] .card-value[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.style-muted[_ngcontent-%COMP%] .card-icon[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n\n\n.position-bottom[_ngcontent-%COMP%] .cards-container.layout-vertical[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.position-bottom[_ngcontent-%COMP%] .cards-container.layout-vertical[_ngcontent-%COMP%] .aggregate-card[_ngcontent-%COMP%] {\n flex: 1 1 200px;\n max-width: 300px;\n}"] });
337
337
  }
338
338
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AggregatePanelComponent, [{
339
339
  type: Component,
340
- args: [{ standalone: false, selector: 'mj-aggregate-panel', template: "<div class=\"aggregate-panel\"\n [class.position-right]=\"Position === 'right'\"\n [class.position-bottom]=\"Position === 'bottom'\"\n [class.collapsed]=\"IsCollapsed\"\n [ngStyle]=\"PanelStyle\">\n\n <!-- Panel Header -->\n <div class=\"panel-header\" (click)=\"ToggleCollapse()\">\n <span class=\"panel-title\">{{ Title }}</span>\n\n <div class=\"panel-header-right\">\n <!-- Loading indicator -->\n @if (Loading) {\n <span class=\"loading-indicator\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </span>\n }\n\n <!-- Collapse toggle -->\n @if (Collapsible) {\n <button class=\"collapse-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-up]=\"!IsCollapsed\" [class.fa-chevron-down]=\"IsCollapsed\"></i>\n </button>\n }\n </div>\n </div>\n\n <!-- Panel Content -->\n @if (!IsCollapsed) {\n <div class=\"panel-content\">\n <!-- Empty state -->\n @if (CardAggregates.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <p>No summaries configured</p>\n </div>\n }\n <!-- Cards Container -->\n <div class=\"cards-container\"\n [class.layout-horizontal]=\"Layout === 'horizontal'\"\n [class.layout-vertical]=\"Layout === 'vertical'\"\n [class.layout-grid]=\"Layout === 'grid'\"\n [ngStyle]=\"Layout === 'grid' ? {'grid-template-columns': GridTemplateColumns} : {}\">\n <!-- Individual Aggregate Cards -->\n @for (agg of CardAggregates; track agg) {\n <div class=\"aggregate-card\"\n [class]=\"GetStyleClass(agg)\"\n (click)=\"OnAggregateClick(agg)\"\n [title]=\"agg.description || agg.label\">\n <!-- Icon -->\n @if (agg.icon) {\n <div class=\"card-icon\">\n <i [class]=\"agg.icon\"></i>\n </div>\n }\n <!-- Content -->\n <div class=\"card-content\">\n <div class=\"card-value\" [class.loading]=\"Loading\">\n {{ Loading ? '...' : FormatValue(agg) }}\n </div>\n <div class=\"card-label\">{{ agg.label }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: ["/* Aggregate Panel Component Styles */\n\n.aggregate-panel {\n display: flex;\n flex-direction: column;\n background: var(--mj-panel-bg, #ffffff);\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n/* Position variants */\n.position-right {\n height: 100%;\n border-left-width: 1px;\n border-radius: 0 8px 8px 0;\n}\n\n.position-bottom {\n width: 100%;\n border-top-width: 1px;\n border-radius: 0 0 8px 8px;\n}\n\n/* Collapsed state */\n.collapsed .panel-content {\n display: none;\n}\n\n.collapsed.position-right {\n width: auto !important;\n min-width: auto !important;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-panel-header-bg, #f8f9fa);\n border-bottom: 1px solid var(--mj-border-color, #e0e0e0);\n cursor: pointer;\n user-select: none;\n}\n\n.panel-header:hover {\n background: var(--mj-panel-header-hover-bg, #f0f1f2);\n}\n\n.panel-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary, #333333);\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.loading-indicator {\n color: var(--mj-primary-color, #007bff);\n font-size: 14px;\n}\n\n.collapse-toggle {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-secondary, #666666);\n font-size: 12px;\n border-radius: 4px;\n transition: background-color 0.2s, color 0.2s;\n}\n\n.collapse-toggle:hover {\n background: var(--mj-button-hover-bg, rgba(0, 0, 0, 0.05));\n color: var(--mj-text-primary, #333333);\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n overflow-y: auto;\n flex: 1;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: var(--mj-text-muted, #999999);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 13px;\n}\n\n/* Cards Container */\n.cards-container {\n display: flex;\n gap: 12px;\n}\n\n.layout-horizontal {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.layout-vertical {\n flex-direction: column;\n}\n\n.layout-grid {\n display: grid;\n gap: 12px;\n}\n\n/* Aggregate Card */\n.aggregate-card {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n background: var(--mj-card-bg, #ffffff);\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;\n}\n\n.aggregate-card:hover {\n border-color: var(--mj-primary-color, #007bff);\n box-shadow: 0 2px 8px rgba(0, 123, 255, 0.15);\n transform: translateY(-1px);\n}\n\n/* Card Icon */\n.card-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-icon-bg, #f0f4f8);\n border-radius: 8px;\n color: var(--mj-primary-color, #007bff);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n/* Card Content */\n.card-content {\n flex: 1;\n min-width: 0;\n}\n\n.card-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary, #333333);\n line-height: 1.2;\n margin-bottom: 4px;\n word-break: break-word;\n}\n\n.card-value.loading {\n color: var(--mj-text-muted, #999999);\n}\n\n.card-label {\n font-size: 12px;\n color: var(--mj-text-secondary, #666666);\n line-height: 1.3;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Conditional Style Classes */\n.style-success {\n border-left: 4px solid var(--mj-success-color, #28a745);\n}\n\n.style-success .card-value {\n color: var(--mj-success-color, #28a745);\n}\n\n.style-success .card-icon {\n background: var(--mj-success-bg, #d4edda);\n color: var(--mj-success-color, #28a745);\n}\n\n.style-warning {\n border-left: 4px solid var(--mj-warning-color, #ffc107);\n}\n\n.style-warning .card-value {\n color: var(--mj-warning-dark, #856404);\n}\n\n.style-warning .card-icon {\n background: var(--mj-warning-bg, #fff3cd);\n color: var(--mj-warning-dark, #856404);\n}\n\n.style-danger {\n border-left: 4px solid var(--mj-danger-color, #dc3545);\n}\n\n.style-danger .card-value {\n color: var(--mj-danger-color, #dc3545);\n}\n\n.style-danger .card-icon {\n background: var(--mj-danger-bg, #f8d7da);\n color: var(--mj-danger-color, #dc3545);\n}\n\n.style-info {\n border-left: 4px solid var(--mj-info-color, #17a2b8);\n}\n\n.style-info .card-value {\n color: var(--mj-info-color, #17a2b8);\n}\n\n.style-info .card-icon {\n background: var(--mj-info-bg, #d1ecf1);\n color: var(--mj-info-color, #17a2b8);\n}\n\n.style-muted {\n border-left: 4px solid var(--mj-muted-color, #6c757d);\n}\n\n.style-muted .card-value {\n color: var(--mj-muted-color, #6c757d);\n}\n\n.style-muted .card-icon {\n background: var(--mj-muted-bg, #e9ecef);\n color: var(--mj-muted-color, #6c757d);\n}\n\n/* Responsive adjustments for bottom position */\n.position-bottom .cards-container.layout-vertical {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.position-bottom .cards-container.layout-vertical .aggregate-card {\n flex: 1 1 200px;\n max-width: 300px;\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .aggregate-panel {\n --mj-panel-bg: #1e1e1e;\n --mj-panel-header-bg: #252525;\n --mj-panel-header-hover-bg: #2a2a2a;\n --mj-border-color: #3c3c3c;\n --mj-text-primary: #ffffff;\n --mj-text-secondary: #b0b0b0;\n --mj-text-muted: #808080;\n --mj-card-bg: #252525;\n --mj-icon-bg: #333333;\n }\n}\n"] }]
340
+ args: [{ standalone: false, selector: 'mj-aggregate-panel', template: "<div class=\"aggregate-panel\"\n [class.position-right]=\"Position === 'right'\"\n [class.position-bottom]=\"Position === 'bottom'\"\n [class.collapsed]=\"IsCollapsed\"\n [ngStyle]=\"PanelStyle\">\n\n <!-- Panel Header -->\n <div class=\"panel-header\" (click)=\"ToggleCollapse()\">\n <span class=\"panel-title\">{{ Title }}</span>\n\n <div class=\"panel-header-right\">\n <!-- Loading indicator -->\n @if (Loading) {\n <span class=\"loading-indicator\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </span>\n }\n\n <!-- Collapse toggle -->\n @if (Collapsible) {\n <button class=\"collapse-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-up]=\"!IsCollapsed\" [class.fa-chevron-down]=\"IsCollapsed\"></i>\n </button>\n }\n </div>\n </div>\n\n <!-- Panel Content -->\n @if (!IsCollapsed) {\n <div class=\"panel-content\">\n <!-- Empty state -->\n @if (CardAggregates.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <p>No summaries configured</p>\n </div>\n }\n <!-- Cards Container -->\n <div class=\"cards-container\"\n [class.layout-horizontal]=\"Layout === 'horizontal'\"\n [class.layout-vertical]=\"Layout === 'vertical'\"\n [class.layout-grid]=\"Layout === 'grid'\"\n [ngStyle]=\"Layout === 'grid' ? {'grid-template-columns': GridTemplateColumns} : {}\">\n <!-- Individual Aggregate Cards -->\n @for (agg of CardAggregates; track agg) {\n <div class=\"aggregate-card\"\n [class]=\"GetStyleClass(agg)\"\n (click)=\"OnAggregateClick(agg)\"\n [title]=\"agg.description || agg.label\">\n <!-- Icon -->\n @if (agg.icon) {\n <div class=\"card-icon\">\n <i [class]=\"agg.icon\"></i>\n </div>\n }\n <!-- Content -->\n <div class=\"card-content\">\n <div class=\"card-value\" [class.loading]=\"Loading\">\n {{ Loading ? '...' : FormatValue(agg) }}\n </div>\n <div class=\"card-label\">{{ agg.label }}</div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: ["/* Aggregate Panel Component Styles */\n\n.aggregate-panel {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n/* Position variants */\n.position-right {\n height: 100%;\n border-left-width: 1px;\n border-radius: 0 8px 8px 0;\n}\n\n.position-bottom {\n width: 100%;\n border-top-width: 1px;\n border-radius: 0 0 8px 8px;\n}\n\n/* Collapsed state */\n.collapsed .panel-content {\n display: none;\n}\n\n.collapsed.position-right {\n width: auto !important;\n min-width: auto !important;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n}\n\n.panel-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.panel-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.loading-indicator {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.collapse-toggle {\n background: none;\n border: none;\n padding: 4px 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 12px;\n border-radius: 4px;\n transition: background-color 0.2s, color 0.2s;\n}\n\n.collapse-toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-primary);\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n overflow-y: auto;\n flex: 1;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n color: var(--mj-text-disabled);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 13px;\n}\n\n/* Cards Container */\n.cards-container {\n display: flex;\n gap: 12px;\n}\n\n.layout-horizontal {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.layout-vertical {\n flex-direction: column;\n}\n\n.layout-grid {\n display: grid;\n gap: 12px;\n}\n\n/* Aggregate Card */\n.aggregate-card {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;\n}\n\n.aggregate-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n transform: translateY(-1px);\n}\n\n/* Card Icon */\n.card-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n/* Card Content */\n.card-content {\n flex: 1;\n min-width: 0;\n}\n\n.card-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n margin-bottom: 4px;\n word-break: break-word;\n}\n\n.card-value.loading {\n color: var(--mj-text-disabled);\n}\n\n.card-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Conditional Style Classes */\n.style-success {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.style-success .card-value {\n color: var(--mj-status-success);\n}\n\n.style-success .card-icon {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.style-warning {\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.style-warning .card-value {\n color: var(--mj-status-warning-text);\n}\n\n.style-warning .card-icon {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.style-danger {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.style-danger .card-value {\n color: var(--mj-status-error);\n}\n\n.style-danger .card-icon {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.style-info {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.style-info .card-value {\n color: var(--mj-brand-primary);\n}\n\n.style-info .card-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.style-muted {\n border-left: 4px solid var(--mj-text-muted);\n}\n\n.style-muted .card-value {\n color: var(--mj-text-muted);\n}\n\n.style-muted .card-icon {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n/* Responsive adjustments for bottom position */\n.position-bottom .cards-container.layout-vertical {\n flex-direction: row;\n flex-wrap: wrap;\n}\n\n.position-bottom .cards-container.layout-vertical .aggregate-card {\n flex: 1 1 200px;\n max-width: 300px;\n}\n"] }]
341
341
  }], null, { Aggregates: [{
342
342
  type: Input
343
343
  }], Values: [{
@@ -931,11 +931,11 @@ export class AggregateSetupDialogComponent {
931
931
  i0.ɵɵtextInterpolate1("", ctx.Aggregate ? "Update" : "Add", " Aggregate");
932
932
  i0.ɵɵadvance(3);
933
933
  i0.ɵɵconditional(ctx.ValidationMessage ? 74 : -1);
934
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n font-size: 18px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n color: #374151;\n}\n\n\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: #f8fafc;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #fafafa;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #6b7280;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n\n\n.mode-content[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.mode-description[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: #0369a1;\n line-height: 1.5;\n}\n\n.mode-description[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0284c7;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 18px;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.form-label.required[_ngcontent-%COMP%]::after {\n content: ' *';\n color: #dc2626;\n}\n\n.form-label[_ngcontent-%COMP%] .optional[_ngcontent-%COMP%] {\n font-weight: 400;\n color: #9ca3af;\n}\n\n.form-label.examples-label[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n\n\n.form-input[_ngcontent-%COMP%], \n.form-select[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: white;\n}\n\n.form-input[_ngcontent-%COMP%]:focus, \n.form-select[_ngcontent-%COMP%]:focus, \n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input[_ngcontent-%COMP%] {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n\n\n.function-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.function-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.function-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #6b7280;\n}\n\n.function-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.function-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n}\n\n.function-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n\n\n.field-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: #f8fafc;\n border-radius: 6px;\n font-size: 12px;\n color: #64748b;\n}\n\n.field-hint.warning[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: #92400e;\n}\n\n.field-hint.warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.field-hint.info[_ngcontent-%COMP%] {\n background: #eff6ff;\n color: #1e40af;\n}\n\n.field-hint.info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.field-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n.expression-preview[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #1e293b;\n}\n\n\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n\n\n.smart-input-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input[_ngcontent-%COMP%] {\n min-height: 100px;\n}\n\n.smart-input[_ngcontent-%COMP%]:disabled {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.generate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border: none;\n border-radius: 10px;\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n.generate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n\n\n.generated-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 16px;\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border: 1px solid #86efac;\n border-radius: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] .form-label[_ngcontent-%COMP%] {\n margin-bottom: 0;\n color: #166534;\n}\n\n.clear-generated-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #86efac;\n border-radius: 6px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #166534;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn[_ngcontent-%COMP%]:hover {\n background: #166534;\n color: white;\n}\n\n.generated-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #86efac;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #14532d;\n margin-bottom: 10px;\n}\n\n.generated-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: #166534;\n}\n\n.generated-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 1px;\n}\n\n\n\n.smart-tips[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding: 14px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n border-radius: 10px;\n}\n\n.tips-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #92400e;\n}\n\n.tips-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.tips-list[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: #78350f;\n line-height: 1.6;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n padding-top: 16px;\n}\n\n.section-divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider[_ngcontent-%COMP%]::before, \n.section-divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: #e5e7eb;\n}\n\n.section-divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #9ca3af;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.display-type-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.display-type-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: #6b7280;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.display-type-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n.display-type-btn[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n color: #60a5fa;\n}\n\n\n\n.icon-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #eff6ff;\n border: 1px solid #93c5fd;\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 20px;\n color: #3b82f6;\n}\n\n.clear-icon-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n border: none;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n color: #9ca3af;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn[_ngcontent-%COMP%]:hover {\n background: #dc2626;\n color: white;\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.icon-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.icon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #6b7280;\n}\n\n.icon-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid #d1d5db;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f3f4f6;\n border-color: #9ca3af;\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-color: #3b82f6;\n color: white;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border-color: #2563eb;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n\n\n.validation-message[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.validation-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n@media (max-width: 600px) {\n .dialog-panel[_ngcontent-%COMP%] {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header[_ngcontent-%COMP%], \n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn[_ngcontent-%COMP%] {\n padding: 10px 8px;\n }\n\n .mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .function-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"] });
934
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 16px 16px 0 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-color-info-700);\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n\n\n.mode-content[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.mode-description[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: var(--mj-color-info-700);\n line-height: 1.5;\n}\n\n.mode-description[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 18px;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-label.required[_ngcontent-%COMP%]::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-label[_ngcontent-%COMP%] .optional[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--mj-text-disabled);\n}\n\n.form-label.examples-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.form-input[_ngcontent-%COMP%], \n.form-select[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: var(--mj-bg-surface);\n}\n\n.form-input[_ngcontent-%COMP%]:focus, \n.form-select[_ngcontent-%COMP%]:focus, \n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input[_ngcontent-%COMP%] {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n\n\n.function-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.function-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.function-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.function-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.function-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.function-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-color-info-700);\n}\n\n\n\n.field-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.field-hint.warning[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.field-hint.warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.field-hint.info[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.field-hint.info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.field-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n.expression-preview[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-color-info-700);\n}\n\n\n\n.smart-input-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input[_ngcontent-%COMP%] {\n min-height: 100px;\n}\n\n.smart-input[_ngcontent-%COMP%]:disabled {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.generate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.generate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n\n\n.generated-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 16px;\n background: var(--mj-status-success-bg);\n border: 1px solid var(--mj-status-success-border);\n border-radius: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header[_ngcontent-%COMP%] .form-label[_ngcontent-%COMP%] {\n margin-bottom: 0;\n color: var(--mj-status-success-text);\n}\n\n.clear-generated-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-status-success-border);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-success-text);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-success-text);\n color: var(--mj-text-inverse);\n}\n\n.generated-code[_ngcontent-%COMP%] {\n display: block;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-status-success-border);\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: var(--mj-status-success-text);\n margin-bottom: 10px;\n}\n\n.generated-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-status-success-text);\n}\n\n.generated-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 1px;\n}\n\n\n\n.smart-tips[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding: 14px;\n background: var(--mj-status-warning-bg);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: 10px;\n}\n\n.tips-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-status-warning-text);\n}\n\n.tips-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.tips-list[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: var(--mj-status-warning-text);\n line-height: 1.6;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n padding-top: 16px;\n}\n\n.section-divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider[_ngcontent-%COMP%]::before, \n.section-divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.section-divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.display-type-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.display-type-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--mj-text-muted);\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.display-type-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-color-info-700);\n}\n\n.display-type-btn[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.display-type-btn.active[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.icon-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.clear-icon-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n border: none;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n cursor: pointer;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.icon-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.icon-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-muted);\n}\n\n.icon-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-color-info-600);\n border-color: var(--mj-color-info-600);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n\n\n.validation-message[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.validation-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n@media (max-width: 600px) {\n .dialog-panel[_ngcontent-%COMP%] {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header[_ngcontent-%COMP%], \n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn[_ngcontent-%COMP%] {\n padding: 10px 8px;\n }\n\n .mode-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .function-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"] });
935
935
  }
936
936
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AggregateSetupDialogComponent, [{
937
937
  type: Component,
938
- args: [{ standalone: false, selector: 'mj-aggregate-setup-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Aggregate ? 'Edit Aggregate' : 'Add Aggregate' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'simple'\"\n (click)=\"setMode('simple')\"\n title=\"Pick a column and function\">\n <i class=\"fa-solid fa-wand-sparkles\"></i>\n <span>Simple</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'advanced'\"\n (click)=\"setMode('advanced')\"\n title=\"Write custom SQL expression\">\n <i class=\"fa-solid fa-code\"></i>\n <span>Advanced</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'smart'\"\n (click)=\"setMode('smart')\"\n title=\"Describe in natural language\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart</span>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Simple Mode -->\n @if (Mode === 'simple') {\n <div class=\"mode-content simple-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Select a column and an aggregate function to calculate</span>\n </div>\n\n <!-- Function Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Function</label>\n <div class=\"function-grid\">\n @for (func of AggregateFunctions; track func.value) {\n <button\n class=\"function-btn\"\n [class.active]=\"SelectedFunction === func.value\"\n (click)=\"selectFunction(func.value)\"\n [title]=\"func.label\">\n <i [class]=\"func.icon\"></i>\n <span>{{ func.label }}</span>\n </button>\n }\n </div>\n </div>\n\n <!-- Column Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Column</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"SelectedColumn\"\n (ngModelChange)=\"onColumnSelected($event)\">\n <option value=\"\">Select a column...</option>\n @for (field of AvailableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ getFieldDisplayLabel(field) }}</option>\n }\n </select>\n @if (SelectedFunction !== 'COUNT' && SelectedFunction !== 'COUNT_DISTINCT' && NumericFields.length === 0) {\n <div class=\"field-hint warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>No numeric fields available. Use COUNT or switch to Advanced mode.</span>\n </div>\n }\n @if (SelectedFunction === 'COUNT' && !SelectedColumn) {\n <div class=\"field-hint info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No column selected - will count all records (COUNT(*))</span>\n </div>\n }\n </div>\n\n <!-- Preview -->\n @if (SelectedFunction && (SelectedColumn || SelectedFunction === 'COUNT')) {\n <div class=\"expression-preview\">\n <label class=\"preview-label\">Expression Preview</label>\n <code class=\"preview-code\">{{\n !SelectedColumn && SelectedFunction === 'COUNT' ? 'COUNT(*)' :\n SelectedFunction === 'COUNT_DISTINCT' ? 'COUNT(DISTINCT ' + SelectedColumn + ')' :\n SelectedFunction + '(' + SelectedColumn + ')'\n }}</code>\n </div>\n }\n </div>\n }\n\n <!-- Advanced Mode -->\n @if (Mode === 'advanced') {\n <div class=\"mode-content advanced-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Write a custom SQL aggregate expression. Use field names as they appear in the database.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">SQL Expression</label>\n <textarea\n class=\"form-textarea code-input\"\n [(ngModel)]=\"Expression\"\n placeholder=\"e.g., SUM(Amount * Quantity) or COUNT(CASE WHEN Status = 'Active' THEN 1 END)\"\n rows=\"3\"\n ></textarea>\n <div class=\"field-hint\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use brackets for column names with spaces, e.g., [Total Amount]</span>\n </div>\n </div>\n\n <!-- Quick Examples -->\n <div class=\"form-section\">\n <label class=\"form-label examples-label\">Quick Examples</label>\n <div class=\"example-chips\">\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(Amount)'\">\n SUM(Amount)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'AVG(Price * Quantity)'\">\n AVG(Price * Quantity)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'COUNT(CASE WHEN Status = \\'Active\\' THEN 1 END)'\">\n COUNT with condition\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(CASE WHEN Type = \\'Credit\\' THEN Amount ELSE -Amount END)'\">\n Conditional SUM\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Smart Mode -->\n @if (Mode === 'smart') {\n <div class=\"mode-content smart-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Describe what you want to calculate in plain English. AI will generate the expression.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">What would you like to calculate?</label>\n <div class=\"smart-input-container\">\n <textarea\n class=\"form-textarea smart-input\"\n [(ngModel)]=\"SmartPrompt\"\n [disabled]=\"!!GeneratedExpression\"\n placeholder=\"e.g., 'Total revenue from completed orders' or 'Average order value for premium customers'\"\n rows=\"3\"\n ></textarea>\n @if (!GeneratedExpression) {\n <button\n class=\"generate-btn\"\n [disabled]=\"!SmartPrompt.trim() || IsGenerating\"\n (click)=\"onGenerateFromPrompt()\">\n @if (IsGenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Generating...</span>\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Generate</span>\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Generated Expression -->\n @if (GeneratedExpression) {\n <div class=\"generated-section\">\n <div class=\"generated-header\">\n <label class=\"form-label\">Generated Expression</label>\n <button class=\"clear-generated-btn\" (click)=\"clearGeneratedExpression()\" title=\"Edit prompt\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit Prompt</span>\n </button>\n </div>\n <code class=\"generated-code\">{{ GeneratedExpression }}</code>\n <div class=\"generated-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>This expression was generated from your description. Clear it to edit the prompt.</span>\n </div>\n </div>\n }\n\n <!-- Smart Mode Tips -->\n <div class=\"smart-tips\">\n <div class=\"tips-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tips for better results:</span>\n </div>\n <ul class=\"tips-list\">\n <li>Be specific about which fields to use</li>\n <li>Mention any conditions or filters</li>\n <li>Specify the type of calculation (sum, average, count, etc.)</li>\n </ul>\n </div>\n </div>\n }\n\n <!-- Common Configuration -->\n <div class=\"config-section\">\n <div class=\"section-divider\">\n <span>Display Options</span>\n </div>\n\n <!-- Label -->\n <div class=\"form-section\">\n <label class=\"form-label required\">Label</label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Label\"\n placeholder=\"e.g., Total Revenue, Average Order Value\"\n />\n </div>\n\n <!-- Description (optional) -->\n <div class=\"form-section\">\n <label class=\"form-label\">Description <span class=\"optional\">(optional)</span></label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Description\"\n placeholder=\"Brief explanation of what this shows\"\n />\n </div>\n\n <!-- Display Type -->\n <div class=\"form-section\">\n <label class=\"form-label\">Display As</label>\n <div class=\"display-type-toggle\">\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'card'\"\n (click)=\"DisplayType = 'card'\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>Card</span>\n <small>Shows in summary panel</small>\n </button>\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'column'\"\n (click)=\"DisplayType = 'column'\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>Column Footer</span>\n <small>Shows at bottom of grid</small>\n </button>\n </div>\n </div>\n\n <!-- Icon Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Icon <span class=\"optional\">(optional)</span></label>\n <div class=\"icon-selector\">\n @if (Icon) {\n <div class=\"selected-icon\">\n <i [class]=\"Icon\"></i>\n <button class=\"clear-icon-btn\" (click)=\"clearIcon()\" title=\"Remove icon\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n <div class=\"icon-grid\">\n @for (icon of CommonIcons; track icon) {\n <button\n class=\"icon-btn\"\n [class.active]=\"Icon === icon\"\n (click)=\"selectIcon(icon)\"\n [title]=\"icon\">\n <i [class]=\"icon\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n <button\n class=\"footer-btn save-btn primary\"\n [disabled]=\"!IsValid\"\n (click)=\"onSave()\">\n <i class=\"fa-solid fa-check\"></i>\n <span>{{ Aggregate ? 'Update' : 'Add' }} Aggregate</span>\n </button>\n </div>\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n\n <!-- Validation Message -->\n @if (ValidationMessage) {\n <div class=\"validation-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ ValidationMessage }}</span>\n </div>\n }\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title i {\n color: #3b82f6;\n font-size: 18px;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: #e5e7eb;\n color: #374151;\n}\n\n/* Mode Selector */\n.mode-selector {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: #f8fafc;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.mode-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn:hover {\n border-color: #d1d5db;\n background: #fafafa;\n}\n\n.mode-btn.active {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.mode-btn i {\n font-size: 18px;\n color: #6b7280;\n}\n\n.mode-btn.active i {\n color: #3b82f6;\n}\n\n.mode-btn span {\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.mode-btn.active span {\n color: #1d4ed8;\n}\n\n/* Dialog Content */\n.dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n/* Mode Content */\n.mode-content {\n margin-bottom: 20px;\n}\n\n.mode-description {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: #0369a1;\n line-height: 1.5;\n}\n\n.mode-description i {\n color: #0284c7;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Form Sections */\n.form-section {\n margin-bottom: 18px;\n}\n\n.form-label {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n}\n\n.form-label.required::after {\n content: ' *';\n color: #dc2626;\n}\n\n.form-label .optional {\n font-weight: 400;\n color: #9ca3af;\n}\n\n.form-label.examples-label {\n color: #6b7280;\n}\n\n/* Form Inputs */\n.form-input,\n.form-select,\n.form-textarea {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: white;\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n/* Function Grid */\n.function-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.function-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.function-btn i {\n font-size: 18px;\n color: #6b7280;\n}\n\n.function-btn.active i {\n color: #3b82f6;\n}\n\n.function-btn span {\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n}\n\n.function-btn.active span {\n color: #1d4ed8;\n}\n\n/* Field Hint */\n.field-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: #f8fafc;\n border-radius: 6px;\n font-size: 12px;\n color: #64748b;\n}\n\n.field-hint.warning {\n background: #fffbeb;\n color: #92400e;\n}\n\n.field-hint.warning i {\n color: #f59e0b;\n}\n\n.field-hint.info {\n background: #eff6ff;\n color: #1e40af;\n}\n\n.field-hint.info i {\n color: #3b82f6;\n}\n\n.field-hint i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Expression Preview */\n.expression-preview {\n margin-top: 16px;\n padding: 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n}\n\n.preview-label {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #1e293b;\n}\n\n/* Example Chips */\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n/* Smart Mode Input */\n.smart-input-container {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input {\n min-height: 100px;\n}\n\n.smart-input:disabled {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.generate-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border: none;\n border-radius: 10px;\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n.generate-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n/* Generated Section */\n.generated-section {\n margin-top: 16px;\n padding: 16px;\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border: 1px solid #86efac;\n border-radius: 10px;\n}\n\n.generated-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header .form-label {\n margin-bottom: 0;\n color: #166534;\n}\n\n.clear-generated-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid #86efac;\n border-radius: 6px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #166534;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn:hover {\n background: #166534;\n color: white;\n}\n\n.generated-code {\n display: block;\n padding: 12px 14px;\n background: white;\n border: 1px solid #86efac;\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: #14532d;\n margin-bottom: 10px;\n}\n\n.generated-info {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: #166534;\n}\n\n.generated-info i {\n margin-top: 1px;\n}\n\n/* Smart Tips */\n.smart-tips {\n margin-top: 20px;\n padding: 14px;\n background: #fffbeb;\n border: 1px solid #fde68a;\n border-radius: 10px;\n}\n\n.tips-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #92400e;\n}\n\n.tips-header i {\n color: #f59e0b;\n}\n\n.tips-list {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: #78350f;\n line-height: 1.6;\n}\n\n/* Config Section */\n.config-section {\n padding-top: 16px;\n}\n\n.section-divider {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider::before,\n.section-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: #e5e7eb;\n}\n\n.section-divider span {\n font-size: 12px;\n font-weight: 600;\n color: #9ca3af;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Display Type Toggle */\n.display-type-toggle {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.display-type-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.display-type-btn i {\n font-size: 22px;\n color: #6b7280;\n}\n\n.display-type-btn.active i {\n color: #3b82f6;\n}\n\n.display-type-btn span {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n}\n\n.display-type-btn.active span {\n color: #1d4ed8;\n}\n\n.display-type-btn small {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.display-type-btn.active small {\n color: #60a5fa;\n}\n\n/* Icon Selector */\n.icon-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: #eff6ff;\n border: 1px solid #93c5fd;\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon i:first-child {\n font-size: 20px;\n color: #3b82f6;\n}\n\n.clear-icon-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n color: #9ca3af;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn:hover {\n background: #dc2626;\n color: white;\n}\n\n.icon-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn:hover {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.icon-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.icon-btn i {\n font-size: 16px;\n color: #6b7280;\n}\n\n.icon-btn.active i {\n color: #3b82f6;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid #d1d5db;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: #f3f4f6;\n border-color: #9ca3af;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-color: #3b82f6;\n color: white;\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border-color: #2563eb;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);\n}\n\n/* Validation Message */\n.validation-message {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.validation-message i {\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 600px) {\n .dialog-panel {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header,\n .dialog-footer {\n border-radius: 0;\n }\n\n .dialog-header {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn {\n padding: 10px 8px;\n }\n\n .mode-btn span {\n font-size: 11px;\n }\n\n .function-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle {\n flex-direction: column;\n }\n}\n"] }]
938
+ args: [{ standalone: false, selector: 'mj-aggregate-setup-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Aggregate ? 'Edit Aggregate' : 'Add Aggregate' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'simple'\"\n (click)=\"setMode('simple')\"\n title=\"Pick a column and function\">\n <i class=\"fa-solid fa-wand-sparkles\"></i>\n <span>Simple</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'advanced'\"\n (click)=\"setMode('advanced')\"\n title=\"Write custom SQL expression\">\n <i class=\"fa-solid fa-code\"></i>\n <span>Advanced</span>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"Mode === 'smart'\"\n (click)=\"setMode('smart')\"\n title=\"Describe in natural language\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart</span>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Simple Mode -->\n @if (Mode === 'simple') {\n <div class=\"mode-content simple-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Select a column and an aggregate function to calculate</span>\n </div>\n\n <!-- Function Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Function</label>\n <div class=\"function-grid\">\n @for (func of AggregateFunctions; track func.value) {\n <button\n class=\"function-btn\"\n [class.active]=\"SelectedFunction === func.value\"\n (click)=\"selectFunction(func.value)\"\n [title]=\"func.label\">\n <i [class]=\"func.icon\"></i>\n <span>{{ func.label }}</span>\n </button>\n }\n </div>\n </div>\n\n <!-- Column Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Column</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"SelectedColumn\"\n (ngModelChange)=\"onColumnSelected($event)\">\n <option value=\"\">Select a column...</option>\n @for (field of AvailableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ getFieldDisplayLabel(field) }}</option>\n }\n </select>\n @if (SelectedFunction !== 'COUNT' && SelectedFunction !== 'COUNT_DISTINCT' && NumericFields.length === 0) {\n <div class=\"field-hint warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>No numeric fields available. Use COUNT or switch to Advanced mode.</span>\n </div>\n }\n @if (SelectedFunction === 'COUNT' && !SelectedColumn) {\n <div class=\"field-hint info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No column selected - will count all records (COUNT(*))</span>\n </div>\n }\n </div>\n\n <!-- Preview -->\n @if (SelectedFunction && (SelectedColumn || SelectedFunction === 'COUNT')) {\n <div class=\"expression-preview\">\n <label class=\"preview-label\">Expression Preview</label>\n <code class=\"preview-code\">{{\n !SelectedColumn && SelectedFunction === 'COUNT' ? 'COUNT(*)' :\n SelectedFunction === 'COUNT_DISTINCT' ? 'COUNT(DISTINCT ' + SelectedColumn + ')' :\n SelectedFunction + '(' + SelectedColumn + ')'\n }}</code>\n </div>\n }\n </div>\n }\n\n <!-- Advanced Mode -->\n @if (Mode === 'advanced') {\n <div class=\"mode-content advanced-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Write a custom SQL aggregate expression. Use field names as they appear in the database.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">SQL Expression</label>\n <textarea\n class=\"form-textarea code-input\"\n [(ngModel)]=\"Expression\"\n placeholder=\"e.g., SUM(Amount * Quantity) or COUNT(CASE WHEN Status = 'Active' THEN 1 END)\"\n rows=\"3\"\n ></textarea>\n <div class=\"field-hint\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tip: Use brackets for column names with spaces, e.g., [Total Amount]</span>\n </div>\n </div>\n\n <!-- Quick Examples -->\n <div class=\"form-section\">\n <label class=\"form-label examples-label\">Quick Examples</label>\n <div class=\"example-chips\">\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(Amount)'\">\n SUM(Amount)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'AVG(Price * Quantity)'\">\n AVG(Price * Quantity)\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'COUNT(CASE WHEN Status = \\'Active\\' THEN 1 END)'\">\n COUNT with condition\n </button>\n <button class=\"example-chip\" (click)=\"Expression = 'SUM(CASE WHEN Type = \\'Credit\\' THEN Amount ELSE -Amount END)'\">\n Conditional SUM\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Smart Mode -->\n @if (Mode === 'smart') {\n <div class=\"mode-content smart-mode\">\n <div class=\"mode-description\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Describe what you want to calculate in plain English. AI will generate the expression.</span>\n </div>\n\n <div class=\"form-section\">\n <label class=\"form-label\">What would you like to calculate?</label>\n <div class=\"smart-input-container\">\n <textarea\n class=\"form-textarea smart-input\"\n [(ngModel)]=\"SmartPrompt\"\n [disabled]=\"!!GeneratedExpression\"\n placeholder=\"e.g., 'Total revenue from completed orders' or 'Average order value for premium customers'\"\n rows=\"3\"\n ></textarea>\n @if (!GeneratedExpression) {\n <button\n class=\"generate-btn\"\n [disabled]=\"!SmartPrompt.trim() || IsGenerating\"\n (click)=\"onGenerateFromPrompt()\">\n @if (IsGenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Generating...</span>\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Generate</span>\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Generated Expression -->\n @if (GeneratedExpression) {\n <div class=\"generated-section\">\n <div class=\"generated-header\">\n <label class=\"form-label\">Generated Expression</label>\n <button class=\"clear-generated-btn\" (click)=\"clearGeneratedExpression()\" title=\"Edit prompt\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit Prompt</span>\n </button>\n </div>\n <code class=\"generated-code\">{{ GeneratedExpression }}</code>\n <div class=\"generated-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>This expression was generated from your description. Clear it to edit the prompt.</span>\n </div>\n </div>\n }\n\n <!-- Smart Mode Tips -->\n <div class=\"smart-tips\">\n <div class=\"tips-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Tips for better results:</span>\n </div>\n <ul class=\"tips-list\">\n <li>Be specific about which fields to use</li>\n <li>Mention any conditions or filters</li>\n <li>Specify the type of calculation (sum, average, count, etc.)</li>\n </ul>\n </div>\n </div>\n }\n\n <!-- Common Configuration -->\n <div class=\"config-section\">\n <div class=\"section-divider\">\n <span>Display Options</span>\n </div>\n\n <!-- Label -->\n <div class=\"form-section\">\n <label class=\"form-label required\">Label</label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Label\"\n placeholder=\"e.g., Total Revenue, Average Order Value\"\n />\n </div>\n\n <!-- Description (optional) -->\n <div class=\"form-section\">\n <label class=\"form-label\">Description <span class=\"optional\">(optional)</span></label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"Description\"\n placeholder=\"Brief explanation of what this shows\"\n />\n </div>\n\n <!-- Display Type -->\n <div class=\"form-section\">\n <label class=\"form-label\">Display As</label>\n <div class=\"display-type-toggle\">\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'card'\"\n (click)=\"DisplayType = 'card'\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>Card</span>\n <small>Shows in summary panel</small>\n </button>\n <button\n class=\"display-type-btn\"\n [class.active]=\"DisplayType === 'column'\"\n (click)=\"DisplayType = 'column'\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>Column Footer</span>\n <small>Shows at bottom of grid</small>\n </button>\n </div>\n </div>\n\n <!-- Icon Selection -->\n <div class=\"form-section\">\n <label class=\"form-label\">Icon <span class=\"optional\">(optional)</span></label>\n <div class=\"icon-selector\">\n @if (Icon) {\n <div class=\"selected-icon\">\n <i [class]=\"Icon\"></i>\n <button class=\"clear-icon-btn\" (click)=\"clearIcon()\" title=\"Remove icon\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n <div class=\"icon-grid\">\n @for (icon of CommonIcons; track icon) {\n <button\n class=\"icon-btn\"\n [class.active]=\"Icon === icon\"\n (click)=\"selectIcon(icon)\"\n [title]=\"icon\">\n <i [class]=\"icon\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n <button\n class=\"footer-btn save-btn primary\"\n [disabled]=\"!IsValid\"\n (click)=\"onSave()\">\n <i class=\"fa-solid fa-check\"></i>\n <span>{{ Aggregate ? 'Update' : 'Add' }} Aggregate</span>\n </button>\n </div>\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n\n <!-- Validation Message -->\n @if (ValidationMessage) {\n <div class=\"validation-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ ValidationMessage }}</span>\n </div>\n }\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 520px;\n max-width: calc(100vw - 40px);\n max-height: calc(100vh - 60px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 16px 16px 0 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n/* Mode Selector */\n.mode-selector {\n display: flex;\n gap: 8px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.mode-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 16px;\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.mode-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.mode-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.mode-btn i {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.mode-btn.active i {\n color: var(--mj-brand-primary);\n}\n\n.mode-btn span {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-btn.active span {\n color: var(--mj-color-info-700);\n}\n\n/* Dialog Content */\n.dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n}\n\n/* Mode Content */\n.mode-content {\n margin-bottom: 20px;\n}\n\n.mode-description {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 10px;\n margin-bottom: 20px;\n font-size: 13px;\n color: var(--mj-color-info-700);\n line-height: 1.5;\n}\n\n.mode-description i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Form Sections */\n.form-section {\n margin-bottom: 18px;\n}\n\n.form-label {\n display: block;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-label.required::after {\n content: ' *';\n color: var(--mj-status-error);\n}\n\n.form-label .optional {\n font-weight: 400;\n color: var(--mj-text-disabled);\n}\n\n.form-label.examples-label {\n color: var(--mj-text-muted);\n}\n\n/* Form Inputs */\n.form-input,\n.form-select,\n.form-textarea {\n width: 100%;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n background: var(--mj-bg-surface);\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-textarea.code-input {\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n}\n\n/* Function Grid */\n.function-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 8px;\n}\n\n.function-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 14px 10px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.function-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.function-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.function-btn i {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.function-btn.active i {\n color: var(--mj-brand-primary);\n}\n\n.function-btn span {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.function-btn.active span {\n color: var(--mj-color-info-700);\n}\n\n/* Field Hint */\n.field-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-top: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.field-hint.warning {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.field-hint.warning i {\n color: var(--mj-status-warning);\n}\n\n.field-hint.info {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.field-hint.info i {\n color: var(--mj-brand-primary);\n}\n\n.field-hint i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Expression Preview */\n.expression-preview {\n margin-top: 16px;\n padding: 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.preview-label {\n display: block;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-code {\n display: block;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n/* Example Chips */\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-color-info-700);\n}\n\n/* Smart Mode Input */\n.smart-input-container {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.smart-input {\n min-height: 100px;\n}\n\n.smart-input:disabled {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.generate-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n align-self: flex-start;\n}\n\n.generate-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.generate-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n/* Generated Section */\n.generated-section {\n margin-top: 16px;\n padding: 16px;\n background: var(--mj-status-success-bg);\n border: 1px solid var(--mj-status-success-border);\n border-radius: 10px;\n}\n\n.generated-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.generated-header .form-label {\n margin-bottom: 0;\n color: var(--mj-status-success-text);\n}\n\n.clear-generated-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-status-success-border);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-success-text);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-generated-btn:hover {\n background: var(--mj-status-success-text);\n color: var(--mj-text-inverse);\n}\n\n.generated-code {\n display: block;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-status-success-border);\n border-radius: 6px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n font-size: 13px;\n color: var(--mj-status-success-text);\n margin-bottom: 10px;\n}\n\n.generated-info {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-status-success-text);\n}\n\n.generated-info i {\n margin-top: 1px;\n}\n\n/* Smart Tips */\n.smart-tips {\n margin-top: 20px;\n padding: 14px;\n background: var(--mj-status-warning-bg);\n border: 1px solid var(--mj-status-warning-border);\n border-radius: 10px;\n}\n\n.tips-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-status-warning-text);\n}\n\n.tips-header i {\n color: var(--mj-status-warning);\n}\n\n.tips-list {\n margin: 0;\n padding-left: 20px;\n font-size: 12px;\n color: var(--mj-status-warning-text);\n line-height: 1.6;\n}\n\n/* Config Section */\n.config-section {\n padding-top: 16px;\n}\n\n.section-divider {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.section-divider::before,\n.section-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.section-divider span {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Display Type Toggle */\n.display-type-toggle {\n display: flex;\n gap: 12px;\n}\n\n.display-type-btn {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 16px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.display-type-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.display-type-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.display-type-btn i {\n font-size: 22px;\n color: var(--mj-text-muted);\n}\n\n.display-type-btn.active i {\n color: var(--mj-brand-primary);\n}\n\n.display-type-btn span {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.display-type-btn.active span {\n color: var(--mj-color-info-700);\n}\n\n.display-type-btn small {\n font-size: 11px;\n color: var(--mj-text-disabled);\n}\n\n.display-type-btn.active small {\n color: var(--mj-brand-primary);\n}\n\n/* Icon Selector */\n.icon-selector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.selected-icon {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 8px;\n width: fit-content;\n}\n\n.selected-icon i:first-child {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.clear-icon-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n cursor: pointer;\n color: var(--mj-text-disabled);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n transition: all 0.15s ease;\n}\n\n.clear-icon-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.icon-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.15s ease;\n}\n\n.icon-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n}\n\n.icon-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.icon-btn i {\n font-size: 16px;\n color: var(--mj-text-muted);\n}\n\n.icon-btn.active i {\n color: var(--mj-brand-primary);\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 16px 16px;\n}\n\n.footer-left {\n display: flex;\n gap: 10px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 11px 18px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: var(--mj-color-info-600);\n border-color: var(--mj-color-info-600);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n/* Validation Message */\n.validation-message {\n position: absolute;\n bottom: 80px;\n left: 24px;\n right: 24px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-status-error);\n}\n\n.validation-message i {\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 600px) {\n .dialog-panel {\n width: calc(100vw - 24px);\n max-height: calc(100vh - 40px);\n border-radius: 12px;\n }\n\n .dialog-header,\n .dialog-footer {\n border-radius: 0;\n }\n\n .dialog-header {\n border-radius: 12px 12px 0 0;\n }\n\n .dialog-footer {\n border-radius: 0 0 12px 12px;\n }\n\n .mode-btn {\n padding: 10px 8px;\n }\n\n .mode-btn span {\n font-size: 11px;\n }\n\n .function-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .display-type-toggle {\n flex-direction: column;\n }\n}\n"] }]
939
939
  }], () => [{ type: i0.ChangeDetectorRef }], { Entity: [{
940
940
  type: Input
941
941
  }], Aggregate: [{
@@ -136,11 +136,11 @@ export class ConfirmDialogComponent {
136
136
  i0.ɵɵtextInterpolate1(" ", ctx.ConfirmText, " ");
137
137
  i0.ɵɵadvance(2);
138
138
  i0.ɵɵtextInterpolate1(" ", ctx.CancelText, " ");
139
- } }, styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n font-size: 18px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.message[_ngcontent-%COMP%] {\n font-size: 15px;\n color: #374151;\n line-height: 1.5;\n margin: 0;\n}\n\n.detail-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n margin: 12px 0 0 0;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n padding: 9px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-confirm.btn-primary[_ngcontent-%COMP%] {\n background: #3b82f6;\n color: white;\n}\n\n.btn-confirm.btn-primary[_ngcontent-%COMP%]:hover {\n background: #2563eb;\n}\n\n.btn-confirm.btn-danger[_ngcontent-%COMP%] {\n background: #ef4444;\n color: white;\n}\n\n.btn-confirm.btn-danger[_ngcontent-%COMP%]:hover {\n background: #dc2626;\n}\n\n.btn-cancel[_ngcontent-%COMP%] {\n background: #f3f4f6;\n color: #374151;\n}\n\n.btn-cancel[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n}"] });
139
+ } }, styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 16px 16px 0 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.message[_ngcontent-%COMP%] {\n font-size: 15px;\n color: var(--mj-text-primary);\n line-height: 1.5;\n margin: 0;\n}\n\n.detail-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin: 12px 0 0 0;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 16px 16px;\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n padding: 9px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-confirm.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-confirm.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-info-600);\n}\n\n.btn-confirm.btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.btn-confirm.btn-danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-text);\n}\n\n.btn-cancel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}"] });
140
140
  }
141
141
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConfirmDialogComponent, [{
142
142
  type: Component,
143
- args: [{ standalone: false, selector: 'mj-ev-confirm-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"OnCancel()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i [class]=\"Icon\"></i>\n <span>{{ Title }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <p class=\"message\">{{ Message }}</p>\n @if (DetailMessage) {\n <p class=\"detail-message\">{{ DetailMessage }}</p>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button\n class=\"btn btn-confirm\"\n [class.btn-primary]=\"ConfirmStyle === 'primary'\"\n [class.btn-danger]=\"ConfirmStyle === 'danger'\"\n (click)=\"OnConfirm()\">\n {{ ConfirmText }}\n </button>\n <button class=\"btn btn-cancel\" (click)=\"OnCancel()\">\n {{ CancelText }}\n </button>\n </div>\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 16px 16px 0 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-title i {\n color: #3b82f6;\n font-size: 18px;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 24px;\n}\n\n.message {\n font-size: 15px;\n color: #374151;\n line-height: 1.5;\n margin: 0;\n}\n\n.detail-message {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n margin: 12px 0 0 0;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid #e5e7eb;\n background: #f8fafc;\n border-radius: 0 0 16px 16px;\n}\n\n/* Buttons */\n.btn {\n padding: 9px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-confirm.btn-primary {\n background: #3b82f6;\n color: white;\n}\n\n.btn-confirm.btn-primary:hover {\n background: #2563eb;\n}\n\n.btn-confirm.btn-danger {\n background: #ef4444;\n color: white;\n}\n\n.btn-confirm.btn-danger:hover {\n background: #dc2626;\n}\n\n.btn-cancel {\n background: #f3f4f6;\n color: #374151;\n}\n\n.btn-cancel:hover {\n background: #e5e7eb;\n}\n"] }]
143
+ args: [{ standalone: false, selector: 'mj-ev-confirm-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"OnCancel()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-title\">\n <i [class]=\"Icon\"></i>\n <span>{{ Title }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <p class=\"message\">{{ Message }}</p>\n @if (DetailMessage) {\n <p class=\"detail-message\">{{ DetailMessage }}</p>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button\n class=\"btn btn-confirm\"\n [class.btn-primary]=\"ConfirmStyle === 'primary'\"\n [class.btn-danger]=\"ConfirmStyle === 'danger'\"\n (click)=\"OnConfirm()\">\n {{ ConfirmText }}\n </button>\n <button class=\"btn btn-cancel\" (click)=\"OnCancel()\">\n {{ CancelText }}\n </button>\n </div>\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 16px 16px 0 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 17px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 24px;\n}\n\n.message {\n font-size: 15px;\n color: var(--mj-text-primary);\n line-height: 1.5;\n margin: 0;\n}\n\n.detail-message {\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin: 12px 0 0 0;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n border-radius: 0 0 16px 16px;\n}\n\n/* Buttons */\n.btn {\n padding: 9px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-confirm.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-confirm.btn-primary:hover {\n background: var(--mj-color-info-600);\n}\n\n.btn-confirm.btn-danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.btn-confirm.btn-danger:hover {\n background: var(--mj-status-error-text);\n}\n\n.btn-cancel {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-cancel:hover {\n background: var(--mj-bg-surface-active);\n}\n"] }]
144
144
  }], null, { IsOpen: [{
145
145
  type: Input
146
146
  }], Title: [{
@@ -162,11 +162,11 @@ export class DuplicateViewDialogComponent {
162
162
  i0.ɵɵconditional(ctx.Summary ? 20 : -1);
163
163
  i0.ɵɵadvance(2);
164
164
  i0.ɵɵproperty("disabled", !ctx.NewName.trim());
165
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px 24px 0;\n}\n\n.icon-circle[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n background: #eff6ff;\n color: #3b82f6;\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: auto;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n\n\n.dialog-body[_ngcontent-%COMP%] {\n padding: 20px 24px;\n}\n\n.intro-text[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6b7280;\n line-height: 1.5;\n margin: 0 0 16px 0;\n}\n\n.intro-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: #374151;\n}\n\n\n\n.form-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 16px;\n}\n\n.form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #6b7280;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n color: #1f2937;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n.form-input.invalid[_ngcontent-%COMP%] {\n border-color: #ef4444;\n}\n\n.validation-error[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #ef4444;\n}\n\n\n\n.meta-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n background: #f8fafc;\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 12px;\n color: #6b7280;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n font-size: 11px;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px 20px;\n border-top: 1px solid #e5e7eb;\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: #3b82f6;\n color: white;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #2563eb;\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n background: #93c5fd;\n cursor: not-allowed;\n}\n\n.btn-cancel[_ngcontent-%COMP%] {\n background: #f3f4f6;\n color: #374151;\n}\n\n.btn-cancel[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n}"] });
165
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["\n\n.dialog-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px 24px 0;\n}\n\n.icon-circle[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: auto;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n.dialog-body[_ngcontent-%COMP%] {\n padding: 20px 24px;\n}\n\n.intro-text[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin: 0 0 16px 0;\n}\n\n.intro-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n\n.form-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 16px;\n}\n\n.form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-input.invalid[_ngcontent-%COMP%] {\n border-color: var(--mj-status-error);\n}\n\n.validation-error[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-status-error);\n}\n\n\n\n.meta-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-color-info-600);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n cursor: not-allowed;\n}\n\n.btn-cancel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}"] });
166
166
  }
167
167
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DuplicateViewDialogComponent, [{
168
168
  type: Component,
169
- args: [{ standalone: false, selector: 'mj-duplicate-view-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"OnCancel()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"icon-circle\">\n <i class=\"fa-regular fa-copy\"></i>\n </div>\n <span class=\"header-title\">Duplicate View</span>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"dialog-body\">\n <p class=\"intro-text\">\n Creating a copy of <strong>\"{{ SourceViewName }}\"</strong> with all its columns, filters, and sorting.\n </p>\n\n <!-- New Name Input -->\n <div class=\"form-group\">\n <label for=\"duplicateName\">New View Name</label>\n <input\n id=\"duplicateName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !NewName.trim()\"\n [(ngModel)]=\"NewName\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnDuplicate()\"\n />\n @if (NameTouched && !NewName.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Metadata Summary -->\n @if (Summary) {\n <div class=\"meta-summary\">\n @if (Summary.FilterCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-filter\"></i>\n {{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}\n </span>\n }\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n {{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}\n </span>\n @if (Summary.SortCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-arrow-down-short-wide\"></i>\n {{ Summary.SortCount }} sort{{ Summary.SortCount !== 1 ? 's' : '' }}\n </span>\n }\n @if (Summary.AggregateCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n {{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button\n class=\"btn btn-primary\"\n (click)=\"OnDuplicate()\"\n [disabled]=\"!NewName.trim()\">\n <i class=\"fa-regular fa-copy\"></i>\n Duplicate\n </button>\n <button class=\"btn btn-cancel\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px 24px 0;\n}\n\n.icon-circle {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n background: #eff6ff;\n color: #3b82f6;\n flex-shrink: 0;\n}\n\n.header-title {\n font-size: 18px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #6b7280;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: auto;\n}\n\n.close-btn:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n/* Dialog Body */\n.dialog-body {\n padding: 20px 24px;\n}\n\n.intro-text {\n font-size: 14px;\n color: #6b7280;\n line-height: 1.5;\n margin: 0 0 16px 0;\n}\n\n.intro-text strong {\n color: #374151;\n}\n\n/* Form Group */\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 16px;\n}\n\n.form-group label {\n font-size: 13px;\n font-weight: 600;\n color: #6b7280;\n}\n\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n color: #1f2937;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n.form-input.invalid {\n border-color: #ef4444;\n}\n\n.validation-error {\n font-size: 12px;\n color: #ef4444;\n}\n\n/* Metadata Summary */\n.meta-summary {\n display: flex;\n gap: 16px;\n background: #f8fafc;\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 12px;\n color: #6b7280;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-item i {\n color: #3b82f6;\n font-size: 11px;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px 20px;\n border-top: 1px solid #e5e7eb;\n}\n\n/* Buttons */\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary {\n background: #3b82f6;\n color: white;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #2563eb;\n}\n\n.btn-primary:disabled {\n background: #93c5fd;\n cursor: not-allowed;\n}\n\n.btn-cancel {\n background: #f3f4f6;\n color: #374151;\n}\n\n.btn-cancel:hover {\n background: #e5e7eb;\n}\n"] }]
169
+ args: [{ standalone: false, selector: 'mj-duplicate-view-dialog', template: "<!-- Dialog Backdrop -->\n@if (IsOpen) {\n <div class=\"dialog-backdrop\" (click)=\"OnCancel()\"></div>\n}\n\n<!-- Dialog Panel -->\n<div class=\"dialog-panel\" [class.open]=\"IsOpen\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"icon-circle\">\n <i class=\"fa-regular fa-copy\"></i>\n </div>\n <span class=\"header-title\">Duplicate View</span>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"dialog-body\">\n <p class=\"intro-text\">\n Creating a copy of <strong>\"{{ SourceViewName }}\"</strong> with all its columns, filters, and sorting.\n </p>\n\n <!-- New Name Input -->\n <div class=\"form-group\">\n <label for=\"duplicateName\">New View Name</label>\n <input\n id=\"duplicateName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !NewName.trim()\"\n [(ngModel)]=\"NewName\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnDuplicate()\"\n />\n @if (NameTouched && !NewName.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Metadata Summary -->\n @if (Summary) {\n <div class=\"meta-summary\">\n @if (Summary.FilterCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-filter\"></i>\n {{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}\n </span>\n }\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n {{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}\n </span>\n @if (Summary.SortCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-arrow-down-short-wide\"></i>\n {{ Summary.SortCount }} sort{{ Summary.SortCount !== 1 ? 's' : '' }}\n </span>\n }\n @if (Summary.AggregateCount > 0) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n {{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button\n class=\"btn btn-primary\"\n (click)=\"OnDuplicate()\"\n [disabled]=\"!NewName.trim()\">\n <i class=\"fa-regular fa-copy\"></i>\n Duplicate\n </button>\n <button class=\"btn btn-cancel\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* Dialog Backdrop */\n.dialog-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 2000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Panel */\n.dialog-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n width: 420px;\n max-width: calc(100vw - 40px);\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.dialog-panel.open {\n opacity: 1;\n pointer-events: auto;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* Dialog Header */\n.dialog-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px 24px 0;\n}\n\n.icon-circle {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.header-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: auto;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Dialog Body */\n.dialog-body {\n padding: 20px 24px;\n}\n\n.intro-text {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin: 0 0 16px 0;\n}\n\n.intro-text strong {\n color: var(--mj-text-primary);\n}\n\n/* Form Group */\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 16px;\n}\n\n.form-group label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-input.invalid {\n border-color: var(--mj-status-error);\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n}\n\n/* Metadata Summary */\n.meta-summary {\n display: flex;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.meta-item i {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 24px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* Buttons */\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-color-info-600);\n}\n\n.btn-primary:disabled {\n background: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n cursor: not-allowed;\n}\n\n.btn-cancel {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-cancel:hover {\n background: var(--mj-bg-surface-active);\n}\n"] }]
170
170
  }], () => [{ type: i0.ChangeDetectorRef }], { IsOpen: [{
171
171
  type: Input
172
172
  }], SourceViewName: [{
@@ -720,8 +720,8 @@ export class EntityCardsComponent {
720
720
  }
721
721
  getRecordColor(record) {
722
722
  if (!this.entity)
723
- return '#1976d2';
724
- const colors = ['#1976d2', '#388e3c', '#f57c00', '#7b1fa2', '#c2185b', '#0097a7', '#5d4037', '#455a64'];
723
+ return 'var(--mj-brand-primary)';
724
+ const colors = ['var(--mj-brand-primary)', 'var(--mj-status-success)', 'var(--mj-status-warning)', 'var(--mj-brand-primary)', 'var(--mj-status-error)', 'var(--mj-brand-primary)', 'var(--mj-text-muted)', 'var(--mj-text-secondary)'];
725
725
  const pk = buildPkString(record, this.entity);
726
726
  let hash = 0;
727
727
  for (let i = 0; i < pk.length; i++) {
@@ -782,11 +782,11 @@ export class EntityCardsComponent {
782
782
  } if (rf & 2) {
783
783
  i0.ɵɵadvance();
784
784
  i0.ɵɵconditional(ctx.isLoading && ctx.effectiveRecords.length === 0 ? 1 : 2);
785
- } }, dependencies: [i1.LoadingComponent, i2.PillComponent], styles: ["/* Scoped to mj-entity-cards to prevent style leakage with ViewEncapsulation.None */\nmj-entity-cards .cards-view-wrapper {\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\nmj-entity-cards .cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 4px;\n}\n\nmj-entity-cards .data-card {\n background: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n/* Hover state for unselected cards */\nmj-entity-cards .data-card:hover:not(.selected) {\n border-color: #bdbdbd;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\nmj-entity-cards .data-card:hover .card-open-btn {\n opacity: 1;\n}\n\n/* Selected state - subtle but clear */\nmj-entity-cards .data-card.selected {\n border-color: #1976d2;\n}\n\nmj-entity-cards .data-card.selected .card-title {\n color: #1565c0;\n}\n\n/* Selected + hover state - same as regular hover */\nmj-entity-cards .data-card.selected:hover {\n border-color: #1976d2;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\nmj-entity-cards .card-header {\n display: flex;\n align-items: flex-start;\n padding: 16px;\n gap: 12px;\n}\n\nmj-entity-cards .card-thumbnail {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n}\nmj-entity-cards .card-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\nmj-entity-cards .card-avatar {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n font-weight: 600;\n color: white;\n flex-shrink: 0;\n}\n\nmj-entity-cards .card-header-content {\n flex: 1;\n min-width: 0;\n}\n\nmj-entity-cards .card-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: #212121;\n line-height: 1.3;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\nmj-entity-cards .card-subtitle {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: #757575;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\nmj-entity-cards .card-open-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #9e9e9e;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\nmj-entity-cards .card-open-btn:hover {\n background: #f5f5f5;\n color: #1976d2;\n}\n\nmj-entity-cards .card-body {\n padding: 0 16px 16px 16px;\n}\n\nmj-entity-cards .card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: #616161;\n line-height: 1.5;\n}\n\n/* Card Display Fields */\nmj-entity-cards .card-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid #f0f0f0;\n}\n\nmj-entity-cards .field-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 60px;\n}\n\nmj-entity-cards .field-item .field-value {\n font-size: 15px;\n font-weight: 600;\n color: #212121;\n}\n\nmj-entity-cards .field-item .field-label {\n font-size: 10px;\n color: #9e9e9e;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Boolean fields */\nmj-entity-cards .field-item.field-boolean {\n flex-direction: row;\n align-items: center;\n gap: 6px;\n min-width: auto;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon {\n font-size: 14px;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-true {\n color: #2e7d32;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-false {\n color: #bdbdbd;\n}\n\nmj-entity-cards .field-item.field-boolean .field-label {\n font-size: 12px;\n text-transform: none;\n color: #616161;\n}\n\n/* Text fields */\nmj-entity-cards .field-item.field-text {\n flex: 1 1 100%;\n max-width: 100%;\n}\n\nmj-entity-cards .field-item .field-text-value {\n font-size: 13px;\n color: #424242;\n line-height: 1.4;\n word-break: break-word;\n}\n\n/* Date fields */\nmj-entity-cards .field-item .field-date {\n font-size: 13px;\n font-weight: 500;\n}\n\nmj-entity-cards .card-footer {\n padding: 12px 16px;\n background: #fafafa;\n border-top: 1px solid #f0f0f0;\n}\n\n/* Highlight matches - scoped to work with innerHTML */\nmj-entity-cards .highlight-match {\n background-color: #fff176;\n border-radius: 2px;\n}\n\n/* Pill spacing when used as subtitle */\nmj-entity-cards .card-header-content mj-pill {\n display: block;\n margin-top: 4px;\n}\n\n/* Hidden field match indicator */\nmj-entity-cards .hidden-match-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: #fff8e1;\n border-top: 1px solid #ffe082;\n font-size: 11px;\n color: #f57c00;\n}\n\nmj-entity-cards .hidden-match-indicator i {\n font-size: 10px;\n}\n\nmj-entity-cards .hidden-match-indicator span {\n font-weight: 500;\n}\n\n/* Loading state */\nmj-entity-cards .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 40px;\n}\n\n/* No results state */\nmj-entity-cards .no-results {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #9e9e9e;\n text-align: center;\n}\nmj-entity-cards .no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\nmj-entity-cards .no-results p {\n margin: 0;\n font-size: 14px;\n}\n"], encapsulation: 2 });
785
+ } }, dependencies: [i1.LoadingComponent, i2.PillComponent], styles: ["/* Scoped to mj-entity-cards to prevent style leakage with ViewEncapsulation.None */\nmj-entity-cards .cards-view-wrapper {\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\nmj-entity-cards .cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 4px;\n}\n\nmj-entity-cards .data-card {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n/* Hover state for unselected cards */\nmj-entity-cards .data-card:hover:not(.selected) {\n border-color: var(--mj-border-strong);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\nmj-entity-cards .data-card:hover .card-open-btn {\n opacity: 1;\n}\n\n/* Selected state - subtle but clear */\nmj-entity-cards .data-card.selected {\n border-color: var(--mj-brand-primary);\n}\n\nmj-entity-cards .data-card.selected .card-title {\n color: var(--mj-brand-primary-hover);\n}\n\n/* Selected + hover state - same as regular hover */\nmj-entity-cards .data-card.selected:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\nmj-entity-cards .card-header {\n display: flex;\n align-items: flex-start;\n padding: 16px;\n gap: 12px;\n}\n\nmj-entity-cards .card-thumbnail {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n}\nmj-entity-cards .card-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\nmj-entity-cards .card-avatar {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\nmj-entity-cards .card-header-content {\n flex: 1;\n min-width: 0;\n}\n\nmj-entity-cards .card-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n line-height: 1.3;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\nmj-entity-cards .card-subtitle {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\nmj-entity-cards .card-open-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\nmj-entity-cards .card-open-btn:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n}\n\nmj-entity-cards .card-body {\n padding: 0 16px 16px 16px;\n}\n\nmj-entity-cards .card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n/* Card Display Fields */\nmj-entity-cards .card-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\nmj-entity-cards .field-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 60px;\n}\n\nmj-entity-cards .field-item .field-value {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\nmj-entity-cards .field-item .field-label {\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Boolean fields */\nmj-entity-cards .field-item.field-boolean {\n flex-direction: row;\n align-items: center;\n gap: 6px;\n min-width: auto;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon {\n font-size: 14px;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-true {\n color: var(--mj-status-success);\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-false {\n color: var(--mj-text-muted);\n}\n\nmj-entity-cards .field-item.field-boolean .field-label {\n font-size: 12px;\n text-transform: none;\n color: var(--mj-text-secondary);\n}\n\n/* Text fields */\nmj-entity-cards .field-item.field-text {\n flex: 1 1 100%;\n max-width: 100%;\n}\n\nmj-entity-cards .field-item .field-text-value {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n word-break: break-word;\n}\n\n/* Date fields */\nmj-entity-cards .field-item .field-date {\n font-size: 13px;\n font-weight: 500;\n}\n\nmj-entity-cards .card-footer {\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n/* Highlight matches - scoped to work with innerHTML */\nmj-entity-cards .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n}\n\n/* Pill spacing when used as subtitle */\nmj-entity-cards .card-header-content mj-pill {\n display: block;\n margin-top: 4px;\n}\n\n/* Hidden field match indicator */\nmj-entity-cards .hidden-match-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-warning-bg);\n border-top: 1px solid var(--mj-status-warning-border);\n font-size: 11px;\n color: var(--mj-status-warning);\n}\n\nmj-entity-cards .hidden-match-indicator i {\n font-size: 10px;\n}\n\nmj-entity-cards .hidden-match-indicator span {\n font-weight: 500;\n}\n\n/* Loading state */\nmj-entity-cards .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 40px;\n}\n\n/* No results state */\nmj-entity-cards .no-results {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\nmj-entity-cards .no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\nmj-entity-cards .no-results p {\n margin: 0;\n font-size: 14px;\n}\n"], encapsulation: 2 });
786
786
  }
787
787
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityCardsComponent, [{
788
788
  type: Component,
789
- args: [{ standalone: false, selector: 'mj-entity-cards', encapsulation: ViewEncapsulation.None, template: "<div class=\"cards-view-wrapper\">\n @if (isLoading && effectiveRecords.length === 0) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading records...\"></mj-loading>\n </div>\n } @else {\n <div class=\"cards-container\">\n @for (record of effectiveRecords; track getRecordTrackId(record, $index)) {\n <div\n class=\"data-card\"\n [class.selected]=\"isSelected(record)\"\n (click)=\"onCardClick(record)\">\n\n <!-- Card Header with Avatar/Icon -->\n <div class=\"card-header\">\n @switch (getThumbnailType(record)) {\n @case ('image') {\n <div class=\"card-thumbnail\">\n <img [src]=\"getThumbnailUrl(record)\" alt=\"\" />\n </div>\n }\n @case ('icon') {\n <div class=\"card-avatar\" [style.background-color]=\"getRecordColor(record)\">\n <i [class]=\"getThumbnailUrl(record)\"></i>\n </div>\n }\n @default {\n <div class=\"card-avatar\" [style.background-color]=\"getRecordColor(record)\">\n {{ getInitials(record) }}\n </div>\n }\n }\n\n <div class=\"card-header-content\">\n <h3 class=\"card-title\" [innerHTML]=\"highlightMatch(getFieldValue(record, effectiveTemplate?.titleField ?? null))\"></h3>\n @if (effectiveTemplate?.subtitleField; as subField) {\n @if (subtitleIsPill) {\n <mj-pill [value]=\"getFieldValue(record, subField)\"></mj-pill>\n } @else {\n <span class=\"card-subtitle\" [innerHTML]=\"highlightMatch(getFieldValue(record, subField))\"></span>\n }\n }\n </div>\n\n <button class=\"card-open-btn\" (click)=\"onOpenClick($event, record)\" title=\"Open Record\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (effectiveTemplate?.descriptionField; as descField) {\n <p class=\"card-description\" [innerHTML]=\"highlightMatch(getTextValue(record, descField, 100))\"></p>\n }\n\n <!-- Display Fields -->\n @if (effectiveTemplate && effectiveTemplate.displayFields.length > 0) {\n <div class=\"card-fields\">\n @for (field of effectiveTemplate.displayFields; track field.name) {\n <div class=\"field-item\" [class.field-boolean]=\"field.type === 'boolean'\" [class.field-text]=\"field.type === 'text'\">\n @switch (field.type) {\n @case ('boolean') {\n <i class=\"field-icon\" [class.fa-solid]=\"true\"\n [class.fa-check]=\"getBooleanValue(record, field.name)\"\n [class.fa-minus]=\"!getBooleanValue(record, field.name)\"\n [class.bool-true]=\"getBooleanValue(record, field.name)\"\n [class.bool-false]=\"!getBooleanValue(record, field.name)\"></i>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @case ('number') {\n <span class=\"field-value\">{{ getNumericValue(record, field.name) }}</span>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @case ('date') {\n <span class=\"field-value field-date\">{{ getDateValue(record, field.name) }}</span>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @default {\n <span class=\"field-label\">{{ field.label }}</span>\n <span class=\"field-text-value\" [innerHTML]=\"highlightMatch(getTextValue(record, field.name, 40))\"></span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Card Footer with Badge -->\n @if (effectiveTemplate?.badgeField; as badgeField) {\n <div class=\"card-footer\">\n <mj-pill [value]=\"getFieldValue(record, badgeField)\"></mj-pill>\n </div>\n }\n\n <!-- Hidden field match indicator -->\n @if (hasHiddenFieldMatch(record)) {\n <div class=\"hidden-match-indicator\" [title]=\"'Matched in: ' + getHiddenMatchFieldName(record)\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>{{ getHiddenMatchFieldName(record) }}</span>\n </div>\n }\n </div>\n }\n\n @if (effectiveRecords.length === 0) {\n <div class=\"no-results\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No records to display</p>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["/* Scoped to mj-entity-cards to prevent style leakage with ViewEncapsulation.None */\nmj-entity-cards .cards-view-wrapper {\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\nmj-entity-cards .cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 4px;\n}\n\nmj-entity-cards .data-card {\n background: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n/* Hover state for unselected cards */\nmj-entity-cards .data-card:hover:not(.selected) {\n border-color: #bdbdbd;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\nmj-entity-cards .data-card:hover .card-open-btn {\n opacity: 1;\n}\n\n/* Selected state - subtle but clear */\nmj-entity-cards .data-card.selected {\n border-color: #1976d2;\n}\n\nmj-entity-cards .data-card.selected .card-title {\n color: #1565c0;\n}\n\n/* Selected + hover state - same as regular hover */\nmj-entity-cards .data-card.selected:hover {\n border-color: #1976d2;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\nmj-entity-cards .card-header {\n display: flex;\n align-items: flex-start;\n padding: 16px;\n gap: 12px;\n}\n\nmj-entity-cards .card-thumbnail {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n}\nmj-entity-cards .card-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\nmj-entity-cards .card-avatar {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n font-weight: 600;\n color: white;\n flex-shrink: 0;\n}\n\nmj-entity-cards .card-header-content {\n flex: 1;\n min-width: 0;\n}\n\nmj-entity-cards .card-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: #212121;\n line-height: 1.3;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\nmj-entity-cards .card-subtitle {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: #757575;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\nmj-entity-cards .card-open-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #9e9e9e;\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\nmj-entity-cards .card-open-btn:hover {\n background: #f5f5f5;\n color: #1976d2;\n}\n\nmj-entity-cards .card-body {\n padding: 0 16px 16px 16px;\n}\n\nmj-entity-cards .card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: #616161;\n line-height: 1.5;\n}\n\n/* Card Display Fields */\nmj-entity-cards .card-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid #f0f0f0;\n}\n\nmj-entity-cards .field-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 60px;\n}\n\nmj-entity-cards .field-item .field-value {\n font-size: 15px;\n font-weight: 600;\n color: #212121;\n}\n\nmj-entity-cards .field-item .field-label {\n font-size: 10px;\n color: #9e9e9e;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Boolean fields */\nmj-entity-cards .field-item.field-boolean {\n flex-direction: row;\n align-items: center;\n gap: 6px;\n min-width: auto;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon {\n font-size: 14px;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-true {\n color: #2e7d32;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-false {\n color: #bdbdbd;\n}\n\nmj-entity-cards .field-item.field-boolean .field-label {\n font-size: 12px;\n text-transform: none;\n color: #616161;\n}\n\n/* Text fields */\nmj-entity-cards .field-item.field-text {\n flex: 1 1 100%;\n max-width: 100%;\n}\n\nmj-entity-cards .field-item .field-text-value {\n font-size: 13px;\n color: #424242;\n line-height: 1.4;\n word-break: break-word;\n}\n\n/* Date fields */\nmj-entity-cards .field-item .field-date {\n font-size: 13px;\n font-weight: 500;\n}\n\nmj-entity-cards .card-footer {\n padding: 12px 16px;\n background: #fafafa;\n border-top: 1px solid #f0f0f0;\n}\n\n/* Highlight matches - scoped to work with innerHTML */\nmj-entity-cards .highlight-match {\n background-color: #fff176;\n border-radius: 2px;\n}\n\n/* Pill spacing when used as subtitle */\nmj-entity-cards .card-header-content mj-pill {\n display: block;\n margin-top: 4px;\n}\n\n/* Hidden field match indicator */\nmj-entity-cards .hidden-match-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: #fff8e1;\n border-top: 1px solid #ffe082;\n font-size: 11px;\n color: #f57c00;\n}\n\nmj-entity-cards .hidden-match-indicator i {\n font-size: 10px;\n}\n\nmj-entity-cards .hidden-match-indicator span {\n font-weight: 500;\n}\n\n/* Loading state */\nmj-entity-cards .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 40px;\n}\n\n/* No results state */\nmj-entity-cards .no-results {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #9e9e9e;\n text-align: center;\n}\nmj-entity-cards .no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\nmj-entity-cards .no-results p {\n margin: 0;\n font-size: 14px;\n}\n"] }]
789
+ args: [{ standalone: false, selector: 'mj-entity-cards', encapsulation: ViewEncapsulation.None, template: "<div class=\"cards-view-wrapper\">\n @if (isLoading && effectiveRecords.length === 0) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading records...\"></mj-loading>\n </div>\n } @else {\n <div class=\"cards-container\">\n @for (record of effectiveRecords; track getRecordTrackId(record, $index)) {\n <div\n class=\"data-card\"\n [class.selected]=\"isSelected(record)\"\n (click)=\"onCardClick(record)\">\n\n <!-- Card Header with Avatar/Icon -->\n <div class=\"card-header\">\n @switch (getThumbnailType(record)) {\n @case ('image') {\n <div class=\"card-thumbnail\">\n <img [src]=\"getThumbnailUrl(record)\" alt=\"\" />\n </div>\n }\n @case ('icon') {\n <div class=\"card-avatar\" [style.background-color]=\"getRecordColor(record)\">\n <i [class]=\"getThumbnailUrl(record)\"></i>\n </div>\n }\n @default {\n <div class=\"card-avatar\" [style.background-color]=\"getRecordColor(record)\">\n {{ getInitials(record) }}\n </div>\n }\n }\n\n <div class=\"card-header-content\">\n <h3 class=\"card-title\" [innerHTML]=\"highlightMatch(getFieldValue(record, effectiveTemplate?.titleField ?? null))\"></h3>\n @if (effectiveTemplate?.subtitleField; as subField) {\n @if (subtitleIsPill) {\n <mj-pill [value]=\"getFieldValue(record, subField)\"></mj-pill>\n } @else {\n <span class=\"card-subtitle\" [innerHTML]=\"highlightMatch(getFieldValue(record, subField))\"></span>\n }\n }\n </div>\n\n <button class=\"card-open-btn\" (click)=\"onOpenClick($event, record)\" title=\"Open Record\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (effectiveTemplate?.descriptionField; as descField) {\n <p class=\"card-description\" [innerHTML]=\"highlightMatch(getTextValue(record, descField, 100))\"></p>\n }\n\n <!-- Display Fields -->\n @if (effectiveTemplate && effectiveTemplate.displayFields.length > 0) {\n <div class=\"card-fields\">\n @for (field of effectiveTemplate.displayFields; track field.name) {\n <div class=\"field-item\" [class.field-boolean]=\"field.type === 'boolean'\" [class.field-text]=\"field.type === 'text'\">\n @switch (field.type) {\n @case ('boolean') {\n <i class=\"field-icon\" [class.fa-solid]=\"true\"\n [class.fa-check]=\"getBooleanValue(record, field.name)\"\n [class.fa-minus]=\"!getBooleanValue(record, field.name)\"\n [class.bool-true]=\"getBooleanValue(record, field.name)\"\n [class.bool-false]=\"!getBooleanValue(record, field.name)\"></i>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @case ('number') {\n <span class=\"field-value\">{{ getNumericValue(record, field.name) }}</span>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @case ('date') {\n <span class=\"field-value field-date\">{{ getDateValue(record, field.name) }}</span>\n <span class=\"field-label\">{{ field.label }}</span>\n }\n @default {\n <span class=\"field-label\">{{ field.label }}</span>\n <span class=\"field-text-value\" [innerHTML]=\"highlightMatch(getTextValue(record, field.name, 40))\"></span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Card Footer with Badge -->\n @if (effectiveTemplate?.badgeField; as badgeField) {\n <div class=\"card-footer\">\n <mj-pill [value]=\"getFieldValue(record, badgeField)\"></mj-pill>\n </div>\n }\n\n <!-- Hidden field match indicator -->\n @if (hasHiddenFieldMatch(record)) {\n <div class=\"hidden-match-indicator\" [title]=\"'Matched in: ' + getHiddenMatchFieldName(record)\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>{{ getHiddenMatchFieldName(record) }}</span>\n </div>\n }\n </div>\n }\n\n @if (effectiveRecords.length === 0) {\n <div class=\"no-results\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No records to display</p>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["/* Scoped to mj-entity-cards to prevent style leakage with ViewEncapsulation.None */\nmj-entity-cards .cards-view-wrapper {\n height: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\nmj-entity-cards .cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 4px;\n}\n\nmj-entity-cards .data-card {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n/* Hover state for unselected cards */\nmj-entity-cards .data-card:hover:not(.selected) {\n border-color: var(--mj-border-strong);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\nmj-entity-cards .data-card:hover .card-open-btn {\n opacity: 1;\n}\n\n/* Selected state - subtle but clear */\nmj-entity-cards .data-card.selected {\n border-color: var(--mj-brand-primary);\n}\n\nmj-entity-cards .data-card.selected .card-title {\n color: var(--mj-brand-primary-hover);\n}\n\n/* Selected + hover state - same as regular hover */\nmj-entity-cards .data-card.selected:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\nmj-entity-cards .card-header {\n display: flex;\n align-items: flex-start;\n padding: 16px;\n gap: 12px;\n}\n\nmj-entity-cards .card-thumbnail {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n}\nmj-entity-cards .card-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\nmj-entity-cards .card-avatar {\n width: 48px;\n height: 48px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\nmj-entity-cards .card-header-content {\n flex: 1;\n min-width: 0;\n}\n\nmj-entity-cards .card-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n line-height: 1.3;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\nmj-entity-cards .card-subtitle {\n display: block;\n margin-top: 2px;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\nmj-entity-cards .card-open-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n opacity: 0;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\nmj-entity-cards .card-open-btn:hover {\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n}\n\nmj-entity-cards .card-body {\n padding: 0 16px 16px 16px;\n}\n\nmj-entity-cards .card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n/* Card Display Fields */\nmj-entity-cards .card-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\nmj-entity-cards .field-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 60px;\n}\n\nmj-entity-cards .field-item .field-value {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\nmj-entity-cards .field-item .field-label {\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Boolean fields */\nmj-entity-cards .field-item.field-boolean {\n flex-direction: row;\n align-items: center;\n gap: 6px;\n min-width: auto;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon {\n font-size: 14px;\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-true {\n color: var(--mj-status-success);\n}\n\nmj-entity-cards .field-item.field-boolean .field-icon.bool-false {\n color: var(--mj-text-muted);\n}\n\nmj-entity-cards .field-item.field-boolean .field-label {\n font-size: 12px;\n text-transform: none;\n color: var(--mj-text-secondary);\n}\n\n/* Text fields */\nmj-entity-cards .field-item.field-text {\n flex: 1 1 100%;\n max-width: 100%;\n}\n\nmj-entity-cards .field-item .field-text-value {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n word-break: break-word;\n}\n\n/* Date fields */\nmj-entity-cards .field-item .field-date {\n font-size: 13px;\n font-weight: 500;\n}\n\nmj-entity-cards .card-footer {\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n/* Highlight matches - scoped to work with innerHTML */\nmj-entity-cards .highlight-match {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 2px;\n}\n\n/* Pill spacing when used as subtitle */\nmj-entity-cards .card-header-content mj-pill {\n display: block;\n margin-top: 4px;\n}\n\n/* Hidden field match indicator */\nmj-entity-cards .hidden-match-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-status-warning-bg);\n border-top: 1px solid var(--mj-status-warning-border);\n font-size: 11px;\n color: var(--mj-status-warning);\n}\n\nmj-entity-cards .hidden-match-indicator i {\n font-size: 10px;\n}\n\nmj-entity-cards .hidden-match-indicator span {\n font-weight: 500;\n}\n\n/* Loading state */\nmj-entity-cards .loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n padding: 40px;\n}\n\n/* No results state */\nmj-entity-cards .no-results {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\nmj-entity-cards .no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\nmj-entity-cards .no-results p {\n margin: 0;\n font-size: 14px;\n}\n"] }]
790
790
  }], () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], { entity: [{
791
791
  type: Input
792
792
  }], records: [{