@memberjunction/ng-list-management 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.
@@ -928,11 +928,11 @@ export class ListManagementDialogComponent {
928
928
  i0.ɵɵconditionalCreate(0, ListManagementDialogComponent_Conditional_0_Template, 50, 18, "div", 0);
929
929
  } if (rf & 2) {
930
930
  i0.ɵɵconditional(ctx.visible ? 0 : -1);
931
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent], styles: ["\n\n\n\n\n\n\n.dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-container[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n width: 90vw;\n max-width: 600px;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease-out;\n overflow: hidden;\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n}\n\n.header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.dialog-subtitle[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-button[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 8px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.2s;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.search-section[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 20px;\n background: #f8fafc;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.search-bar[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 14px;\n color: #94a3b8;\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 40px 12px 42px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.2s;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n}\n\n.clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 12px;\n border: none;\n background: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.clear-search[_ngcontent-%COMP%]:hover {\n color: #64748b;\n}\n\n.create-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.create-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n}\n\n.create-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n\n\n.filter-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n border-bottom: 1px solid #e2e8f0;\n background: white;\n}\n\n.tabs-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tab-button[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: none;\n background: none;\n color: #64748b;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n\n.tab-button[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n color: #334155;\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n background: #ede9fe;\n color: #7c3aed;\n}\n\n.sort-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-size: 13px;\n color: #64748b;\n background: white;\n cursor: pointer;\n}\n\n.sort-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #667eea;\n}\n\n\n\n.create-form[_ngcontent-%COMP%] {\n background: #fefce8;\n border-bottom: 1px solid #fde047;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 300px;\n }\n}\n\n.create-form-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-weight: 600;\n color: #854d0e;\n font-size: 14px;\n border-bottom: 1px solid #fde047;\n}\n\n.create-form-body[_ngcontent-%COMP%] {\n padding: 16px 20px;\n}\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.form-group[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 16px;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n background: white;\n transition: all 0.2s;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 60px;\n}\n\n.create-form-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n}\n\n\n\n.list-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\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: 60px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: #cbd5e1;\n margin-bottom: 16px;\n}\n\n.empty-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #334155;\n margin: 0 0 6px 0;\n}\n\n.empty-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #64748b;\n margin: 0 0 20px 0;\n}\n\n\n\n.list-items[_ngcontent-%COMP%] {\n padding: 8px 12px;\n}\n\n.list-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 8px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n transition: all 0.2s;\n}\n\n.list-item[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.list-item[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n}\n\n.list-item.selected-add[_ngcontent-%COMP%] {\n background: #ecfdf5;\n border-color: #10b981;\n}\n\n.list-item.selected-remove[_ngcontent-%COMP%] {\n background: #fef2f2;\n border-color: #ef4444;\n}\n\n.list-item.is-member[_ngcontent-%COMP%] {\n border-left: 3px solid #667eea;\n}\n\n\n\n.list-item-select[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.select-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: all 0.2s;\n}\n\n.select-btn.add-btn[_ngcontent-%COMP%]:hover {\n border-color: #10b981;\n color: #10b981;\n background: #ecfdf5;\n}\n\n.select-btn.add-btn.selected[_ngcontent-%COMP%] {\n background: #10b981;\n border-color: #10b981;\n color: white;\n}\n\n.select-btn.remove-btn[_ngcontent-%COMP%]:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: #fef2f2;\n}\n\n.select-btn.remove-btn.selected[_ngcontent-%COMP%] {\n background: #ef4444;\n border-color: #ef4444;\n color: white;\n}\n\n\n\n.list-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.list-item-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.list-icon[_ngcontent-%COMP%] {\n color: #667eea;\n font-size: 14px;\n}\n\n.list-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.badge-new[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n}\n\n.list-item-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n font-size: 12px;\n color: #64748b;\n}\n\n.list-description[_ngcontent-%COMP%] {\n max-width: 180px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.meta-separator[_ngcontent-%COMP%] {\n color: #cbd5e1;\n}\n\n\n\n.membership-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.membership-indicator.full-member[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.membership-indicator.partial-member[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.membership-indicator.not-member[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.membership-text[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: #f8fafc;\n border-top: 1px solid #e2e8f0;\n}\n\n.footer-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.summary-item.add[_ngcontent-%COMP%] {\n color: #16a34a;\n}\n\n.summary-item.remove[_ngcontent-%COMP%] {\n color: #dc2626;\n}\n\n.summary-empty[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 13px;\n}\n\n.footer-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s;\n border: none;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n transform: translateY(-1px);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: white;\n color: #64748b;\n border: 1px solid #e2e8f0;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8fafc;\n border-color: #cbd5e1;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n\n\n\n\n\n@media (max-width: 640px) {\n .dialog-overlay[_ngcontent-%COMP%] {\n align-items: flex-end;\n }\n\n .dialog-container[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 24px 24px 0 0;\n animation: slideUpMobile 0.3s ease-out;\n }\n\n @keyframes slideUpMobile {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-radius: 24px 24px 0 0;\n }\n\n .header-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .dialog-title[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .dialog-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .search-section[_ngcontent-%COMP%] {\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .search-bar[_ngcontent-%COMP%] {\n width: 100%;\n order: 1;\n }\n\n .create-button[_ngcontent-%COMP%] {\n order: 2;\n width: 100%;\n justify-content: center;\n margin-top: 8px;\n }\n\n .button-text[_ngcontent-%COMP%] {\n display: inline;\n }\n\n .filter-tabs[_ngcontent-%COMP%] {\n padding: 10px 16px;\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .tabs-left[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: space-between;\n }\n\n .tab-button[_ngcontent-%COMP%] {\n flex: 1;\n text-align: center;\n padding: 10px 8px;\n }\n\n .tabs-right[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .sort-select[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .list-content[_ngcontent-%COMP%] {\n max-height: 50vh;\n }\n\n .list-items[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .list-item[_ngcontent-%COMP%] {\n padding: 12px;\n gap: 10px;\n }\n\n .list-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .list-description[_ngcontent-%COMP%] {\n display: none;\n }\n\n .membership-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n padding: 12px 16px;\n flex-direction: column;\n gap: 12px;\n }\n\n .footer-summary[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .footer-actions[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .footer-actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: center;\n }\n\n .create-form-body[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .create-form-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .create-form-actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n\n\n@media (min-width: 641px) and (max-width: 1024px) {\n .dialog-container[_ngcontent-%COMP%] {\n max-width: 550px;\n }\n\n .list-description[_ngcontent-%COMP%] {\n max-width: 140px;\n }\n}\n\n\n\n@media (min-width: 1025px) {\n .list-content[_ngcontent-%COMP%] {\n max-height: 450px;\n }\n\n .list-item[_ngcontent-%COMP%]:hover {\n transform: translateX(4px);\n }\n}\n\n\n\n.search-input[_ngcontent-%COMP%]:focus-visible, \n.tab-button[_ngcontent-%COMP%]:focus-visible, \n.select-btn[_ngcontent-%COMP%]:focus-visible, \n.btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid #667eea;\n outline-offset: 2px;\n}\n\n\n\n@media (prefers-reduced-motion: reduce) {\n .dialog-overlay[_ngcontent-%COMP%], \n .dialog-container[_ngcontent-%COMP%], \n .create-form[_ngcontent-%COMP%], \n .list-item[_ngcontent-%COMP%], \n .btn[_ngcontent-%COMP%] {\n animation: none;\n transition: none;\n }\n}"] });
931
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent], styles: ["\n\n\n\n\n\n\n.dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.dialog-container[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px var(--mj-shadow-lg);\n width: 90vw;\n max-width: 600px;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease-out;\n overflow: hidden;\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n}\n\n.header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.dialog-subtitle[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-button[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.2s;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n\n\n.search-section[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-bar[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 14px;\n color: var(--mj-text-muted);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 40px 12px 42px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface-card);\n transition: all 0.2s;\n}\n\n.search-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) 15%, transparent);\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 12px;\n border: none;\n background: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.clear-search[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.create-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.create-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.create-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n\n\n.filter-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.tabs-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tab-button[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: none;\n background: none;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n\n.tab-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.sort-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n}\n\n.sort-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.create-form[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n animation: _ngcontent-%COMP%_slideDown 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 300px;\n }\n}\n\n.create-form-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-weight: 600;\n color: var(--mj-status-warning);\n font-size: 14px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.create-form-body[_ngcontent-%COMP%] {\n padding: 16px 20px;\n}\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.form-group[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 16px;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n background: var(--mj-bg-surface-card);\n transition: all 0.2s;\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) 15%, transparent);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 60px;\n}\n\n.create-form-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n}\n\n\n\n.list-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\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: 60px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-strong);\n margin-bottom: 16px;\n}\n\n.empty-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 6px 0;\n}\n\n.empty-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0 0 20px 0;\n}\n\n\n\n.list-items[_ngcontent-%COMP%] {\n padding: 8px 12px;\n}\n\n.list-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s;\n}\n\n.list-item[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.list-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px var(--mj-shadow-sm);\n}\n\n.list-item.selected-add[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-success);\n}\n\n.list-item.selected-remove[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-error);\n}\n\n.list-item.is-member[_ngcontent-%COMP%] {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n\n\n.list-item-select[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.select-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: all 0.2s;\n}\n\n.select-btn.add-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-status-success);\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.select-btn.add-btn.selected[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.select-btn.remove-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.select-btn.remove-btn.selected[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n\n\n.list-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.list-item-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.list-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.list-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.badge-new[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.list-item-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.list-description[_ngcontent-%COMP%] {\n max-width: 180px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.meta-separator[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n}\n\n\n\n.membership-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.membership-indicator.full-member[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.membership-indicator.partial-member[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.membership-indicator.not-member[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.membership-text[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.footer-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.summary-item.add[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.summary-item.remove[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.summary-empty[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.footer-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n}\n\n\n\n.btn[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s;\n border: none;\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 box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateY(-1px);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n\n\n\n\n\n@media (max-width: 640px) {\n .dialog-overlay[_ngcontent-%COMP%] {\n align-items: flex-end;\n }\n\n .dialog-container[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 24px 24px 0 0;\n animation: slideUpMobile 0.3s ease-out;\n }\n\n @keyframes slideUpMobile {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-radius: 24px 24px 0 0;\n }\n\n .header-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .dialog-title[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .dialog-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .search-section[_ngcontent-%COMP%] {\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .search-bar[_ngcontent-%COMP%] {\n width: 100%;\n order: 1;\n }\n\n .create-button[_ngcontent-%COMP%] {\n order: 2;\n width: 100%;\n justify-content: center;\n margin-top: 8px;\n }\n\n .button-text[_ngcontent-%COMP%] {\n display: inline;\n }\n\n .filter-tabs[_ngcontent-%COMP%] {\n padding: 10px 16px;\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .tabs-left[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: space-between;\n }\n\n .tab-button[_ngcontent-%COMP%] {\n flex: 1;\n text-align: center;\n padding: 10px 8px;\n }\n\n .tabs-right[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .sort-select[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .list-content[_ngcontent-%COMP%] {\n max-height: 50vh;\n }\n\n .list-items[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .list-item[_ngcontent-%COMP%] {\n padding: 12px;\n gap: 10px;\n }\n\n .list-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .list-description[_ngcontent-%COMP%] {\n display: none;\n }\n\n .membership-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n padding: 12px 16px;\n flex-direction: column;\n gap: 12px;\n }\n\n .footer-summary[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .footer-actions[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .footer-actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: center;\n }\n\n .create-form-body[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .create-form-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .create-form-actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n\n\n@media (min-width: 641px) and (max-width: 1024px) {\n .dialog-container[_ngcontent-%COMP%] {\n max-width: 550px;\n }\n\n .list-description[_ngcontent-%COMP%] {\n max-width: 140px;\n }\n}\n\n\n\n@media (min-width: 1025px) {\n .list-content[_ngcontent-%COMP%] {\n max-height: 450px;\n }\n\n .list-item[_ngcontent-%COMP%]:hover {\n transform: translateX(4px);\n }\n}\n\n\n\n.search-input[_ngcontent-%COMP%]:focus-visible, \n.tab-button[_ngcontent-%COMP%]:focus-visible, \n.select-btn[_ngcontent-%COMP%]:focus-visible, \n.btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n@media (prefers-reduced-motion: reduce) {\n .dialog-overlay[_ngcontent-%COMP%], \n .dialog-container[_ngcontent-%COMP%], \n .create-form[_ngcontent-%COMP%], \n .list-item[_ngcontent-%COMP%], \n .btn[_ngcontent-%COMP%] {\n animation: none;\n transition: none;\n }\n}"] });
932
932
  }
933
933
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListManagementDialogComponent, [{
934
934
  type: Component,
935
- args: [{ standalone: false, selector: 'mj-list-management-dialog', template: "@if (visible) {\n <div class=\"dialog-overlay\" (click)=\"onCancel()\">\n <div class=\"dialog-container\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-content\">\n <div class=\"header-icon\">\n <span class=\"fa-solid fa-rectangle-list\"></span>\n </div>\n <div class=\"header-text\">\n <h2 class=\"dialog-title\">{{ dialogTitle }}</h2>\n <p class=\"dialog-subtitle\">{{ dialogSubtitle }}</p>\n </div>\n </div>\n <button class=\"close-button\" (click)=\"onCancel()\" title=\"Close\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n\n <!-- Search and Filters -->\n <div class=\"search-section\">\n <div class=\"search-bar\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search lists...\"\n [value]=\"searchText\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchText) {\n <button class=\"clear-search\" (click)=\"clearSearch()\">\n <span class=\"fa-solid fa-times-circle\"></span>\n </button>\n }\n </div>\n\n @if (config.allowCreate !== false) {\n <button class=\"create-button\" (click)=\"showCreateListForm()\" [disabled]=\"showCreateForm\">\n <span class=\"fa-solid fa-plus\"></span>\n <span class=\"button-text\">New</span>\n </button>\n }\n </div>\n\n <!-- Filter Tabs -->\n <div class=\"filter-tabs\">\n <div class=\"tabs-left\">\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'all'\"\n (click)=\"setActiveTab('all')\">\n All\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'my-lists'\"\n (click)=\"setActiveTab('my-lists')\">\n My Lists\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'recent'\"\n (click)=\"setActiveTab('recent')\">\n Recent\n </button>\n </div>\n <div class=\"tabs-right\">\n <select class=\"sort-select\" [value]=\"sortOption\" (change)=\"setSortOption($any($event.target).value)\">\n <option value=\"name\">Sort: Name</option>\n <option value=\"recent\">Sort: Recent</option>\n <option value=\"item-count\">Sort: Items</option>\n </select>\n </div>\n </div>\n\n <!-- Create List Form -->\n @if (showCreateForm) {\n <div class=\"create-form\">\n <div class=\"create-form-header\">\n <span class=\"fa-solid fa-plus-circle\"></span>\n <span>Create New List</span>\n </div>\n <div class=\"create-form-body\">\n <div class=\"form-group\">\n <input\n type=\"text\"\n class=\"form-input\"\n placeholder=\"List name *\"\n [(ngModel)]=\"newListName\"\n [disabled]=\"saving\"\n (keyup.enter)=\"createList()\"\n />\n </div>\n <div class=\"form-group\">\n <textarea\n class=\"form-input form-textarea\"\n placeholder=\"Description (optional)\"\n [(ngModel)]=\"newListDescription\"\n [disabled]=\"saving\"\n rows=\"2\">\n </textarea>\n </div>\n @if (categories.length > 0) {\n <div class=\"form-group\">\n <select class=\"form-input\" [(ngModel)]=\"newListCategoryId\" [disabled]=\"saving\">\n <option [ngValue]=\"null\">No category</option>\n @for (category of categories; track category.ID) {\n <option [ngValue]=\"category.ID\">{{ category.Name }}</option>\n }\n </select>\n </div>\n }\n <div class=\"create-form-actions\">\n <button\n class=\"btn btn-primary\"\n (click)=\"createList()\"\n [disabled]=\"!newListName.trim() || saving\">\n @if (saving) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n }\n Create List\n </button>\n <button class=\"btn btn-secondary\" (click)=\"cancelCreateList()\" [disabled]=\"saving\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- List Content -->\n <div class=\"list-content\">\n @if (loading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading lists...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (filteredLists.length === 0) {\n <div class=\"empty-state\">\n @if (searchText) {\n <span class=\"fa-solid fa-search empty-icon\"></span>\n <p class=\"empty-title\">No lists found</p>\n <p class=\"empty-subtitle\">Try a different search term</p>\n } @else {\n <span class=\"fa-solid fa-rectangle-list empty-icon\"></span>\n <p class=\"empty-title\">No lists yet</p>\n <p class=\"empty-subtitle\">Create your first list to get started</p>\n @if (config.allowCreate !== false) {\n <button class=\"btn btn-primary\" (click)=\"showCreateListForm()\">\n <span class=\"fa-solid fa-plus\"></span>\n Create List\n </button>\n }\n }\n </div>\n } @else {\n <div class=\"list-items\">\n @for (vm of filteredLists; track vm.list.ID) {\n <div\n class=\"list-item\"\n [class.selected-add]=\"vm.isSelectedForAdd || addedToLists.has(vm.list.ID)\"\n [class.selected-remove]=\"vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)\"\n [class.is-member]=\"vm.isFullMember || vm.isPartialMember\">\n\n <!-- Checkbox / Selection Area -->\n <div class=\"list-item-select\">\n @if (showAddButton(vm)) {\n <button\n class=\"select-btn add-btn\"\n [class.selected]=\"vm.isSelectedForAdd || addedToLists.has(vm.list.ID)\"\n (click)=\"toggleListForAdd(vm)\"\n [title]=\"(vm.isSelectedForAdd || addedToLists.has(vm.list.ID)) ? 'Remove from selection' : 'Add to this list'\">\n @if (vm.isSelectedForAdd || addedToLists.has(vm.list.ID)) {\n <span class=\"fa-solid fa-check\"></span>\n } @else {\n <span class=\"fa-solid fa-plus\"></span>\n }\n </button>\n }\n @if (showRemoveButton(vm) && (vm.isFullMember || vm.isPartialMember)) {\n <button\n class=\"select-btn remove-btn\"\n [class.selected]=\"vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)\"\n (click)=\"toggleListForRemove(vm)\"\n [title]=\"(vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)) ? 'Cancel removal' : 'Remove from this list'\">\n @if (vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)) {\n <span class=\"fa-solid fa-undo\"></span>\n } @else {\n <span class=\"fa-solid fa-minus\"></span>\n }\n </button>\n }\n </div>\n\n <!-- List Info -->\n <div class=\"list-item-content\">\n <div class=\"list-item-header\">\n <span class=\"fa-solid fa-folder list-icon\"></span>\n <span class=\"list-name\">{{ vm.list.Name }}</span>\n @if (newlyCreatedLists.includes(vm.list)) {\n <span class=\"badge badge-new\">New</span>\n }\n </div>\n <div class=\"list-item-meta\">\n @if (vm.list.Description) {\n <span class=\"list-description\">{{ vm.list.Description }}</span>\n <span class=\"meta-separator\">\u2022</span>\n }\n <span class=\"list-count\">{{ vm.itemCount }} item{{ vm.itemCount !== 1 ? 's' : '' }}</span>\n <span class=\"meta-separator\">\u2022</span>\n <span class=\"list-updated\">{{ formatDate(vm.lastUpdated) }}</span>\n </div>\n </div>\n\n <!-- Membership Indicator -->\n @if (config.showMembership !== false) {\n <div class=\"membership-indicator\" [class]=\"getMembershipClass(vm)\">\n <span [class]=\"getMembershipIcon(vm)\"></span>\n <span class=\"membership-text\">{{ getMembershipText(vm) }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-summary\">\n @if (hasChanges) {\n @if (addCount > 0) {\n <span class=\"summary-item add\">\n <span class=\"fa-solid fa-plus-circle\"></span>\n {{ addCount }} list{{ addCount !== 1 ? 's' : '' }}\n </span>\n }\n @if (removeCount > 0) {\n <span class=\"summary-item remove\">\n <span class=\"fa-solid fa-minus-circle\"></span>\n {{ removeCount }} list{{ removeCount !== 1 ? 's' : '' }}\n </span>\n }\n } @else {\n <span class=\"summary-empty\">No changes</span>\n }\n </div>\n <div class=\"footer-actions\">\n <button class=\"btn btn-secondary\" (click)=\"onCancel()\" [disabled]=\"saving\">\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"applyChanges()\"\n [disabled]=\"!hasChanges || saving\">\n @if (saving) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n }\n Apply Changes\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["/* ============================================\n List Management Dialog - Gorgeous Responsive Design\n ============================================ */\n\n/* Overlay */\n.dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: fadeIn 0.2s ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Container */\n.dialog-container {\n background: #ffffff;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n width: 90vw;\n max-width: 600px;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n animation: slideUp 0.3s ease-out;\n overflow: hidden;\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n.header-content {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-icon {\n width: 48px;\n height: 48px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n}\n\n.header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.dialog-title {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.dialog-subtitle {\n margin: 0;\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-button {\n width: 36px;\n height: 36px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 8px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.2s;\n}\n\n.close-button:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Search Section */\n.search-section {\n display: flex;\n gap: 12px;\n padding: 16px 20px;\n background: #f8fafc;\n border-bottom: 1px solid #e2e8f0;\n}\n\n.search-bar {\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon {\n position: absolute;\n left: 14px;\n color: #94a3b8;\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input {\n width: 100%;\n padding: 12px 40px 12px 42px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.2s;\n}\n\n.search-input:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);\n}\n\n.search-input::placeholder {\n color: #94a3b8;\n}\n\n.clear-search {\n position: absolute;\n right: 12px;\n border: none;\n background: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.clear-search:hover {\n color: #64748b;\n}\n\n.create-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.create-button:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n}\n\n.create-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* Filter Tabs */\n.filter-tabs {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n border-bottom: 1px solid #e2e8f0;\n background: white;\n}\n\n.tabs-left {\n display: flex;\n gap: 4px;\n}\n\n.tab-button {\n padding: 8px 16px;\n border: none;\n background: none;\n color: #64748b;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n\n.tab-button:hover {\n background: #f1f5f9;\n color: #334155;\n}\n\n.tab-button.active {\n background: #ede9fe;\n color: #7c3aed;\n}\n\n.sort-select {\n padding: 8px 12px;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-size: 13px;\n color: #64748b;\n background: white;\n cursor: pointer;\n}\n\n.sort-select:focus {\n outline: none;\n border-color: #667eea;\n}\n\n/* Create Form */\n.create-form {\n background: #fefce8;\n border-bottom: 1px solid #fde047;\n animation: slideDown 0.2s ease-out;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 300px;\n }\n}\n\n.create-form-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-weight: 600;\n color: #854d0e;\n font-size: 14px;\n border-bottom: 1px solid #fde047;\n}\n\n.create-form-body {\n padding: 16px 20px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-of-type {\n margin-bottom: 16px;\n}\n\n.form-input {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n background: white;\n transition: all 0.2s;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: #667eea;\n box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 60px;\n}\n\n.create-form-actions {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n}\n\n/* List Content */\n.list-content {\n flex: 1;\n overflow-y: auto;\n min-height: 200px;\n max-height: 400px;\n}\n\n/* Loading State */\n.loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\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: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: #cbd5e1;\n margin-bottom: 16px;\n}\n\n.empty-title {\n font-size: 16px;\n font-weight: 600;\n color: #334155;\n margin: 0 0 6px 0;\n}\n\n.empty-subtitle {\n font-size: 14px;\n color: #64748b;\n margin: 0 0 20px 0;\n}\n\n/* List Items */\n.list-items {\n padding: 8px 12px;\n}\n\n.list-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 8px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n transition: all 0.2s;\n}\n\n.list-item:last-child {\n margin-bottom: 0;\n}\n\n.list-item:hover {\n border-color: #cbd5e1;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n}\n\n.list-item.selected-add {\n background: #ecfdf5;\n border-color: #10b981;\n}\n\n.list-item.selected-remove {\n background: #fef2f2;\n border-color: #ef4444;\n}\n\n.list-item.is-member {\n border-left: 3px solid #667eea;\n}\n\n/* Selection Buttons */\n.list-item-select {\n display: flex;\n gap: 6px;\n}\n\n.select-btn {\n width: 32px;\n height: 32px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: all 0.2s;\n}\n\n.select-btn.add-btn:hover {\n border-color: #10b981;\n color: #10b981;\n background: #ecfdf5;\n}\n\n.select-btn.add-btn.selected {\n background: #10b981;\n border-color: #10b981;\n color: white;\n}\n\n.select-btn.remove-btn:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: #fef2f2;\n}\n\n.select-btn.remove-btn.selected {\n background: #ef4444;\n border-color: #ef4444;\n color: white;\n}\n\n/* List Item Content */\n.list-item-content {\n flex: 1;\n min-width: 0;\n}\n\n.list-item-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.list-icon {\n color: #667eea;\n font-size: 14px;\n}\n\n.list-name {\n font-weight: 600;\n font-size: 14px;\n color: #1e293b;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.badge-new {\n background: #dbeafe;\n color: #2563eb;\n}\n\n.list-item-meta {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n font-size: 12px;\n color: #64748b;\n}\n\n.list-description {\n max-width: 180px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.meta-separator {\n color: #cbd5e1;\n}\n\n/* Membership Indicator */\n.membership-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.membership-indicator.full-member {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.membership-indicator.partial-member {\n background: #fef3c7;\n color: #d97706;\n}\n\n.membership-indicator.not-member {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.membership-text {\n font-variant-numeric: tabular-nums;\n}\n\n/* Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: #f8fafc;\n border-top: 1px solid #e2e8f0;\n}\n\n.footer-summary {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.summary-item.add {\n color: #16a34a;\n}\n\n.summary-item.remove {\n color: #dc2626;\n}\n\n.summary-empty {\n color: #94a3b8;\n font-size: 13px;\n}\n\n.footer-actions {\n display: flex;\n gap: 10px;\n}\n\n/* Buttons */\n.btn {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s;\n border: none;\n}\n\n.btn-primary {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n.btn-primary:hover:not(:disabled) {\n box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n transform: translateY(-1px);\n}\n\n.btn-primary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n background: white;\n color: #64748b;\n border: 1px solid #e2e8f0;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #f8fafc;\n border-color: #cbd5e1;\n}\n\n.btn-secondary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ============================================\n Mobile Responsive - Bottom Sheet Pattern\n ============================================ */\n\n@media (max-width: 640px) {\n .dialog-overlay {\n align-items: flex-end;\n }\n\n .dialog-container {\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 24px 24px 0 0;\n animation: slideUpMobile 0.3s ease-out;\n }\n\n @keyframes slideUpMobile {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n\n .dialog-header {\n padding: 16px 20px;\n border-radius: 24px 24px 0 0;\n }\n\n .header-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .dialog-title {\n font-size: 16px;\n }\n\n .dialog-subtitle {\n font-size: 12px;\n }\n\n .search-section {\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .search-bar {\n width: 100%;\n order: 1;\n }\n\n .create-button {\n order: 2;\n width: 100%;\n justify-content: center;\n margin-top: 8px;\n }\n\n .button-text {\n display: inline;\n }\n\n .filter-tabs {\n padding: 10px 16px;\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .tabs-left {\n width: 100%;\n justify-content: space-between;\n }\n\n .tab-button {\n flex: 1;\n text-align: center;\n padding: 10px 8px;\n }\n\n .tabs-right {\n width: 100%;\n }\n\n .sort-select {\n width: 100%;\n }\n\n .list-content {\n max-height: 50vh;\n }\n\n .list-items {\n padding: 8px;\n }\n\n .list-item {\n padding: 12px;\n gap: 10px;\n }\n\n .list-item-content {\n flex: 1;\n min-width: 0;\n }\n\n .list-description {\n display: none;\n }\n\n .membership-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .dialog-footer {\n padding: 12px 16px;\n flex-direction: column;\n gap: 12px;\n }\n\n .footer-summary {\n width: 100%;\n justify-content: center;\n }\n\n .footer-actions {\n width: 100%;\n }\n\n .footer-actions .btn {\n flex: 1;\n justify-content: center;\n }\n\n .create-form-body {\n padding: 12px 16px;\n }\n\n .create-form-actions {\n flex-direction: column;\n }\n\n .create-form-actions .btn {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* Tablet adjustments */\n@media (min-width: 641px) and (max-width: 1024px) {\n .dialog-container {\n max-width: 550px;\n }\n\n .list-description {\n max-width: 140px;\n }\n}\n\n/* Large screen enhancements */\n@media (min-width: 1025px) {\n .list-content {\n max-height: 450px;\n }\n\n .list-item:hover {\n transform: translateX(4px);\n }\n}\n\n/* Accessibility - Focus states */\n.search-input:focus-visible,\n.tab-button:focus-visible,\n.select-btn:focus-visible,\n.btn:focus-visible {\n outline: 2px solid #667eea;\n outline-offset: 2px;\n}\n\n/* Reduced motion preference */\n@media (prefers-reduced-motion: reduce) {\n .dialog-overlay,\n .dialog-container,\n .create-form,\n .list-item,\n .btn {\n animation: none;\n transition: none;\n }\n}\n"] }]
935
+ args: [{ standalone: false, selector: 'mj-list-management-dialog', template: "@if (visible) {\n <div class=\"dialog-overlay\" (click)=\"onCancel()\">\n <div class=\"dialog-container\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"dialog-header\">\n <div class=\"header-content\">\n <div class=\"header-icon\">\n <span class=\"fa-solid fa-rectangle-list\"></span>\n </div>\n <div class=\"header-text\">\n <h2 class=\"dialog-title\">{{ dialogTitle }}</h2>\n <p class=\"dialog-subtitle\">{{ dialogSubtitle }}</p>\n </div>\n </div>\n <button class=\"close-button\" (click)=\"onCancel()\" title=\"Close\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n\n <!-- Search and Filters -->\n <div class=\"search-section\">\n <div class=\"search-bar\">\n <span class=\"fa-solid fa-search search-icon\"></span>\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search lists...\"\n [value]=\"searchText\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchText) {\n <button class=\"clear-search\" (click)=\"clearSearch()\">\n <span class=\"fa-solid fa-times-circle\"></span>\n </button>\n }\n </div>\n\n @if (config.allowCreate !== false) {\n <button class=\"create-button\" (click)=\"showCreateListForm()\" [disabled]=\"showCreateForm\">\n <span class=\"fa-solid fa-plus\"></span>\n <span class=\"button-text\">New</span>\n </button>\n }\n </div>\n\n <!-- Filter Tabs -->\n <div class=\"filter-tabs\">\n <div class=\"tabs-left\">\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'all'\"\n (click)=\"setActiveTab('all')\">\n All\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'my-lists'\"\n (click)=\"setActiveTab('my-lists')\">\n My Lists\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'recent'\"\n (click)=\"setActiveTab('recent')\">\n Recent\n </button>\n </div>\n <div class=\"tabs-right\">\n <select class=\"sort-select\" [value]=\"sortOption\" (change)=\"setSortOption($any($event.target).value)\">\n <option value=\"name\">Sort: Name</option>\n <option value=\"recent\">Sort: Recent</option>\n <option value=\"item-count\">Sort: Items</option>\n </select>\n </div>\n </div>\n\n <!-- Create List Form -->\n @if (showCreateForm) {\n <div class=\"create-form\">\n <div class=\"create-form-header\">\n <span class=\"fa-solid fa-plus-circle\"></span>\n <span>Create New List</span>\n </div>\n <div class=\"create-form-body\">\n <div class=\"form-group\">\n <input\n type=\"text\"\n class=\"form-input\"\n placeholder=\"List name *\"\n [(ngModel)]=\"newListName\"\n [disabled]=\"saving\"\n (keyup.enter)=\"createList()\"\n />\n </div>\n <div class=\"form-group\">\n <textarea\n class=\"form-input form-textarea\"\n placeholder=\"Description (optional)\"\n [(ngModel)]=\"newListDescription\"\n [disabled]=\"saving\"\n rows=\"2\">\n </textarea>\n </div>\n @if (categories.length > 0) {\n <div class=\"form-group\">\n <select class=\"form-input\" [(ngModel)]=\"newListCategoryId\" [disabled]=\"saving\">\n <option [ngValue]=\"null\">No category</option>\n @for (category of categories; track category.ID) {\n <option [ngValue]=\"category.ID\">{{ category.Name }}</option>\n }\n </select>\n </div>\n }\n <div class=\"create-form-actions\">\n <button\n class=\"btn btn-primary\"\n (click)=\"createList()\"\n [disabled]=\"!newListName.trim() || saving\">\n @if (saving) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n }\n Create List\n </button>\n <button class=\"btn btn-secondary\" (click)=\"cancelCreateList()\" [disabled]=\"saving\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- List Content -->\n <div class=\"list-content\">\n @if (loading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading lists...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (filteredLists.length === 0) {\n <div class=\"empty-state\">\n @if (searchText) {\n <span class=\"fa-solid fa-search empty-icon\"></span>\n <p class=\"empty-title\">No lists found</p>\n <p class=\"empty-subtitle\">Try a different search term</p>\n } @else {\n <span class=\"fa-solid fa-rectangle-list empty-icon\"></span>\n <p class=\"empty-title\">No lists yet</p>\n <p class=\"empty-subtitle\">Create your first list to get started</p>\n @if (config.allowCreate !== false) {\n <button class=\"btn btn-primary\" (click)=\"showCreateListForm()\">\n <span class=\"fa-solid fa-plus\"></span>\n Create List\n </button>\n }\n }\n </div>\n } @else {\n <div class=\"list-items\">\n @for (vm of filteredLists; track vm.list.ID) {\n <div\n class=\"list-item\"\n [class.selected-add]=\"vm.isSelectedForAdd || addedToLists.has(vm.list.ID)\"\n [class.selected-remove]=\"vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)\"\n [class.is-member]=\"vm.isFullMember || vm.isPartialMember\">\n\n <!-- Checkbox / Selection Area -->\n <div class=\"list-item-select\">\n @if (showAddButton(vm)) {\n <button\n class=\"select-btn add-btn\"\n [class.selected]=\"vm.isSelectedForAdd || addedToLists.has(vm.list.ID)\"\n (click)=\"toggleListForAdd(vm)\"\n [title]=\"(vm.isSelectedForAdd || addedToLists.has(vm.list.ID)) ? 'Remove from selection' : 'Add to this list'\">\n @if (vm.isSelectedForAdd || addedToLists.has(vm.list.ID)) {\n <span class=\"fa-solid fa-check\"></span>\n } @else {\n <span class=\"fa-solid fa-plus\"></span>\n }\n </button>\n }\n @if (showRemoveButton(vm) && (vm.isFullMember || vm.isPartialMember)) {\n <button\n class=\"select-btn remove-btn\"\n [class.selected]=\"vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)\"\n (click)=\"toggleListForRemove(vm)\"\n [title]=\"(vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)) ? 'Cancel removal' : 'Remove from this list'\">\n @if (vm.isSelectedForRemove || removedFromLists.has(vm.list.ID)) {\n <span class=\"fa-solid fa-undo\"></span>\n } @else {\n <span class=\"fa-solid fa-minus\"></span>\n }\n </button>\n }\n </div>\n\n <!-- List Info -->\n <div class=\"list-item-content\">\n <div class=\"list-item-header\">\n <span class=\"fa-solid fa-folder list-icon\"></span>\n <span class=\"list-name\">{{ vm.list.Name }}</span>\n @if (newlyCreatedLists.includes(vm.list)) {\n <span class=\"badge badge-new\">New</span>\n }\n </div>\n <div class=\"list-item-meta\">\n @if (vm.list.Description) {\n <span class=\"list-description\">{{ vm.list.Description }}</span>\n <span class=\"meta-separator\">\u2022</span>\n }\n <span class=\"list-count\">{{ vm.itemCount }} item{{ vm.itemCount !== 1 ? 's' : '' }}</span>\n <span class=\"meta-separator\">\u2022</span>\n <span class=\"list-updated\">{{ formatDate(vm.lastUpdated) }}</span>\n </div>\n </div>\n\n <!-- Membership Indicator -->\n @if (config.showMembership !== false) {\n <div class=\"membership-indicator\" [class]=\"getMembershipClass(vm)\">\n <span [class]=\"getMembershipIcon(vm)\"></span>\n <span class=\"membership-text\">{{ getMembershipText(vm) }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"dialog-footer\">\n <div class=\"footer-summary\">\n @if (hasChanges) {\n @if (addCount > 0) {\n <span class=\"summary-item add\">\n <span class=\"fa-solid fa-plus-circle\"></span>\n {{ addCount }} list{{ addCount !== 1 ? 's' : '' }}\n </span>\n }\n @if (removeCount > 0) {\n <span class=\"summary-item remove\">\n <span class=\"fa-solid fa-minus-circle\"></span>\n {{ removeCount }} list{{ removeCount !== 1 ? 's' : '' }}\n </span>\n }\n } @else {\n <span class=\"summary-empty\">No changes</span>\n }\n </div>\n <div class=\"footer-actions\">\n <button class=\"btn btn-secondary\" (click)=\"onCancel()\" [disabled]=\"saving\">\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"applyChanges()\"\n [disabled]=\"!hasChanges || saving\">\n @if (saving) {\n <span class=\"fa-solid fa-spinner fa-spin\"></span>\n }\n Apply Changes\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["/* ============================================\n List Management Dialog - Gorgeous Responsive Design\n ============================================ */\n\n/* Overlay */\n.dialog-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n animation: fadeIn 0.2s ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Dialog Container */\n.dialog-container {\n background: var(--mj-bg-surface-card);\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px var(--mj-shadow-lg);\n width: 90vw;\n max-width: 600px;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n animation: slideUp 0.3s ease-out;\n overflow: hidden;\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Header */\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.header-content {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-icon {\n width: 48px;\n height: 48px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n}\n\n.header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.dialog-title {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.01em;\n}\n\n.dialog-subtitle {\n margin: 0;\n font-size: 13px;\n opacity: 0.85;\n}\n\n.close-button {\n width: 36px;\n height: 36px;\n border: none;\n background: rgba(255, 255, 255, 0.15);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.2s;\n}\n\n.close-button:hover {\n background: rgba(255, 255, 255, 0.25);\n}\n\n/* Search Section */\n.search-section {\n display: flex;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-bar {\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon {\n position: absolute;\n left: 14px;\n color: var(--mj-text-muted);\n font-size: 14px;\n pointer-events: none;\n}\n\n.search-input {\n width: 100%;\n padding: 12px 40px 12px 42px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface-card);\n transition: all 0.2s;\n}\n\n.search-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) 15%, transparent);\n}\n\n.search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.clear-search {\n position: absolute;\n right: 12px;\n border: none;\n background: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.clear-search:hover {\n color: var(--mj-text-secondary);\n}\n\n.create-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 18px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.create-button:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.create-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* Filter Tabs */\n.filter-tabs {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.tabs-left {\n display: flex;\n gap: 4px;\n}\n\n.tab-button {\n padding: 8px 16px;\n border: none;\n background: none;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n\n.tab-button:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.tab-button.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.sort-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n}\n\n.sort-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Create Form */\n.create-form {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n animation: slideDown 0.2s ease-out;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 300px;\n }\n}\n\n.create-form-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 20px;\n font-weight: 600;\n color: var(--mj-status-warning);\n font-size: 14px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.create-form-body {\n padding: 16px 20px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-of-type {\n margin-bottom: 16px;\n}\n\n.form-input {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n background: var(--mj-bg-surface-card);\n transition: all 0.2s;\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) 15%, transparent);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 60px;\n}\n\n.create-form-actions {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n}\n\n/* List Content */\n.list-content {\n flex: 1;\n overflow-y: auto;\n min-height: 200px;\n max-height: 400px;\n}\n\n/* Loading State */\n.loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\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: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-strong);\n margin-bottom: 16px;\n}\n\n.empty-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 6px 0;\n}\n\n.empty-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0 0 20px 0;\n}\n\n/* List Items */\n.list-items {\n padding: 8px 12px;\n}\n\n.list-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n margin-bottom: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s;\n}\n\n.list-item:last-child {\n margin-bottom: 0;\n}\n\n.list-item:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 2px 8px var(--mj-shadow-sm);\n}\n\n.list-item.selected-add {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-success);\n}\n\n.list-item.selected-remove {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-error);\n}\n\n.list-item.is-member {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n/* Selection Buttons */\n.list-item-select {\n display: flex;\n gap: 6px;\n}\n\n.select-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: all 0.2s;\n}\n\n.select-btn.add-btn:hover {\n border-color: var(--mj-status-success);\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.select-btn.add-btn.selected {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.select-btn.remove-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.select-btn.remove-btn.selected {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n/* List Item Content */\n.list-item-content {\n flex: 1;\n min-width: 0;\n}\n\n.list-item-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.list-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.list-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.badge-new {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.list-item-meta {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.list-description {\n max-width: 180px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.meta-separator {\n color: var(--mj-border-strong);\n}\n\n/* Membership Indicator */\n.membership-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.membership-indicator.full-member {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.membership-indicator.partial-member {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.membership-indicator.not-member {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.membership-text {\n font-variant-numeric: tabular-nums;\n}\n\n/* Footer */\n.dialog-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.footer-summary {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.summary-item.add {\n color: var(--mj-status-success);\n}\n\n.summary-item.remove {\n color: var(--mj-status-error);\n}\n\n.summary-empty {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.footer-actions {\n display: flex;\n gap: 10px;\n}\n\n/* Buttons */\n.btn {\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s;\n border: none;\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 box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateY(-1px);\n}\n\n.btn-primary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.btn-secondary:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ============================================\n Mobile Responsive - Bottom Sheet Pattern\n ============================================ */\n\n@media (max-width: 640px) {\n .dialog-overlay {\n align-items: flex-end;\n }\n\n .dialog-container {\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 24px 24px 0 0;\n animation: slideUpMobile 0.3s ease-out;\n }\n\n @keyframes slideUpMobile {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n }\n\n .dialog-header {\n padding: 16px 20px;\n border-radius: 24px 24px 0 0;\n }\n\n .header-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .dialog-title {\n font-size: 16px;\n }\n\n .dialog-subtitle {\n font-size: 12px;\n }\n\n .search-section {\n padding: 12px 16px;\n flex-wrap: wrap;\n }\n\n .search-bar {\n width: 100%;\n order: 1;\n }\n\n .create-button {\n order: 2;\n width: 100%;\n justify-content: center;\n margin-top: 8px;\n }\n\n .button-text {\n display: inline;\n }\n\n .filter-tabs {\n padding: 10px 16px;\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .tabs-left {\n width: 100%;\n justify-content: space-between;\n }\n\n .tab-button {\n flex: 1;\n text-align: center;\n padding: 10px 8px;\n }\n\n .tabs-right {\n width: 100%;\n }\n\n .sort-select {\n width: 100%;\n }\n\n .list-content {\n max-height: 50vh;\n }\n\n .list-items {\n padding: 8px;\n }\n\n .list-item {\n padding: 12px;\n gap: 10px;\n }\n\n .list-item-content {\n flex: 1;\n min-width: 0;\n }\n\n .list-description {\n display: none;\n }\n\n .membership-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n\n .dialog-footer {\n padding: 12px 16px;\n flex-direction: column;\n gap: 12px;\n }\n\n .footer-summary {\n width: 100%;\n justify-content: center;\n }\n\n .footer-actions {\n width: 100%;\n }\n\n .footer-actions .btn {\n flex: 1;\n justify-content: center;\n }\n\n .create-form-body {\n padding: 12px 16px;\n }\n\n .create-form-actions {\n flex-direction: column;\n }\n\n .create-form-actions .btn {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* Tablet adjustments */\n@media (min-width: 641px) and (max-width: 1024px) {\n .dialog-container {\n max-width: 550px;\n }\n\n .list-description {\n max-width: 140px;\n }\n}\n\n/* Large screen enhancements */\n@media (min-width: 1025px) {\n .list-content {\n max-height: 450px;\n }\n\n .list-item:hover {\n transform: translateX(4px);\n }\n}\n\n/* Accessibility - Focus states */\n.search-input:focus-visible,\n.tab-button:focus-visible,\n.select-btn:focus-visible,\n.btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Reduced motion preference */\n@media (prefers-reduced-motion: reduce) {\n .dialog-overlay,\n .dialog-container,\n .create-form,\n .list-item,\n .btn {\n animation: none;\n transition: none;\n }\n}\n"] }]
936
936
  }], () => [{ type: i1.ListManagementService }, { type: i0.ChangeDetectorRef }], { config: [{
937
937
  type: Input
938
938
  }], visible: [{
@@ -644,11 +644,11 @@ export class ListShareDialogComponent {
644
644
  i0.ɵɵconditionalCreate(0, ListShareDialogComponent_Conditional_0_Template, 9, 5, "kendo-dialog", 0);
645
645
  } if (rf & 2) {
646
646
  i0.ɵɵconditional(ctx.visible ? 0 : -1);
647
- } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.DialogComponent, i3.DialogActionsComponent, i4.ButtonComponent, i5.TextBoxComponent, i5.TextBoxPrefixTemplateDirective, i6.ItemTemplateDirective, i6.DropDownListComponent, i7.LoadingComponent], styles: [".share-dialog-content[_ngcontent-%COMP%] {\n padding: 0;\n min-height: 200px;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n}\n\n\n\n.section-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.section-divider[_ngcontent-%COMP%] {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--mj-border-color, #e0e0e0);\n}\n\n\n\n.add-share-section[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary, #666);\n margin-left: 8px;\n}\n\n.search-results[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: white;\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-height: 200px;\n overflow-y: auto;\n z-index: 1000;\n}\n\n.search-result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.search-result-item[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-hover-bg, #f5f5f5);\n}\n\n.search-result-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary, #666);\n width: 20px;\n text-align: center;\n}\n\n.recipient-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.recipient-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.recipient-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary, #666);\n}\n\n\n\n.selected-recipient[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-secondary, #f8f9fa);\n border-radius: 6px;\n}\n\n.recipient-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: white;\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 20px;\n flex: 1;\n}\n\n.recipient-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-primary-color, #0078d4);\n}\n\n.recipient-chip[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.permission-dropdown[_ngcontent-%COMP%] {\n width: 150px;\n}\n\n\n\n.permission-option[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n\n.permission-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.permission-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary, #666);\n}\n\n\n\n.current-shares-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.share-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.share-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-secondary, #f8f9fa);\n border-radius: 6px;\n transition: background-color 0.15s;\n}\n\n.share-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-hover-bg, #f0f0f0);\n}\n\n.share-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.share-type-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-primary-color-light, #e6f2ff);\n color: var(--mj-primary-color, #0078d4);\n border-radius: 50%;\n}\n\n.share-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.share-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.share-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary, #666);\n}\n\n.share-type-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary, #666);\n background: var(--mj-border-color, #e0e0e0);\n padding: 2px 6px;\n border-radius: 3px;\n display: inline-block;\n width: fit-content;\n}\n\n.share-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.permission-dropdown-small[_ngcontent-%COMP%] {\n width: 110px;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n background: var(--mj-primary-color-light, #e6f2ff);\n color: var(--mj-primary-color, #0078d4);\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\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: 40px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-color, #e0e0e0);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-secondary, #666);\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n font-size: 13px;\n margin-top: 8px !important;\n}\n\n\n\n.readonly-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: var(--mj-warning-bg, #fff8e1);\n border-radius: 6px;\n margin-top: 16px;\n color: var(--mj-warning-color, #856404);\n font-size: 13px;\n}\n\n.readonly-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-warning-color, #ffc107);\n}\n\n\n\n[_nghost-%COMP%] kendo-dialog-actions {\n flex-direction: row;\n justify-content: flex-start;\n}"] });
647
+ } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.DialogComponent, i3.DialogActionsComponent, i4.ButtonComponent, i5.TextBoxComponent, i5.TextBoxPrefixTemplateDirective, i6.ItemTemplateDirective, i6.DropDownListComponent, i7.LoadingComponent], styles: [".share-dialog-content[_ngcontent-%COMP%] {\n padding: 0;\n min-height: 200px;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n}\n\n\n\n.section-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.section-divider[_ngcontent-%COMP%] {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n\n.add-share-section[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.search-type-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n margin-left: 8px;\n}\n\n.search-results[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n box-shadow: var(--mj-shadow-md);\n max-height: 200px;\n overflow-y: auto;\n z-index: 1000;\n}\n\n.search-result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.search-result-item[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.search-result-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n width: 20px;\n text-align: center;\n}\n\n.recipient-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.recipient-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.recipient-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.selected-recipient[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n}\n\n.recipient-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n flex: 1;\n}\n\n.recipient-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.recipient-chip[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.permission-dropdown[_ngcontent-%COMP%] {\n width: 150px;\n}\n\n\n\n.permission-option[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n\n.permission-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.permission-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.current-shares-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.share-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.share-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n transition: background-color 0.15s;\n}\n\n.share-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.share-type-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 50%;\n}\n\n.share-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.share-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.share-type-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-border-default);\n padding: 2px 6px;\n border-radius: 3px;\n display: inline-block;\n width: fit-content;\n}\n\n.share-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.permission-dropdown-small[_ngcontent-%COMP%] {\n width: 110px;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\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: 40px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-secondary);\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n font-size: 13px;\n margin-top: 8px !important;\n}\n\n\n\n.readonly-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-radius: 6px;\n margin-top: 16px;\n color: var(--mj-status-warning);\n font-size: 13px;\n}\n\n.readonly-notice[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n\n[_nghost-%COMP%] kendo-dialog-actions {\n flex-direction: row;\n justify-content: flex-start;\n}"] });
648
648
  }
649
649
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ListShareDialogComponent, [{
650
650
  type: Component,
651
- args: [{ standalone: false, selector: 'mj-list-share-dialog', template: "@if (visible) {\n <kendo-dialog\n [title]=\"dialogTitle\"\n [width]=\"500\"\n [minWidth]=\"400\"\n (close)=\"onCancel()\">\n <div class=\"share-dialog-content\">\n <!-- Loading state -->\n @if (loading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading shares...\"></mj-loading>\n </div>\n }\n @if (!loading) {\n <!-- Add new share section -->\n @if (canModifyShares) {\n <div class=\"add-share-section\">\n <h4 class=\"section-title\">Add people or roles</h4>\n <!-- Search type toggle -->\n <div class=\"search-type-toggle\">\n <button kendoButton\n [fillMode]=\"searchType === 'User' ? 'solid' : 'outline'\"\n [themeColor]=\"searchType === 'User' ? 'primary' : 'base'\"\n (click)=\"setSearchType('User')\">\n <i class=\"fa-solid fa-user\"></i> Users\n </button>\n <button kendoButton\n [fillMode]=\"searchType === 'Role' ? 'solid' : 'outline'\"\n [themeColor]=\"searchType === 'Role' ? 'primary' : 'base'\"\n (click)=\"setSearchType('Role')\">\n <i class=\"fa-solid fa-users\"></i> Roles\n </button>\n </div>\n <!-- Search input -->\n <div class=\"search-container\">\n <kendo-textbox\n [value]=\"searchText\"\n (valueChange)=\"onSearchInput($event)\"\n [placeholder]=\"'Search for ' + (searchType === 'User' ? 'users' : 'roles') + '...'\"\n [clearButton]=\"true\"\n (blur)=\"showSearchResults = false\">\n <ng-template kendoTextBoxPrefixTemplate>\n <i class=\"fa-solid fa-search search-icon\"></i>\n </ng-template>\n </kendo-textbox>\n <!-- Search results dropdown -->\n @if (showSearchResults && searchResults.length > 0) {\n <div class=\"search-results\">\n @for (recipient of searchResults; track recipient) {\n <div class=\"search-result-item\"\n (mousedown)=\"selectRecipient(recipient)\">\n <i [class]=\"getShareTypeIcon(recipient.type)\"></i>\n <div class=\"recipient-info\">\n <span class=\"recipient-name\">{{ recipient.name }}</span>\n @if (recipient.email) {\n <span class=\"recipient-email\">{{ recipient.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n <!-- Selected recipient and permission -->\n @if (selectedRecipient) {\n <div class=\"selected-recipient\">\n <div class=\"recipient-chip\">\n <i [class]=\"getShareTypeIcon(selectedRecipient.type)\"></i>\n <span>{{ selectedRecipient.name }}</span>\n <button kendoButton [look]=\"'flat'\" [icon]=\"'close'\" (click)=\"clearSearch()\"></button>\n </div>\n <kendo-dropdownlist\n [data]=\"permissionOptions\"\n [textField]=\"'label'\"\n [valueField]=\"'value'\"\n [(ngModel)]=\"selectedPermission\"\n [valuePrimitive]=\"true\"\n class=\"permission-dropdown\">\n <ng-template kendoDropDownListItemTemplate let-dataItem>\n <div class=\"permission-option\">\n <span class=\"permission-label\">{{ dataItem.label }}</span>\n <span class=\"permission-desc\">{{ dataItem.description }}</span>\n </div>\n </ng-template>\n </kendo-dropdownlist>\n <button kendoButton\n themeColor=\"primary\"\n [disabled]=\"saving\"\n (click)=\"addShare()\">\n <i class=\"fa-solid fa-plus\"></i> Add\n </button>\n </div>\n }\n </div>\n }\n <!-- Divider -->\n @if (currentShares.length > 0 && canModifyShares) {\n <hr class=\"section-divider\">\n }\n <!-- Current shares section -->\n @if (currentShares.length > 0) {\n <div class=\"current-shares-section\">\n <h4 class=\"section-title\">People with access</h4>\n <div class=\"share-list\">\n @for (share of currentShares; track share) {\n <div class=\"share-item\">\n <div class=\"share-info\">\n <i [class]=\"getShareTypeIcon(share.type)\" class=\"share-type-icon\"></i>\n <div class=\"share-details\">\n <span class=\"share-name\">{{ share.recipientName }}</span>\n @if (share.recipientEmail) {\n <span class=\"share-email\">{{ share.recipientEmail }}</span>\n }\n @if (share.type === 'Role') {\n <span class=\"share-type-label\">Role</span>\n }\n </div>\n </div>\n <div class=\"share-actions\">\n @if (canModifyShares) {\n <kendo-dropdownlist\n [data]=\"permissionOptions\"\n [textField]=\"'label'\"\n [valueField]=\"'value'\"\n [value]=\"share.permissionLevel\"\n [valuePrimitive]=\"true\"\n (valueChange)=\"updateSharePermission(share, $event)\"\n [disabled]=\"saving\"\n class=\"permission-dropdown-small\">\n </kendo-dropdownlist>\n }\n @if (!canModifyShares) {\n <span class=\"permission-badge\">\n {{ getPermissionLabel(share.permissionLevel) }}\n </span>\n }\n @if (canModifyShares) {\n <button kendoButton\n [look]=\"'flat'\"\n [icon]=\"'trash'\"\n title=\"Remove access\"\n [disabled]=\"saving\"\n (click)=\"removeShare(share)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty state -->\n @if (currentShares.length === 0 && !loading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-share-nodes empty-icon\"></i>\n <p>This list hasn't been shared with anyone yet.</p>\n @if (canModifyShares) {\n <p class=\"empty-hint\">\n Use the search above to find users or roles to share with.\n </p>\n }\n </div>\n }\n <!-- Read-only notice -->\n @if (!canModifyShares) {\n <div class=\"readonly-notice\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Only the list owner can manage sharing.</span>\n </div>\n }\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton themeColor=\"primary\" (click)=\"onDone()\">Done</button>\n <button kendoButton (click)=\"onCancel()\">Cancel</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: [".share-dialog-content {\n padding: 0;\n min-height: 200px;\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n}\n\n/* Section styling */\n.section-title {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.section-divider {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--mj-border-color, #e0e0e0);\n}\n\n/* Add share section */\n.add-share-section {\n margin-bottom: 16px;\n}\n\n.search-type-toggle {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.search-type-toggle button {\n flex: 1;\n}\n\n.search-type-toggle i {\n margin-right: 6px;\n}\n\n/* Search container */\n.search-container {\n position: relative;\n}\n\n.search-icon {\n color: var(--mj-text-secondary, #666);\n margin-left: 8px;\n}\n\n.search-results {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: white;\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-height: 200px;\n overflow-y: auto;\n z-index: 1000;\n}\n\n.search-result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.search-result-item:hover {\n background-color: var(--mj-hover-bg, #f5f5f5);\n}\n\n.search-result-item i {\n color: var(--mj-text-secondary, #666);\n width: 20px;\n text-align: center;\n}\n\n.recipient-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.recipient-name {\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.recipient-email {\n font-size: 12px;\n color: var(--mj-text-secondary, #666);\n}\n\n/* Selected recipient */\n.selected-recipient {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-secondary, #f8f9fa);\n border-radius: 6px;\n}\n\n.recipient-chip {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: white;\n border: 1px solid var(--mj-border-color, #e0e0e0);\n border-radius: 20px;\n flex: 1;\n}\n\n.recipient-chip i {\n color: var(--mj-primary-color, #0078d4);\n}\n\n.recipient-chip span {\n flex: 1;\n font-weight: 500;\n}\n\n.permission-dropdown {\n width: 150px;\n}\n\n/* Permission option template */\n.permission-option {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n\n.permission-label {\n font-weight: 500;\n}\n\n.permission-desc {\n font-size: 11px;\n color: var(--mj-text-secondary, #666);\n}\n\n/* Current shares section */\n.current-shares-section {\n margin-top: 16px;\n}\n\n.share-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.share-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-secondary, #f8f9fa);\n border-radius: 6px;\n transition: background-color 0.15s;\n}\n\n.share-item:hover {\n background: var(--mj-hover-bg, #f0f0f0);\n}\n\n.share-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.share-type-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-primary-color-light, #e6f2ff);\n color: var(--mj-primary-color, #0078d4);\n border-radius: 50%;\n}\n\n.share-details {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.share-name {\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.share-email {\n font-size: 12px;\n color: var(--mj-text-secondary, #666);\n}\n\n.share-type-label {\n font-size: 11px;\n color: var(--mj-text-secondary, #666);\n background: var(--mj-border-color, #e0e0e0);\n padding: 2px 6px;\n border-radius: 3px;\n display: inline-block;\n width: fit-content;\n}\n\n.share-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.permission-dropdown-small {\n width: 110px;\n}\n\n.permission-badge {\n padding: 4px 10px;\n background: var(--mj-primary-color-light, #e6f2ff);\n color: var(--mj-primary-color, #0078d4);\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\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: 40px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-color, #e0e0e0);\n margin-bottom: 16px;\n}\n\n.empty-state p {\n margin: 0;\n color: var(--mj-text-secondary, #666);\n}\n\n.empty-hint {\n font-size: 13px;\n margin-top: 8px !important;\n}\n\n/* Read-only notice */\n.readonly-notice {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: var(--mj-warning-bg, #fff8e1);\n border-radius: 6px;\n margin-top: 16px;\n color: var(--mj-warning-color, #856404);\n font-size: 13px;\n}\n\n.readonly-notice i {\n color: var(--mj-warning-color, #ffc107);\n}\n\n/* Dialog actions - buttons on left */\n:host ::ng-deep kendo-dialog-actions {\n flex-direction: row;\n justify-content: flex-start;\n}\n"] }]
651
+ args: [{ standalone: false, selector: 'mj-list-share-dialog', template: "@if (visible) {\n <kendo-dialog\n [title]=\"dialogTitle\"\n [width]=\"500\"\n [minWidth]=\"400\"\n (close)=\"onCancel()\">\n <div class=\"share-dialog-content\">\n <!-- Loading state -->\n @if (loading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading shares...\"></mj-loading>\n </div>\n }\n @if (!loading) {\n <!-- Add new share section -->\n @if (canModifyShares) {\n <div class=\"add-share-section\">\n <h4 class=\"section-title\">Add people or roles</h4>\n <!-- Search type toggle -->\n <div class=\"search-type-toggle\">\n <button kendoButton\n [fillMode]=\"searchType === 'User' ? 'solid' : 'outline'\"\n [themeColor]=\"searchType === 'User' ? 'primary' : 'base'\"\n (click)=\"setSearchType('User')\">\n <i class=\"fa-solid fa-user\"></i> Users\n </button>\n <button kendoButton\n [fillMode]=\"searchType === 'Role' ? 'solid' : 'outline'\"\n [themeColor]=\"searchType === 'Role' ? 'primary' : 'base'\"\n (click)=\"setSearchType('Role')\">\n <i class=\"fa-solid fa-users\"></i> Roles\n </button>\n </div>\n <!-- Search input -->\n <div class=\"search-container\">\n <kendo-textbox\n [value]=\"searchText\"\n (valueChange)=\"onSearchInput($event)\"\n [placeholder]=\"'Search for ' + (searchType === 'User' ? 'users' : 'roles') + '...'\"\n [clearButton]=\"true\"\n (blur)=\"showSearchResults = false\">\n <ng-template kendoTextBoxPrefixTemplate>\n <i class=\"fa-solid fa-search search-icon\"></i>\n </ng-template>\n </kendo-textbox>\n <!-- Search results dropdown -->\n @if (showSearchResults && searchResults.length > 0) {\n <div class=\"search-results\">\n @for (recipient of searchResults; track recipient) {\n <div class=\"search-result-item\"\n (mousedown)=\"selectRecipient(recipient)\">\n <i [class]=\"getShareTypeIcon(recipient.type)\"></i>\n <div class=\"recipient-info\">\n <span class=\"recipient-name\">{{ recipient.name }}</span>\n @if (recipient.email) {\n <span class=\"recipient-email\">{{ recipient.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n <!-- Selected recipient and permission -->\n @if (selectedRecipient) {\n <div class=\"selected-recipient\">\n <div class=\"recipient-chip\">\n <i [class]=\"getShareTypeIcon(selectedRecipient.type)\"></i>\n <span>{{ selectedRecipient.name }}</span>\n <button kendoButton [look]=\"'flat'\" [icon]=\"'close'\" (click)=\"clearSearch()\"></button>\n </div>\n <kendo-dropdownlist\n [data]=\"permissionOptions\"\n [textField]=\"'label'\"\n [valueField]=\"'value'\"\n [(ngModel)]=\"selectedPermission\"\n [valuePrimitive]=\"true\"\n class=\"permission-dropdown\">\n <ng-template kendoDropDownListItemTemplate let-dataItem>\n <div class=\"permission-option\">\n <span class=\"permission-label\">{{ dataItem.label }}</span>\n <span class=\"permission-desc\">{{ dataItem.description }}</span>\n </div>\n </ng-template>\n </kendo-dropdownlist>\n <button kendoButton\n themeColor=\"primary\"\n [disabled]=\"saving\"\n (click)=\"addShare()\">\n <i class=\"fa-solid fa-plus\"></i> Add\n </button>\n </div>\n }\n </div>\n }\n <!-- Divider -->\n @if (currentShares.length > 0 && canModifyShares) {\n <hr class=\"section-divider\">\n }\n <!-- Current shares section -->\n @if (currentShares.length > 0) {\n <div class=\"current-shares-section\">\n <h4 class=\"section-title\">People with access</h4>\n <div class=\"share-list\">\n @for (share of currentShares; track share) {\n <div class=\"share-item\">\n <div class=\"share-info\">\n <i [class]=\"getShareTypeIcon(share.type)\" class=\"share-type-icon\"></i>\n <div class=\"share-details\">\n <span class=\"share-name\">{{ share.recipientName }}</span>\n @if (share.recipientEmail) {\n <span class=\"share-email\">{{ share.recipientEmail }}</span>\n }\n @if (share.type === 'Role') {\n <span class=\"share-type-label\">Role</span>\n }\n </div>\n </div>\n <div class=\"share-actions\">\n @if (canModifyShares) {\n <kendo-dropdownlist\n [data]=\"permissionOptions\"\n [textField]=\"'label'\"\n [valueField]=\"'value'\"\n [value]=\"share.permissionLevel\"\n [valuePrimitive]=\"true\"\n (valueChange)=\"updateSharePermission(share, $event)\"\n [disabled]=\"saving\"\n class=\"permission-dropdown-small\">\n </kendo-dropdownlist>\n }\n @if (!canModifyShares) {\n <span class=\"permission-badge\">\n {{ getPermissionLabel(share.permissionLevel) }}\n </span>\n }\n @if (canModifyShares) {\n <button kendoButton\n [look]=\"'flat'\"\n [icon]=\"'trash'\"\n title=\"Remove access\"\n [disabled]=\"saving\"\n (click)=\"removeShare(share)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Empty state -->\n @if (currentShares.length === 0 && !loading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-share-nodes empty-icon\"></i>\n <p>This list hasn't been shared with anyone yet.</p>\n @if (canModifyShares) {\n <p class=\"empty-hint\">\n Use the search above to find users or roles to share with.\n </p>\n }\n </div>\n }\n <!-- Read-only notice -->\n @if (!canModifyShares) {\n <div class=\"readonly-notice\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Only the list owner can manage sharing.</span>\n </div>\n }\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton themeColor=\"primary\" (click)=\"onDone()\">Done</button>\n <button kendoButton (click)=\"onCancel()\">Cancel</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: [".share-dialog-content {\n padding: 0;\n min-height: 200px;\n}\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n}\n\n/* Section styling */\n.section-title {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.section-divider {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* Add share section */\n.add-share-section {\n margin-bottom: 16px;\n}\n\n.search-type-toggle {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.search-type-toggle button {\n flex: 1;\n}\n\n.search-type-toggle i {\n margin-right: 6px;\n}\n\n/* Search container */\n.search-container {\n position: relative;\n}\n\n.search-icon {\n color: var(--mj-text-secondary);\n margin-left: 8px;\n}\n\n.search-results {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n box-shadow: var(--mj-shadow-md);\n max-height: 200px;\n overflow-y: auto;\n z-index: 1000;\n}\n\n.search-result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n\n.search-result-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.search-result-item i {\n color: var(--mj-text-secondary);\n width: 20px;\n text-align: center;\n}\n\n.recipient-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.recipient-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.recipient-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Selected recipient */\n.selected-recipient {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n}\n\n.recipient-chip {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n flex: 1;\n}\n\n.recipient-chip i {\n color: var(--mj-brand-primary);\n}\n\n.recipient-chip span {\n flex: 1;\n font-weight: 500;\n}\n\n.permission-dropdown {\n width: 150px;\n}\n\n/* Permission option template */\n.permission-option {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n}\n\n.permission-label {\n font-weight: 500;\n}\n\n.permission-desc {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n/* Current shares section */\n.current-shares-section {\n margin-top: 16px;\n}\n\n.share-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.share-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n transition: background-color 0.15s;\n}\n\n.share-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.share-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.share-type-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 50%;\n}\n\n.share-details {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.share-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.share-email {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.share-type-label {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-border-default);\n padding: 2px 6px;\n border-radius: 3px;\n display: inline-block;\n width: fit-content;\n}\n\n.share-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.permission-dropdown-small {\n width: 110px;\n}\n\n.permission-badge {\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\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: 40px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-state p {\n margin: 0;\n color: var(--mj-text-secondary);\n}\n\n.empty-hint {\n font-size: 13px;\n margin-top: 8px !important;\n}\n\n/* Read-only notice */\n.readonly-notice {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-radius: 6px;\n margin-top: 16px;\n color: var(--mj-status-warning);\n font-size: 13px;\n}\n\n.readonly-notice i {\n color: var(--mj-status-warning);\n}\n\n/* Dialog actions - buttons on left */\n:host ::ng-deep kendo-dialog-actions {\n flex-direction: row;\n justify-content: flex-start;\n}\n"] }]
652
652
  }], () => [{ type: i1.ListSharingService }, { type: i0.ChangeDetectorRef }], { config: [{
653
653
  type: Input
654
654
  }], visible: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-list-management",
3
- "version": "5.11.0",
3
+ "version": "5.13.0",
4
4
  "description": "MemberJunction: Angular Components for managing entity list membership with beautiful, responsive UI",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -38,12 +38,12 @@
38
38
  "rxjs": "^7.8.2"
39
39
  },
40
40
  "dependencies": {
41
- "@memberjunction/core": "5.11.0",
42
- "@memberjunction/core-entities": "5.11.0",
43
- "@memberjunction/global": "5.11.0",
44
- "@memberjunction/ng-container-directives": "5.11.0",
45
- "@memberjunction/ng-shared": "5.11.0",
46
- "@memberjunction/ng-shared-generic": "5.11.0",
41
+ "@memberjunction/core": "5.13.0",
42
+ "@memberjunction/core-entities": "5.13.0",
43
+ "@memberjunction/global": "5.13.0",
44
+ "@memberjunction/ng-container-directives": "5.13.0",
45
+ "@memberjunction/ng-shared": "5.13.0",
46
+ "@memberjunction/ng-shared-generic": "5.13.0",
47
47
  "tslib": "^2.8.1"
48
48
  },
49
49
  "sideEffects": false,