@memberjunction/ng-entity-viewer 5.38.0 → 5.40.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 (93) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/view-types.test.d.ts +2 -0
  3. package/dist/__tests__/view-types.test.d.ts.map +1 -0
  4. package/dist/__tests__/view-types.test.js +102 -0
  5. package/dist/__tests__/view-types.test.js.map +1 -0
  6. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +2 -2
  7. package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js.map +1 -1
  8. package/dist/lib/confirm-dialog/confirm-dialog.component.js +2 -2
  9. package/dist/lib/confirm-dialog/confirm-dialog.component.js.map +1 -1
  10. package/dist/lib/duplicate-view-dialog/duplicate-view-dialog.component.js +2 -2
  11. package/dist/lib/duplicate-view-dialog/duplicate-view-dialog.component.js.map +1 -1
  12. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  13. package/dist/lib/entity-data-grid/entity-data-grid.component.js +10 -2
  14. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  15. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +2 -2
  16. package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js.map +1 -1
  17. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +356 -341
  18. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  19. package/dist/lib/entity-viewer/entity-viewer.component.js +993 -1097
  20. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  21. package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +2 -2
  22. package/dist/lib/quick-save-dialog/quick-save-dialog.component.js.map +1 -1
  23. package/dist/lib/recycle-bin/recycle-bin.component.js +1 -1
  24. package/dist/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.js +2 -2
  25. package/dist/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.js.map +1 -1
  26. package/dist/lib/view-config-panel/view-config-panel.component.d.ts +126 -126
  27. package/dist/lib/view-config-panel/view-config-panel.component.js +635 -635
  28. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  29. package/dist/lib/view-selector/view-selector.component.d.ts +226 -0
  30. package/dist/lib/view-selector/view-selector.component.d.ts.map +1 -0
  31. package/dist/lib/view-selector/view-selector.component.js +861 -0
  32. package/dist/lib/view-selector/view-selector.component.js.map +1 -0
  33. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts +114 -0
  34. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts.map +1 -0
  35. package/dist/lib/view-type-switcher/view-type-switcher.component.js +209 -0
  36. package/dist/lib/view-type-switcher/view-type-switcher.component.js.map +1 -0
  37. package/dist/lib/view-types/descriptors/cards-view-type.d.ts +18 -0
  38. package/dist/lib/view-types/descriptors/cards-view-type.d.ts.map +1 -0
  39. package/dist/lib/view-types/descriptors/cards-view-type.js +31 -0
  40. package/dist/lib/view-types/descriptors/cards-view-type.js.map +1 -0
  41. package/dist/lib/view-types/descriptors/grid-view-type.d.ts +17 -0
  42. package/dist/lib/view-types/descriptors/grid-view-type.d.ts.map +1 -0
  43. package/dist/lib/view-types/descriptors/grid-view-type.js +30 -0
  44. package/dist/lib/view-types/descriptors/grid-view-type.js.map +1 -0
  45. package/dist/lib/view-types/descriptors/map-view-type.d.ts +21 -0
  46. package/dist/lib/view-types/descriptors/map-view-type.d.ts.map +1 -0
  47. package/dist/lib/view-types/descriptors/map-view-type.js +35 -0
  48. package/dist/lib/view-types/descriptors/map-view-type.js.map +1 -0
  49. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts +22 -0
  50. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts.map +1 -0
  51. package/dist/lib/view-types/descriptors/timeline-view-type.js +40 -0
  52. package/dist/lib/view-types/descriptors/timeline-view-type.js.map +1 -0
  53. package/dist/lib/view-types/index.d.ts +20 -0
  54. package/dist/lib/view-types/index.d.ts.map +1 -0
  55. package/dist/lib/view-types/index.js +29 -0
  56. package/dist/lib/view-types/index.js.map +1 -0
  57. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +93 -0
  58. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -0
  59. package/dist/lib/view-types/renderers/cards-view-renderer.component.js +144 -0
  60. package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -0
  61. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +273 -0
  62. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -0
  63. package/dist/lib/view-types/renderers/grid-view-renderer.component.js +558 -0
  64. package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -0
  65. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +135 -0
  66. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -0
  67. package/dist/lib/view-types/renderers/map-view-renderer.component.js +216 -0
  68. package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -0
  69. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts +176 -0
  70. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts.map +1 -0
  71. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js +535 -0
  72. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js.map +1 -0
  73. package/dist/lib/view-types/view-type.contracts.d.ts +235 -0
  74. package/dist/lib/view-types/view-type.contracts.d.ts.map +1 -0
  75. package/dist/lib/view-types/view-type.contracts.js +51 -0
  76. package/dist/lib/view-types/view-type.contracts.js.map +1 -0
  77. package/dist/lib/view-types/view-type.engine.d.ts +76 -0
  78. package/dist/lib/view-types/view-type.engine.d.ts.map +1 -0
  79. package/dist/lib/view-types/view-type.engine.js +138 -0
  80. package/dist/lib/view-types/view-type.engine.js.map +1 -0
  81. package/dist/lib/view-workspace/view-workspace.component.d.ts +451 -0
  82. package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -0
  83. package/dist/lib/view-workspace/view-workspace.component.js +1212 -0
  84. package/dist/lib/view-workspace/view-workspace.component.js.map +1 -0
  85. package/dist/module.d.ts +20 -11
  86. package/dist/module.d.ts.map +1 -1
  87. package/dist/module.js +50 -8
  88. package/dist/module.js.map +1 -1
  89. package/dist/public-api.d.ts +8 -0
  90. package/dist/public-api.d.ts.map +1 -1
  91. package/dist/public-api.js +14 -0
  92. package/dist/public-api.js.map +1 -1
  93. package/package.json +19 -18
@@ -268,7 +268,7 @@ export class QuickSaveDialogComponent {
268
268
  });
269
269
  }
270
270
  static ɵfac = function QuickSaveDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || QuickSaveDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
271
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QuickSaveDialogComponent, selectors: [["mj-quick-save-dialog"]], inputs: { IsOpen: "IsOpen", ViewEntity: "ViewEntity", EntityName: "EntityName", Summary: "Summary", IsSaving: "IsSaving", DefaultSaveAsNew: "DefaultSaveAsNew" }, outputs: { Save: "Save", Close: "Close", OpenAdvanced: "OpenAdvanced" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 40, vars: 12, consts: [[1, "dialog-backdrop"], [1, "dialog-panel"], [1, "dialog-header"], [1, "header-title"], [1, "fa-solid", "fa-bookmark"], [1, "entity-badge"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "dialog-content"], [1, "form-group"], ["for", "quickSaveName"], ["id", "quickSaveName", "type", "text", "placeholder", "e.g., Active West Coast Contacts", 1, "form-input", 3, "ngModelChange", "blur", "keydown.enter", "ngModel"], [1, "validation-error"], ["for", "quickSaveDescription"], [1, "optional"], ["id", "quickSaveDescription", "placeholder", "What does this view show?", "rows", "2", 1, "form-input", "form-textarea", 3, "ngModelChange", "ngModel"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "checkbox-text"], [1, "summary-section"], [1, "advanced-link", 3, "click"], [1, "fa-solid", "fa-sliders"], [1, "dialog-footer"], [1, "footer-actions"], [1, "btn", "btn-primary", 3, "disabled"], [1, "btn", "btn-cancel", 3, "click"], [1, "dialog-backdrop", 3, "click"], [1, "summary-header"], [1, "fa-solid", "fa-list-check"], [1, "summary-items"], [1, "summary-item"], [1, "fa-solid", "fa-columns"], [1, "summary-item", "smart-filter"], [1, "fa-solid", "fa-arrow-up-wide-short"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "fa-solid", "fa-filter"], [1, "fa-solid", "fa-chart-simple"], [1, "btn", "btn-primary", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-save"], [1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"]], template: function QuickSaveDialogComponent_Template(rf, ctx) { if (rf & 1) {
271
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QuickSaveDialogComponent, selectors: [["mj-quick-save-dialog"]], inputs: { IsOpen: "IsOpen", ViewEntity: "ViewEntity", EntityName: "EntityName", Summary: "Summary", IsSaving: "IsSaving", DefaultSaveAsNew: "DefaultSaveAsNew" }, outputs: { Save: "Save", Close: "Close", OpenAdvanced: "OpenAdvanced" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 40, vars: 12, consts: [[1, "dialog-backdrop"], [1, "dialog-panel"], [1, "dialog-header"], [1, "header-title"], [1, "fa-solid", "fa-bookmark"], [1, "entity-badge"], ["title", "Close", "aria-label", "Close dialog", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "dialog-content"], [1, "form-group"], ["for", "quickSaveName"], ["id", "quickSaveName", "type", "text", "placeholder", "e.g., Active West Coast Contacts", 1, "form-input", 3, "ngModelChange", "blur", "keydown.enter", "ngModel"], [1, "validation-error"], ["for", "quickSaveDescription"], [1, "optional"], ["id", "quickSaveDescription", "placeholder", "What does this view show?", "rows", "2", 1, "form-input", "form-textarea", 3, "ngModelChange", "ngModel"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "checkbox-text"], [1, "summary-section"], [1, "advanced-link", 3, "click"], [1, "fa-solid", "fa-sliders"], [1, "dialog-footer"], [1, "footer-actions"], [1, "btn", "btn-primary", 3, "disabled"], [1, "btn", "btn-cancel", 3, "click"], [1, "dialog-backdrop", 3, "click"], [1, "summary-header"], [1, "fa-solid", "fa-list-check"], [1, "summary-items"], [1, "summary-item"], [1, "fa-solid", "fa-columns"], [1, "summary-item", "smart-filter"], [1, "fa-solid", "fa-arrow-up-wide-short"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "fa-solid", "fa-filter"], [1, "fa-solid", "fa-chart-simple"], [1, "btn", "btn-primary", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-save"], [1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"]], template: function QuickSaveDialogComponent_Template(rf, ctx) { if (rf & 1) {
272
272
  i0.ɵɵconditionalCreate(0, QuickSaveDialogComponent_Conditional_0_Template, 1, 0, "div", 0);
273
273
  i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
274
274
  i0.ɵɵelement(4, "i", 4);
@@ -343,7 +343,7 @@ export class QuickSaveDialogComponent {
343
343
  }
344
344
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(QuickSaveDialogComponent, [{
345
345
  type: Component,
346
- args: [{ standalone: false, selector: 'mj-quick-save-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-bookmark\"></i>\n <span>Save View</span>\n </div>\n @if (EntityName) {\n <span class=\"entity-badge\">{{ EntityName }}</span>\n }\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Name Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveName\">View Name</label>\n <input\n id=\"quickSaveName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !Name.trim()\"\n placeholder=\"e.g., Active West Coast Contacts\"\n [(ngModel)]=\"Name\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnSave(false)\"\n />\n @if (NameTouched && !Name.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Description Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveDescription\">Description <span class=\"optional\">(optional)</span></label>\n <textarea\n id=\"quickSaveDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"What does this view show?\"\n [(ngModel)]=\"Description\"\n rows=\"2\"\n ></textarea>\n </div>\n\n <!-- Share Toggle -->\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"IsShared\" />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n\n <!-- View Summary Preview -->\n @if (Summary) {\n <div class=\"summary-section\">\n <div class=\"summary-header\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>View includes:</span>\n </div>\n <div class=\"summary-items\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>{{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}</span>\n </div>\n @if (Summary.SortCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>{{ Summary.SortCount }} sort level{{ Summary.SortCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.SmartFilterActive) {\n <div class=\"summary-item smart-filter\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart filter: \"{{ Summary.SmartFilterPrompt }}\"</span>\n </div>\n }\n @if (Summary.FilterCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>{{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.AggregateCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Advanced Link -->\n <button class=\"advanced-link\" (click)=\"OnOpenAdvanced()\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Customize columns, filters & sorting...</span>\n </button>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-actions\">\n @if (ViewEntity) {\n <!-- Existing view: Update + Save As New -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(false)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Update' }}\n </button>\n <button\n class=\"btn btn-secondary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As New\n </button>\n } @else {\n <!-- New view: Create -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n </div>\n <button class=\"btn btn-cancel\" (click)=\"OnClose()\">\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: 480px;\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-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Entity Badge */\n.entity-badge {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 3px 10px;\n border-radius: 12px;\n margin-left: auto;\n margin-right: 8px;\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 20px 24px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Form Groups */\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.form-group label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.form-group .optional {\n font-weight: 400;\n color: var(--mj-text-disabled);\n}\n\n.form-input {\n padding: 9px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: border-color 0.15s ease;\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.form-textarea {\n resize: vertical;\n font-family: inherit;\n min-height: 50px;\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n/* Summary Section */\n.summary-section {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 14px;\n}\n\n.summary-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 10px;\n}\n\n.summary-header i {\n color: var(--mj-brand-primary);\n}\n\n.summary-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.summary-item i {\n color: var(--mj-text-muted);\n width: 16px;\n text-align: center;\n font-size: 12px;\n}\n\n.summary-item.smart-filter {\n color: var(--mj-brand-primary);\n}\n\n.summary-item.smart-filter i {\n color: var(--mj-brand-primary);\n}\n\n/* Advanced Link */\n.advanced-link {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0;\n border: none;\n background: none;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n.advanced-link:hover {\n color: var(--mj-color-info-600);\n text-decoration: underline;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\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.footer-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* Buttons */\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\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-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-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-secondary:disabled {\n opacity: 0.5;\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"] }]
346
+ args: [{ standalone: false, selector: 'mj-quick-save-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-bookmark\"></i>\n <span>Save View</span>\n </div>\n @if (EntityName) {\n <span class=\"entity-badge\">{{ EntityName }}</span>\n }\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Name Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveName\">View Name</label>\n <input\n id=\"quickSaveName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !Name.trim()\"\n placeholder=\"e.g., Active West Coast Contacts\"\n [(ngModel)]=\"Name\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnSave(false)\"\n />\n @if (NameTouched && !Name.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Description Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveDescription\">Description <span class=\"optional\">(optional)</span></label>\n <textarea\n id=\"quickSaveDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"What does this view show?\"\n [(ngModel)]=\"Description\"\n rows=\"2\"\n ></textarea>\n </div>\n\n <!-- Share Toggle -->\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"IsShared\" />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n\n <!-- View Summary Preview -->\n @if (Summary) {\n <div class=\"summary-section\">\n <div class=\"summary-header\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>View includes:</span>\n </div>\n <div class=\"summary-items\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>{{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}</span>\n </div>\n @if (Summary.SortCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>{{ Summary.SortCount }} sort level{{ Summary.SortCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.SmartFilterActive) {\n <div class=\"summary-item smart-filter\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart filter: \"{{ Summary.SmartFilterPrompt }}\"</span>\n </div>\n }\n @if (Summary.FilterCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>{{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.AggregateCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Advanced Link -->\n <button class=\"advanced-link\" (click)=\"OnOpenAdvanced()\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Customize columns, filters & sorting...</span>\n </button>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-actions\">\n @if (ViewEntity) {\n <!-- Existing view: Update + Save As New -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(false)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Update' }}\n </button>\n <button\n class=\"btn btn-secondary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As New\n </button>\n } @else {\n <!-- New view: Create -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n </div>\n <button class=\"btn btn-cancel\" (click)=\"OnClose()\">\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: 480px;\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-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Entity Badge */\n.entity-badge {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 3px 10px;\n border-radius: 12px;\n margin-left: auto;\n margin-right: 8px;\n}\n\n/* Dialog Content */\n.dialog-content {\n padding: 20px 24px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* Form Groups */\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.form-group label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.form-group .optional {\n font-weight: 400;\n color: var(--mj-text-disabled);\n}\n\n.form-input {\n padding: 9px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: border-color 0.15s ease;\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.form-textarea {\n resize: vertical;\n font-family: inherit;\n min-height: 50px;\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n/* Summary Section */\n.summary-section {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 14px;\n}\n\n.summary-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 10px;\n}\n\n.summary-header i {\n color: var(--mj-brand-primary);\n}\n\n.summary-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.summary-item i {\n color: var(--mj-text-muted);\n width: 16px;\n text-align: center;\n font-size: 12px;\n}\n\n.summary-item.smart-filter {\n color: var(--mj-brand-primary);\n}\n\n.summary-item.smart-filter i {\n color: var(--mj-brand-primary);\n}\n\n/* Advanced Link */\n.advanced-link {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0;\n border: none;\n background: none;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n.advanced-link:hover {\n color: var(--mj-color-info-600);\n text-decoration: underline;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\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.footer-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* Buttons */\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\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-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-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-secondary:disabled {\n opacity: 0.5;\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"] }]
347
347
  }], () => [{ type: i0.ChangeDetectorRef }], { IsOpen: [{
348
348
  type: Input
349
349
  }], ViewEntity: [{
@@ -1 +1 @@
1
- {"version":3,"file":"quick-save-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/quick-save-dialog/quick-save-dialog.component.ts","../../../src/lib/quick-save-dialog/quick-save-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { ViewConfigSummary, QuickSaveEvent, QuickSaveAdvancedEvent } from '../types';\n\n/**\n * QuickSaveDialogComponent - Focused modal for saving views quickly\n *\n * Replaces the 7+ click \"create new view\" flow with a focused 2-3 click dialog.\n * Shows essential fields (name, description, share) plus a summary preview\n * of what the view configuration includes.\n *\n * Footer buttons determine the action:\n * - No existing view: \"Create View\" button\n * - Existing view: \"Update\" (primary) + \"Save As New\" (secondary) buttons\n *\n * @example\n * ```html\n * <mj-quick-save-dialog\n * [IsOpen]=\"showQuickSave\"\n * [ViewEntity]=\"currentView\"\n * [EntityName]=\"entity.Name\"\n * [Summary]=\"configSummary\"\n * [IsSaving]=\"isSaving\"\n * (Save)=\"onQuickSave($event)\"\n * (Close)=\"showQuickSave = false\"\n * (OpenAdvanced)=\"openConfigPanel()\">\n * </mj-quick-save-dialog>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-quick-save-dialog',\n templateUrl: './quick-save-dialog.component.html',\n styleUrls: ['./quick-save-dialog.component.css']\n})\nexport class QuickSaveDialogComponent implements OnChanges {\n /**\n * Whether the dialog is open\n */\n @Input() IsOpen: boolean = false;\n\n /**\n * The existing view entity (null = creating new)\n */\n @Input() ViewEntity: MJUserViewEntityExtended | null = null;\n\n /**\n * Display name of the entity being viewed\n */\n @Input() EntityName: string = '';\n\n /**\n * Summary of what the current view configuration includes\n */\n @Input() Summary: ViewConfigSummary | null = null;\n\n /**\n * Whether a save is in progress\n */\n @Input() IsSaving: boolean = false;\n\n /**\n * Whether to default to Save As New mode (no longer used for toggle, kept for API compat)\n */\n @Input() DefaultSaveAsNew: boolean = false;\n\n /**\n * Emitted when the user saves\n */\n @Output() Save = new EventEmitter<QuickSaveEvent>();\n\n /**\n * Emitted when the dialog should close\n */\n @Output() Close = new EventEmitter<void>();\n\n /**\n * Emitted when user wants to open the full config panel.\n * Carries the partially-filled form data so the config panel can continue the flow.\n */\n @Output() OpenAdvanced = new EventEmitter<QuickSaveAdvancedEvent>();\n\n // Form state\n public Name: string = '';\n public Description: string = '';\n public IsShared: boolean = false;\n public NameTouched: boolean = false;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['IsOpen'] && this.IsOpen) {\n this.initializeForm();\n }\n }\n\n /**\n * Initialize form from view entity or defaults\n */\n private initializeForm(): void {\n this.NameTouched = false;\n if (this.ViewEntity) {\n this.Name = this.ViewEntity.Name;\n this.Description = this.ViewEntity.Description || '';\n this.IsShared = this.ViewEntity.IsShared;\n } else {\n this.Name = '';\n this.Description = '';\n this.IsShared = false;\n }\n this.cdr.detectChanges();\n }\n\n /**\n * Handle save button click\n * @param saveAsNew - true to create a new view, false to update existing\n */\n OnSave(saveAsNew: boolean): void {\n if (!this.Name.trim() || this.IsSaving) return;\n\n this.Save.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n IsShared: this.IsShared,\n SaveAsNew: saveAsNew\n });\n }\n\n /**\n * Handle close/cancel\n */\n OnClose(): void {\n this.Close.emit();\n }\n\n /**\n * Open advanced configuration panel, carrying partially-filled form data\n */\n OnOpenAdvanced(): void {\n this.OpenAdvanced.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n IsShared: this.IsShared\n });\n }\n}\n","<!-- 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-bookmark\"></i>\n <span>Save View</span>\n </div>\n @if (EntityName) {\n <span class=\"entity-badge\">{{ EntityName }}</span>\n }\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Name Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveName\">View Name</label>\n <input\n id=\"quickSaveName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !Name.trim()\"\n placeholder=\"e.g., Active West Coast Contacts\"\n [(ngModel)]=\"Name\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnSave(false)\"\n />\n @if (NameTouched && !Name.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Description Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveDescription\">Description <span class=\"optional\">(optional)</span></label>\n <textarea\n id=\"quickSaveDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"What does this view show?\"\n [(ngModel)]=\"Description\"\n rows=\"2\"\n ></textarea>\n </div>\n\n <!-- Share Toggle -->\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"IsShared\" />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n\n <!-- View Summary Preview -->\n @if (Summary) {\n <div class=\"summary-section\">\n <div class=\"summary-header\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>View includes:</span>\n </div>\n <div class=\"summary-items\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>{{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}</span>\n </div>\n @if (Summary.SortCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>{{ Summary.SortCount }} sort level{{ Summary.SortCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.SmartFilterActive) {\n <div class=\"summary-item smart-filter\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart filter: \"{{ Summary.SmartFilterPrompt }}\"</span>\n </div>\n }\n @if (Summary.FilterCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>{{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.AggregateCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Advanced Link -->\n <button class=\"advanced-link\" (click)=\"OnOpenAdvanced()\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Customize columns, filters & sorting...</span>\n </button>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-actions\">\n @if (ViewEntity) {\n <!-- Existing view: Update + Save As New -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(false)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Update' }}\n </button>\n <button\n class=\"btn btn-secondary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As New\n </button>\n } @else {\n <!-- New view: Create -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n </div>\n <button class=\"btn btn-cancel\" (click)=\"OnClose()\">\n Cancel\n </button>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"quick-save-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/quick-save-dialog/quick-save-dialog.component.ts","../../../src/lib/quick-save-dialog/quick-save-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { ViewConfigSummary, QuickSaveEvent, QuickSaveAdvancedEvent } from '../types';\n\n/**\n * QuickSaveDialogComponent - Focused modal for saving views quickly\n *\n * Replaces the 7+ click \"create new view\" flow with a focused 2-3 click dialog.\n * Shows essential fields (name, description, share) plus a summary preview\n * of what the view configuration includes.\n *\n * Footer buttons determine the action:\n * - No existing view: \"Create View\" button\n * - Existing view: \"Update\" (primary) + \"Save As New\" (secondary) buttons\n *\n * @example\n * ```html\n * <mj-quick-save-dialog\n * [IsOpen]=\"showQuickSave\"\n * [ViewEntity]=\"currentView\"\n * [EntityName]=\"entity.Name\"\n * [Summary]=\"configSummary\"\n * [IsSaving]=\"isSaving\"\n * (Save)=\"onQuickSave($event)\"\n * (Close)=\"showQuickSave = false\"\n * (OpenAdvanced)=\"openConfigPanel()\">\n * </mj-quick-save-dialog>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-quick-save-dialog',\n templateUrl: './quick-save-dialog.component.html',\n styleUrls: ['./quick-save-dialog.component.css']\n})\nexport class QuickSaveDialogComponent implements OnChanges {\n /**\n * Whether the dialog is open\n */\n @Input() IsOpen: boolean = false;\n\n /**\n * The existing view entity (null = creating new)\n */\n @Input() ViewEntity: MJUserViewEntityExtended | null = null;\n\n /**\n * Display name of the entity being viewed\n */\n @Input() EntityName: string = '';\n\n /**\n * Summary of what the current view configuration includes\n */\n @Input() Summary: ViewConfigSummary | null = null;\n\n /**\n * Whether a save is in progress\n */\n @Input() IsSaving: boolean = false;\n\n /**\n * Whether to default to Save As New mode (no longer used for toggle, kept for API compat)\n */\n @Input() DefaultSaveAsNew: boolean = false;\n\n /**\n * Emitted when the user saves\n */\n @Output() Save = new EventEmitter<QuickSaveEvent>();\n\n /**\n * Emitted when the dialog should close\n */\n @Output() Close = new EventEmitter<void>();\n\n /**\n * Emitted when user wants to open the full config panel.\n * Carries the partially-filled form data so the config panel can continue the flow.\n */\n @Output() OpenAdvanced = new EventEmitter<QuickSaveAdvancedEvent>();\n\n // Form state\n public Name: string = '';\n public Description: string = '';\n public IsShared: boolean = false;\n public NameTouched: boolean = false;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['IsOpen'] && this.IsOpen) {\n this.initializeForm();\n }\n }\n\n /**\n * Initialize form from view entity or defaults\n */\n private initializeForm(): void {\n this.NameTouched = false;\n if (this.ViewEntity) {\n this.Name = this.ViewEntity.Name;\n this.Description = this.ViewEntity.Description || '';\n this.IsShared = this.ViewEntity.IsShared;\n } else {\n this.Name = '';\n this.Description = '';\n this.IsShared = false;\n }\n this.cdr.detectChanges();\n }\n\n /**\n * Handle save button click\n * @param saveAsNew - true to create a new view, false to update existing\n */\n OnSave(saveAsNew: boolean): void {\n if (!this.Name.trim() || this.IsSaving) return;\n\n this.Save.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n IsShared: this.IsShared,\n SaveAsNew: saveAsNew\n });\n }\n\n /**\n * Handle close/cancel\n */\n OnClose(): void {\n this.Close.emit();\n }\n\n /**\n * Open advanced configuration panel, carrying partially-filled form data\n */\n OnOpenAdvanced(): void {\n this.OpenAdvanced.emit({\n Name: this.Name.trim(),\n Description: this.Description,\n IsShared: this.IsShared\n });\n }\n}\n","<!-- 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-bookmark\"></i>\n <span>Save View</span>\n </div>\n @if (EntityName) {\n <span class=\"entity-badge\">{{ EntityName }}</span>\n }\n <button class=\"close-btn\" (click)=\"OnClose()\" title=\"Close\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"dialog-content\">\n <!-- Name Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveName\">View Name</label>\n <input\n id=\"quickSaveName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"NameTouched && !Name.trim()\"\n placeholder=\"e.g., Active West Coast Contacts\"\n [(ngModel)]=\"Name\"\n (blur)=\"NameTouched = true\"\n (keydown.enter)=\"OnSave(false)\"\n />\n @if (NameTouched && !Name.trim()) {\n <span class=\"validation-error\">Name is required</span>\n }\n </div>\n\n <!-- Description Field -->\n <div class=\"form-group\">\n <label for=\"quickSaveDescription\">Description <span class=\"optional\">(optional)</span></label>\n <textarea\n id=\"quickSaveDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"What does this view show?\"\n [(ngModel)]=\"Description\"\n rows=\"2\"\n ></textarea>\n </div>\n\n <!-- Share Toggle -->\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"IsShared\" />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n\n <!-- View Summary Preview -->\n @if (Summary) {\n <div class=\"summary-section\">\n <div class=\"summary-header\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>View includes:</span>\n </div>\n <div class=\"summary-items\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-columns\"></i>\n <span>{{ Summary.ColumnCount }} column{{ Summary.ColumnCount !== 1 ? 's' : '' }}</span>\n </div>\n @if (Summary.SortCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>{{ Summary.SortCount }} sort level{{ Summary.SortCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.SmartFilterActive) {\n <div class=\"summary-item smart-filter\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Smart filter: \"{{ Summary.SmartFilterPrompt }}\"</span>\n </div>\n }\n @if (Summary.FilterCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-filter\"></i>\n <span>{{ Summary.FilterCount }} filter{{ Summary.FilterCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n @if (Summary.AggregateCount > 0) {\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>{{ Summary.AggregateCount }} aggregate{{ Summary.AggregateCount !== 1 ? 's' : '' }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Advanced Link -->\n <button class=\"advanced-link\" (click)=\"OnOpenAdvanced()\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Customize columns, filters & sorting...</span>\n </button>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-actions\">\n @if (ViewEntity) {\n <!-- Existing view: Update + Save As New -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(false)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Update' }}\n </button>\n <button\n class=\"btn btn-secondary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As New\n </button>\n } @else {\n <!-- New view: Create -->\n <button\n class=\"btn btn-primary\"\n (click)=\"OnSave(true)\"\n [disabled]=\"!Name.trim() || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ IsSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n </div>\n <button class=\"btn btn-cancel\" (click)=\"OnClose()\">\n Cancel\n </button>\n </div>\n</div>\n"]}
@@ -4,7 +4,7 @@ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
4
  import * as i0 from "@angular/core";
5
5
  import * as i1 from "@memberjunction/ng-shared-generic";
6
6
  import * as i2 from "@memberjunction/ng-record-changes";
7
- import * as i3 from "@memberjunction/ng-versions";
7
+ import * as i3 from "@memberjunction/ng-ui-components";
8
8
  const _forTrack0 = ($index, $item) => $item.RecordChange.ID;
9
9
  const _forTrack1 = ($index, $item) => $item.Name;
10
10
  function RecycleBinComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
@@ -40,7 +40,7 @@ export class SharedViewWarningDialogComponent {
40
40
  this.Cancel.emit();
41
41
  }
42
42
  static ɵfac = function SharedViewWarningDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SharedViewWarningDialogComponent)(); };
43
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SharedViewWarningDialogComponent, selectors: [["mj-shared-view-warning-dialog"]], inputs: { IsOpen: "IsOpen", ViewName: "ViewName" }, outputs: { Action: "Action", Cancel: "Cancel" }, standalone: false, decls: 27, vars: 4, consts: [[1, "dialog-backdrop"], [1, "dialog-panel"], [1, "dialog-header"], [1, "icon-circle", "warning"], [1, "fa-solid", "fa-users"], [1, "header-title"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "dialog-body"], [1, "message"], [1, "warning-box"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "dialog-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "fa-solid", "fa-save"], [1, "btn", "btn-secondary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "btn", "btn-ghost", 3, "click"], [1, "dialog-backdrop", 3, "click"]], template: function SharedViewWarningDialogComponent_Template(rf, ctx) { if (rf & 1) {
43
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SharedViewWarningDialogComponent, selectors: [["mj-shared-view-warning-dialog"]], inputs: { IsOpen: "IsOpen", ViewName: "ViewName" }, outputs: { Action: "Action", Cancel: "Cancel" }, standalone: false, decls: 27, vars: 4, consts: [[1, "dialog-backdrop"], [1, "dialog-panel"], [1, "dialog-header"], [1, "icon-circle", "warning"], [1, "fa-solid", "fa-users"], [1, "header-title"], ["title", "Close", "aria-label", "Close dialog", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "dialog-body"], [1, "message"], [1, "warning-box"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "dialog-footer"], [1, "btn", "btn-primary", 3, "click"], [1, "fa-solid", "fa-save"], [1, "btn", "btn-secondary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "btn", "btn-ghost", 3, "click"], [1, "dialog-backdrop", 3, "click"]], template: function SharedViewWarningDialogComponent_Template(rf, ctx) { if (rf & 1) {
44
44
  i0.ɵɵconditionalCreate(0, SharedViewWarningDialogComponent_Conditional_0_Template, 1, 0, "div", 0);
45
45
  i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
46
46
  i0.ɵɵelement(4, "i", 4);
@@ -86,7 +86,7 @@ export class SharedViewWarningDialogComponent {
86
86
  }
87
87
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SharedViewWarningDialogComponent, [{
88
88
  type: Component,
89
- args: [{ standalone: false, selector: 'mj-shared-view-warning-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 warning\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <span class=\"header-title\">Shared 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=\"message\">\n <strong>\"{{ ViewName }}\"</strong> is shared with other users.\n Changes you save will affect everyone who uses this view.\n </p>\n <div class=\"warning-box\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Other users may be relying on this view's current configuration.</span>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnUpdateShared()\">\n <i class=\"fa-solid fa-save\"></i>\n Update Shared View\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnSaveAsCopy()\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As My Copy\n </button>\n <button class=\"btn btn-ghost\" (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: 440px;\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 flex-shrink: 0;\n}\n\n.icon-circle.warning {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\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.message {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n margin: 0 0 16px 0;\n}\n\n.message strong {\n color: var(--mj-text-primary);\n}\n\n/* Warning Box */\n.warning-box {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n background: var(--mj-status-warning-bg);\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 13px;\n color: var(--mj-status-warning);\n}\n\n.warning-box i {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 8px;\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: 6px;\n padding: 9px 16px;\n border: none;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover {\n background: var(--mj-color-info-600);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-ghost {\n background: transparent;\n color: var(--mj-text-muted);\n margin-left: auto;\n}\n\n.btn-ghost:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n"] }]
89
+ args: [{ standalone: false, selector: 'mj-shared-view-warning-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 warning\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <span class=\"header-title\">Shared View</span>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"dialog-body\">\n <p class=\"message\">\n <strong>\"{{ ViewName }}\"</strong> is shared with other users.\n Changes you save will affect everyone who uses this view.\n </p>\n <div class=\"warning-box\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Other users may be relying on this view's current configuration.</span>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnUpdateShared()\">\n <i class=\"fa-solid fa-save\"></i>\n Update Shared View\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnSaveAsCopy()\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As My Copy\n </button>\n <button class=\"btn btn-ghost\" (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: 440px;\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 flex-shrink: 0;\n}\n\n.icon-circle.warning {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\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.message {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n margin: 0 0 16px 0;\n}\n\n.message strong {\n color: var(--mj-text-primary);\n}\n\n/* Warning Box */\n.warning-box {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n background: var(--mj-status-warning-bg);\n border-radius: 8px;\n padding: 10px 14px;\n font-size: 13px;\n color: var(--mj-status-warning);\n}\n\n.warning-box i {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Dialog Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n gap: 8px;\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: 6px;\n padding: 9px 16px;\n border: none;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover {\n background: var(--mj-color-info-600);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-ghost {\n background: transparent;\n color: var(--mj-text-muted);\n margin-left: auto;\n}\n\n.btn-ghost:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n"] }]
90
90
  }], null, { IsOpen: [{
91
91
  type: Input
92
92
  }], ViewName: [{
@@ -1 +1 @@
1
- {"version":3,"file":"shared-view-warning-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.ts","../../../src/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;;;ICErE,+BAAkD;IAArB,iMAAS,iBAAU,KAAC;IAAC,iBAAM;;ADK1D;;;;;;;;;;;;;;;;;;GAkBG;AAOH,MAAM,OAAO,gCAAgC;IAClC,MAAM,GAAY,KAAK,CAAC;IACxB,QAAQ,GAAW,EAAE,CAAC;IAErB,MAAM,GAAG,IAAI,YAAY,EAAoB,CAAC;IAC9C,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,cAAc;QACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;0HAjBU,gCAAgC;6DAAhC,gCAAgC;YC/B7C,kGAAc;YAQV,AADF,AAFF,8BAAgD,aAEnB,aACQ;YAC/B,uBAAiC;YACnC,iBAAM;YACN,+BAA2B;YAAA,2BAAW;YAAA,iBAAO;YAC7C,iCAA6D;YAAnC,6GAAS,cAAU,IAAC;YAC5C,uBAAiC;YAErC,AADE,iBAAS,EACL;YAKF,AADF,AADF,8BAAyB,YACJ,cACT;YAAA,aAAgB;YAAA,iBAAS;YAAC,wGAEpC;YAAA,iBAAI;YACJ,gCAAyB;YACvB,yBAAgD;YAChD,6BAAM;YAAA,iFAAgE;YAE1E,AADE,AADwE,iBAAO,EACzE,EACF;YAIJ,AADF,gCAA2B,kBACkC;YAA3B,8GAAS,oBAAgB,IAAC;YACxD,yBAAgC;YAChC,qCACF;YAAA,iBAAS;YACT,mCAA2D;YAAzB,8GAAS,kBAAc,IAAC;YACxD,yBAAgC;YAChC,kCACF;YAAA,iBAAS;YACT,mCAAmD;YAArB,8GAAS,cAAU,IAAC;YAChD,yBACF;YAEJ,AADE,AADE,iBAAS,EACL,EACF;;YA3CN,qCAEC;YAGyB,cAAqB;YAArB,kCAAqB;YAejC,gBAAgB;YAAhB,+CAAgB;;;iFDWjB,gCAAgC;cAN5C,SAAS;6BACI,KAAK,YACP,+BAA+B;;kBAKxC,KAAK;;kBACL,KAAK;;kBAEL,MAAM;;kBACN,MAAM;;kFALI,gCAAgC","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\n\n/**\n * Result of the shared view warning dialog\n */\nexport type SharedViewAction = 'update-shared' | 'save-as-copy' | 'cancel';\n\n/**\n * SharedViewWarningDialogComponent - Warning dialog when saving changes to a shared view\n *\n * Shows when a user attempts to save changes to a view that is shared with other users.\n * Presents three options:\n * - Update Shared View: save changes affecting all users\n * - Save As My Copy: create a personal copy with the changes\n * - Cancel: abort the save\n *\n * @example\n * ```html\n * <mj-shared-view-warning-dialog\n * [IsOpen]=\"showSharedWarning\"\n * [ViewName]=\"currentView.Name\"\n * (Action)=\"onSharedViewAction($event)\"\n * (Cancel)=\"showSharedWarning = false\">\n * </mj-shared-view-warning-dialog>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-shared-view-warning-dialog',\n templateUrl: './shared-view-warning-dialog.component.html',\n styleUrls: ['./shared-view-warning-dialog.component.css']\n})\nexport class SharedViewWarningDialogComponent {\n @Input() IsOpen: boolean = false;\n @Input() ViewName: string = '';\n\n @Output() Action = new EventEmitter<SharedViewAction>();\n @Output() Cancel = new EventEmitter<void>();\n\n OnUpdateShared(): void {\n this.Action.emit('update-shared');\n }\n\n OnSaveAsCopy(): void {\n this.Action.emit('save-as-copy');\n }\n\n OnCancel(): void {\n this.Cancel.emit();\n }\n}\n","<!-- 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 warning\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <span class=\"header-title\">Shared 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=\"message\">\n <strong>\"{{ ViewName }}\"</strong> is shared with other users.\n Changes you save will affect everyone who uses this view.\n </p>\n <div class=\"warning-box\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Other users may be relying on this view's current configuration.</span>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnUpdateShared()\">\n <i class=\"fa-solid fa-save\"></i>\n Update Shared View\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnSaveAsCopy()\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As My Copy\n </button>\n <button class=\"btn btn-ghost\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"shared-view-warning-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.ts","../../../src/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;;;ICErE,+BAAkD;IAArB,iMAAS,iBAAU,KAAC;IAAC,iBAAM;;ADK1D;;;;;;;;;;;;;;;;;;GAkBG;AAOH,MAAM,OAAO,gCAAgC;IAClC,MAAM,GAAY,KAAK,CAAC;IACxB,QAAQ,GAAW,EAAE,CAAC;IAErB,MAAM,GAAG,IAAI,YAAY,EAAoB,CAAC;IAC9C,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,cAAc;QACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;0HAjBU,gCAAgC;6DAAhC,gCAAgC;YC/B7C,kGAAc;YAQV,AADF,AAFF,8BAAgD,aAEnB,aACQ;YAC/B,uBAAiC;YACnC,iBAAM;YACN,+BAA2B;YAAA,2BAAW;YAAA,iBAAO;YAC7C,iCAAuF;YAA7D,6GAAS,cAAU,IAAC;YAC5C,uBAAiC;YAErC,AADE,iBAAS,EACL;YAKF,AADF,AADF,8BAAyB,YACJ,cACT;YAAA,aAAgB;YAAA,iBAAS;YAAC,wGAEpC;YAAA,iBAAI;YACJ,gCAAyB;YACvB,yBAAgD;YAChD,6BAAM;YAAA,iFAAgE;YAE1E,AADE,AADwE,iBAAO,EACzE,EACF;YAIJ,AADF,gCAA2B,kBACkC;YAA3B,8GAAS,oBAAgB,IAAC;YACxD,yBAAgC;YAChC,qCACF;YAAA,iBAAS;YACT,mCAA2D;YAAzB,8GAAS,kBAAc,IAAC;YACxD,yBAAgC;YAChC,kCACF;YAAA,iBAAS;YACT,mCAAmD;YAArB,8GAAS,cAAU,IAAC;YAChD,yBACF;YAEJ,AADE,AADE,iBAAS,EACL,EACF;;YA3CN,qCAEC;YAGyB,cAAqB;YAArB,kCAAqB;YAejC,gBAAgB;YAAhB,+CAAgB;;;iFDWjB,gCAAgC;cAN5C,SAAS;6BACI,KAAK,YACP,+BAA+B;;kBAKxC,KAAK;;kBACL,KAAK;;kBAEL,MAAM;;kBACN,MAAM;;kFALI,gCAAgC","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\n\n/**\n * Result of the shared view warning dialog\n */\nexport type SharedViewAction = 'update-shared' | 'save-as-copy' | 'cancel';\n\n/**\n * SharedViewWarningDialogComponent - Warning dialog when saving changes to a shared view\n *\n * Shows when a user attempts to save changes to a view that is shared with other users.\n * Presents three options:\n * - Update Shared View: save changes affecting all users\n * - Save As My Copy: create a personal copy with the changes\n * - Cancel: abort the save\n *\n * @example\n * ```html\n * <mj-shared-view-warning-dialog\n * [IsOpen]=\"showSharedWarning\"\n * [ViewName]=\"currentView.Name\"\n * (Action)=\"onSharedViewAction($event)\"\n * (Cancel)=\"showSharedWarning = false\">\n * </mj-shared-view-warning-dialog>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-shared-view-warning-dialog',\n templateUrl: './shared-view-warning-dialog.component.html',\n styleUrls: ['./shared-view-warning-dialog.component.css']\n})\nexport class SharedViewWarningDialogComponent {\n @Input() IsOpen: boolean = false;\n @Input() ViewName: string = '';\n\n @Output() Action = new EventEmitter<SharedViewAction>();\n @Output() Cancel = new EventEmitter<void>();\n\n OnUpdateShared(): void {\n this.Action.emit('update-shared');\n }\n\n OnSaveAsCopy(): void {\n this.Action.emit('save-as-copy');\n }\n\n OnCancel(): void {\n this.Cancel.emit();\n }\n}\n","<!-- 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 warning\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <span class=\"header-title\">Shared View</span>\n <button class=\"close-btn\" (click)=\"OnCancel()\" title=\"Close\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"dialog-body\">\n <p class=\"message\">\n <strong>\"{{ ViewName }}\"</strong> is shared with other users.\n Changes you save will affect everyone who uses this view.\n </p>\n <div class=\"warning-box\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>Other users may be relying on this view's current configuration.</span>\n </div>\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <button class=\"btn btn-primary\" (click)=\"OnUpdateShared()\">\n <i class=\"fa-solid fa-save\"></i>\n Update Shared View\n </button>\n <button class=\"btn btn-secondary\" (click)=\"OnSaveAsCopy()\">\n <i class=\"fa-solid fa-plus\"></i>\n Save As My Copy\n </button>\n <button class=\"btn btn-ghost\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </div>\n</div>\n"]}