@memberjunction/ng-entity-relationship-diagram 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.
@@ -667,11 +667,11 @@ export class EntityDetailsComponent {
667
667
  i0.ɵɵtextInterpolate1("Related Entities (", ctx.selectedEntity ? ctx.getRelatedEntities(ctx.selectedEntity.ID).length : 0, ")");
668
668
  i0.ɵɵadvance();
669
669
  i0.ɵɵconditional(ctx.relationshipsSectionExpanded ? 38 : -1);
670
- } }, styles: ["\n\n\n\n\n\n.details-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.details-panel[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .entity-info[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-height: 0;\n transition: flex 0.3s ease;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section.section-expanded[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section.section-expanded[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section.section-collapsed[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section.section-collapsed[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section[_ngcontent-%COMP%]:last-child, \n.details-panel[_ngcontent-%COMP%] .relationships-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n\n\n.open-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.close-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.info-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.status-deprecated[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-900);\n}\n\n.status-badge.status-disabled[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n}\n\n.extra-padding[_ngcontent-%COMP%] {\n padding: 4px;\n}\n\n\n\n.fields-section[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 16px 16px 12px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] .section-title-group[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] .section-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.fields-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.expand-btn.expanded[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.section-title-group[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n}\n\n.section-title-group[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n\n\n.field-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n\n\n.fields-list[_ngcontent-%COMP%], \n.related-entities-list[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-color-neutral-400);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n\n\n.field-item[_ngcontent-%COMP%] {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n\n\n.field-item.primary-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success);\n background: var(--mj-color-success-100);\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n\n\n.field-item.foreign-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-accent-300);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n\n.field-item.regular-field[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-icon.fa-key[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.field-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.field-info-btn[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn[_ngcontent-%COMP%]:hover, \n.field-values-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded[_ngcontent-%COMP%], \n.field-values-btn.expanded[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.field-description[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-description[_ngcontent-%COMP%] .description-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.field-values[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-color-warning-50);\n border-left: 3px solid var(--mj-color-warning-500);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-values[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-color-warning-900);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values[_ngcontent-%COMP%] .values-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-yes[_ngcontent-%COMP%], \n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-no[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-yes[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-900);\n background: var(--mj-color-warning-50);\n border-color: var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-no[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.default-value[_ngcontent-%COMP%] {\n color: var(--mj-color-success-800);\n background: var(--mj-color-success-100);\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] {\n color: var(--mj-color-brand-900);\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-color-accent-300) 80%, var(--mj-brand-primary) 20%);\n transform: translateX(2px);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] .fa-external-link-alt[_ngcontent-%COMP%] {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover .fa-external-link-alt[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.auto-increment[_ngcontent-%COMP%] {\n color: var(--mj-color-success-800);\n background: var(--mj-color-success-100);\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] .description-content[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: var(--mj-color-accent-300);\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n background: var(--mj-color-warning-50);\n border: 1px solid var(--mj-color-warning-500);\n border-radius: 8px;\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-warning-900);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-color-warning-500) 30%, transparent);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-color-warning-50);\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-color-warning-500);\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-color-warning-900);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-text[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-code[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-color-warning-900);\n background: var(--mj-color-warning-50);\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-color-warning-500);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-description[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n\n\n.related-entity-item[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .fa-database[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-color-warning-500));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-database[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}"] });
670
+ } }, styles: ["\n\n\n\n\n\n.details-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.details-panel[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .entity-info[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-height: 0;\n transition: flex 0.3s ease;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section.section-expanded[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section.section-expanded[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section.section-collapsed[_ngcontent-%COMP%], \n.details-panel[_ngcontent-%COMP%] .relationships-section.section-collapsed[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.details-panel[_ngcontent-%COMP%] .fields-section[_ngcontent-%COMP%]:last-child, \n.details-panel[_ngcontent-%COMP%] .relationships-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n\n\n.open-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.close-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.info-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-success);\n}\n\n.status-badge.status-deprecated[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-warning);\n}\n\n.status-badge.status-disabled[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-error);\n}\n\n.extra-padding[_ngcontent-%COMP%] {\n padding: 4px;\n}\n\n\n\n.fields-section[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 16px 16px 12px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] .section-title-group[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] .section-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.fields-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%], \n.relationships-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.expand-btn.expanded[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.section-title-group[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n}\n\n.section-title-group[_ngcontent-%COMP%]:hover {\n opacity: 0.8;\n}\n\n\n\n.field-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n\n\n.fields-list[_ngcontent-%COMP%], \n.related-entities-list[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-text-disabled);\n border-radius: 3px;\n}\n\n.fields-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.related-entities-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n\n\n.field-item[_ngcontent-%COMP%] {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n\n\n.field-item.primary-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n\n\n.field-item.foreign-key-field[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n\n.field-item.regular-field[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-icon.fa-key[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.field-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.field-info-btn[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn[_ngcontent-%COMP%]:hover, \n.field-values-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded[_ngcontent-%COMP%], \n.field-values-btn.expanded[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%], \n.field-values-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.field-description[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-description[_ngcontent-%COMP%] .description-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.field-values[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-left: 3px solid var(--mj-status-warning);\n border-radius: 0 8px 8px 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.field-values[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-primary);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values[_ngcontent-%COMP%] .values-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values[_ngcontent-%COMP%] .value-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .details-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-yes[_ngcontent-%COMP%], \n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.nullable-no[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-yes[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.virtual-no[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.default-value[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface-card));\n transform: translateX(2px);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%] .fa-external-link-alt[_ngcontent-%COMP%] {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.related-entity[_ngcontent-%COMP%]:hover .fa-external-link-alt[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .detail-value.auto-increment[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .comprehensive-description-top[_ngcontent-%COMP%] .description-content[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border: 1px solid var(--mj-status-warning);\n border-radius: 8px;\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-header[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-status-warning);\n border-radius: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .values-grid[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-text[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-main[_ngcontent-%COMP%] .value-code[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-status-warning);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details[_ngcontent-%COMP%] .field-values-comprehensive[_ngcontent-%COMP%] .value-item[_ngcontent-%COMP%] .value-description[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n\n\n.related-entity-item[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover .fa-database[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item[_ngcontent-%COMP%]:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-status-warning));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .fa-database[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item[_ngcontent-%COMP%] .zoom-indicator[_ngcontent-%COMP%] {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}"] });
671
671
  }
672
672
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityDetailsComponent, [{
673
673
  type: Component,
674
- args: [{ standalone: false, selector: 'mj-entity-details', template: "<div class=\"details-panel\">\n <div class=\"panel-header\">\n <h3>{{ selectedEntity?.Name || selectedEntity?.SchemaName }}</h3>\n <div class=\"panel-actions\">\n <button class=\"open-btn\" (click)=\"onOpenEntity()\" title=\"Open Entity Record\">\n <span class=\"fa-solid fa-external-link-alt\"></span>\n Open\n </button>\n <button class=\"close-btn\" (click)=\"onClosePanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n </div>\n\n <div class=\"entity-info\">\n <div class=\"info-row\">\n <label>Schema:</label>\n <span>{{ selectedEntity?.SchemaName }}</span>\n </div>\n <div class=\"info-row\">\n <label>Table:</label>\n <span>{{ selectedEntity?.BaseTable }}</span>\n </div>\n @if (selectedEntity?.Description) {\n <div class=\"info-row\">\n <label>Description:</label>\n <span>{{ selectedEntity?.Description }}</span>\n </div>\n }\n </div>\n\n <div class=\"fields-section\" [class.section-expanded]=\"fieldsSectionExpanded\" [class.section-collapsed]=\"!fieldsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleFieldsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"fieldsSectionExpanded\"\n title=\"Toggle fields section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Fields ({{ selectedEntity ? getEntityFields(selectedEntity.ID).length : 0 }})</h4>\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"field-filters\">\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'all'\"\n (click)=\"setFieldFilter('all')\"\n title=\"Show all fields\">\n All\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'keys'\"\n (click)=\"setFieldFilter('keys')\"\n title=\"Show primary keys and ID fields\">\n Keys\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'foreign_keys'\"\n (click)=\"setFieldFilter('foreign_keys')\"\n title=\"Show foreign key fields only\">\n FKs\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'regular'\"\n (click)=\"setFieldFilter('regular')\"\n title=\"Show regular data fields\">\n Regular\n </button>\n </div>\n }\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"fields-list\" #fieldsListContainer>\n @for (field of getEntityFields(selectedEntity?.ID || ''); track field.ID) {\n <div class=\"field-item\"\n [class]=\"{\n 'primary-key-field': field.IsPrimaryKey,\n 'foreign-key-field': field.RelatedEntityID && !field.IsPrimaryKey,\n 'regular-field': !field.IsPrimaryKey && !field.RelatedEntityID,\n 'field-expanded': isFieldDetailsExpanded(field.ID)\n }\"\n (click)=\"onFieldClick(field)\"\n [title]=\"'Click to see more details about ' + field.Name\">\n <div class=\"field-header\">\n <div class=\"field-name\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-icon fa-solid fa-key\" title=\"Primary Key\"></span>\n } @else if (field.RelatedEntityID) {\n <span class=\"field-icon fa-solid fa-link\" title=\"Foreign Key\"></span>\n }\n {{ field.Name }}\n </div>\n <div class=\"field-actions\">\n @if (hasFieldPossibleValues(field)) {\n <button\n class=\"field-values-btn\"\n (click)=\"toggleFieldValues(field.ID)\"\n [class.expanded]=\"isFieldValuesExpanded(field.ID)\"\n title=\"Toggle possible values\">\n <span class=\"fa-solid fa-list\"></span>\n </button>\n }\n @if (field.Description) {\n <button\n class=\"field-info-btn\"\n (click)=\"toggleFieldDescription(field.ID)\"\n [class.expanded]=\"isFieldDescriptionExpanded(field.ID)\"\n title=\"Toggle field description\">\n <span class=\"fa-solid fa-info-circle\"></span>\n </button>\n }\n <div class=\"field-badges\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-badge primary-key\">PK</span>\n }\n @if (field.RelatedEntityID && !field.IsPrimaryKey) {\n <span class=\"field-badge foreign-key\">FK</span>\n }\n </div>\n </div>\n </div>\n <div class=\"field-details\">\n <div class=\"field-type\">{{ field.Type }}</div>\n @if (field.RelatedEntityID) {\n <div class=\"field-relation\">\n <span class=\"fa-solid fa-arrow-right\"></span>\n Related Entity\n </div>\n }\n </div>\n @if (field.Description && isFieldDescriptionExpanded(field.ID)) {\n <div class=\"field-description\">\n <div class=\"description-text\">{{ field.Description }}</div>\n </div>\n }\n @if (hasFieldPossibleValues(field) && isFieldValuesExpanded(field.ID)) {\n <div class=\"field-values\">\n <div class=\"values-header\">Possible Values:</div>\n <div class=\"values-list\">\n @for (value of getFieldPossibleValues(field); track value; let i = $index) {\n <span class=\"value-tag\">{{ value }}</span>\n }\n </div>\n </div>\n }\n @if (isFieldDetailsExpanded(field.ID)) {\n <div class=\"field-comprehensive-details\">\n @if (field.Description) {\n <div class=\"comprehensive-description-top\">\n <div class=\"description-content\">{{ field.Description }}</div>\n </div>\n }\n @if (field.EntityFieldValues && field.EntityFieldValues.length > 0) {\n <div class=\"field-values-comprehensive\">\n <div class=\"values-header\">\n <span class=\"fa-solid fa-list\"></span>\n Possible Values ({{ field.EntityFieldValues.length }})\n </div>\n <div class=\"values-grid\">\n @for (fieldValue of getSortedEntityFieldValues(field); track fieldValue.ID) {\n <div class=\"value-item\">\n <div class=\"value-main\">\n <span class=\"value-text\">{{ fieldValue.Value }}</span>\n @if (fieldValue.Code && fieldValue.Code !== fieldValue.Value) {\n <span class=\"value-code\">[{{ fieldValue.Code }}]</span>\n }\n </div>\n @if (fieldValue.Description && fieldValue.Description !== fieldValue.Value) {\n <div class=\"value-description\">{{ fieldValue.Description }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n <div class=\"details-grid\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Data Type:</span>\n <span class=\"detail-value\">{{ field.Type }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Nullable:</span>\n <span class=\"detail-value\" [class]=\"field.AllowsNull ? 'nullable-yes' : 'nullable-no'\">\n {{ field.AllowsNull ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.Length && field.Length > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Max Length:</span>\n <span class=\"detail-value\">{{ field.Length }}</span>\n </div>\n }\n @if (field.Precision && field.Precision > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Precision:</span>\n <span class=\"detail-value\">{{ field.Precision }}</span>\n </div>\n }\n @if (field.Scale && field.Scale > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scale:</span>\n <span class=\"detail-value\">{{ field.Scale }}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Virtual Field:</span>\n <span class=\"detail-value\" [class]=\"field.IsVirtual ? 'virtual-yes' : 'virtual-no'\">\n {{ field.IsVirtual ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.DefaultValue) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Default Value:</span>\n <span class=\"detail-value default-value\">{{ field.DefaultValue }}</span>\n </div>\n }\n @if (field.RelatedEntityID) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Related Entity:</span>\n <span class=\"detail-value related-entity\"\n (click)=\"onRelatedEntityClick($event, field)\"\n title=\"Click to select {{ field.RelatedEntity }} in ERD\">\n {{ field.RelatedEntity }}\n <span class=\"fa-solid fa-arrow-right\"></span>\n </span>\n </div>\n }\n @if (field.AutoIncrement) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Auto Increment:</span>\n <span class=\"detail-value auto-increment\">Yes</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"relationships-section\" [class.section-expanded]=\"relationshipsSectionExpanded\" [class.section-collapsed]=\"!relationshipsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleRelationshipsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"relationshipsSectionExpanded\"\n title=\"Toggle relationships section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Related Entities ({{ selectedEntity ? getRelatedEntities(selectedEntity.ID).length : 0 }})</h4>\n </div>\n </div>\n @if (relationshipsSectionExpanded) {\n <div class=\"related-entities-list\" #relationshipsListContainer>\n @for (relatedEntity of getRelatedEntities(selectedEntity?.ID || ''); track relatedEntity.ID) {\n <div class=\"related-entity-item\" (click)=\"selectEntity(relatedEntity, true)\">\n <span class=\"fa-solid fa-database\"></span>\n <span class=\"entity-name\">{{ relatedEntity.Name || relatedEntity.SchemaName }}</span>\n <span class=\"zoom-indicator fa-solid fa-search-plus\" title=\"Click to zoom to entity\"></span>\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: ["/**\n * Entity Details Component - MJ Design Token Styled\n * MemberJunction design tokens for the entity details panel\n */\n\n.details-panel {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.details-panel .panel-header {\n flex-shrink: 0;\n}\n\n.details-panel .entity-info {\n flex-shrink: 0;\n}\n\n.details-panel .fields-section,\n.details-panel .relationships-section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n transition: flex 0.3s ease;\n}\n\n.details-panel .fields-section.section-expanded,\n.details-panel .relationships-section.section-expanded {\n flex: 1;\n}\n\n.details-panel .fields-section.section-collapsed,\n.details-panel .relationships-section.section-collapsed {\n flex: 0 0 auto;\n}\n\n.details-panel .fields-section:last-child,\n.details-panel .relationships-section:last-child {\n border-bottom: none;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n/* Filled Button for Open */\n.open-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n/* Icon Button for Close */\n.close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n/* Entity Info Section */\n.entity-info {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row:last-child {\n margin-bottom: 0;\n}\n\n.info-row label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row span {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n/* Status Badges */\n.status-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.status-deprecated {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-900);\n}\n\n.status-badge.status-disabled {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n}\n\n.extra-padding {\n padding: 4px;\n}\n\n/* Fields and Relationships Sections */\n.fields-section,\n.relationships-section {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section .section-header,\n.relationships-section .section-header {\n flex-shrink: 0;\n padding: 16px 16px 12px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section .section-header .section-title-group,\n.relationships-section .section-header .section-title-group {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.fields-section h4,\n.relationships-section h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Expand Button */\n.expand-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.expand-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.expand-btn .fa-solid {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.expand-btn.expanded .fa-solid {\n transform: rotate(90deg);\n}\n\n.section-title-group {\n cursor: pointer;\n user-select: none;\n}\n\n.section-title-group:hover {\n opacity: 0.8;\n}\n\n/* Field Filter Buttons */\n.field-filters {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n/* Fields and Related Entities Lists */\n.fields-list,\n.related-entities-list {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list::-webkit-scrollbar,\n.related-entities-list::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list::-webkit-scrollbar-track,\n.related-entities-list::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list::-webkit-scrollbar-thumb,\n.related-entities-list::-webkit-scrollbar-thumb {\n background: var(--mj-color-neutral-400);\n border-radius: 3px;\n}\n\n.fields-list::-webkit-scrollbar-thumb:hover,\n.related-entities-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n/* Field Items - Card Style */\n.field-item {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n/* Primary Key Field - Success Accent */\n.field-item.primary-key-field {\n border-color: var(--mj-status-success);\n background: var(--mj-color-success-100);\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n/* Foreign Key Field - Primary Accent */\n.field-item.foreign-key-field {\n border-color: var(--mj-brand-primary);\n background: var(--mj-color-accent-300);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n/* Regular Field */\n.field-item.regular-field {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon {\n font-size: 10px;\n}\n\n.field-icon.fa-key {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link {\n color: var(--mj-brand-primary);\n}\n\n/* Field Badges */\n.field-badges {\n display: flex;\n gap: 4px;\n}\n\n.field-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation .fa-solid {\n margin-right: 4px;\n}\n\n/* Field Info and Values Buttons */\n.field-info-btn,\n.field-values-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn:hover,\n.field-values-btn:hover {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded,\n.field-values-btn.expanded {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn .fa-solid,\n.field-values-btn .fa-solid {\n font-size: 10px;\n}\n\n/* Field Description */\n.field-description {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.field-description .description-text {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Field Values - Warning Accent */\n.field-values {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-color-warning-50);\n border-left: 3px solid var(--mj-color-warning-500);\n border-radius: 0 8px 8px 0;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.field-values .values-header {\n font-size: 11px;\n color: var(--mj-color-warning-900);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values .values-list {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values .value-tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values .value-tag:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n/* Field Comprehensive Details */\n.field-comprehensive-details {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details .details-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .details-header .fa-solid {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details .details-grid {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details .detail-row {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details .detail-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details .detail-value {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .detail-value.nullable-yes,\n.field-comprehensive-details .detail-value.nullable-no {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details .detail-value.virtual-yes {\n color: var(--mj-color-warning-900);\n background: var(--mj-color-warning-50);\n border-color: var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details .detail-value.virtual-no {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details .detail-value.default-value {\n color: var(--mj-color-success-800);\n background: var(--mj-color-success-100);\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details .detail-value.related-entity {\n color: var(--mj-color-brand-900);\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details .detail-value.related-entity:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-color-accent-300) 80%, var(--mj-brand-primary) 20%);\n transform: translateX(2px);\n}\n\n.field-comprehensive-details .detail-value.related-entity .fa-external-link-alt {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details .detail-value.related-entity:hover .fa-external-link-alt {\n opacity: 1;\n}\n\n.field-comprehensive-details .detail-value.auto-increment {\n color: var(--mj-color-success-800);\n background: var(--mj-color-success-100);\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details .comprehensive-description-top {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .comprehensive-description-top .description-content {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: var(--mj-color-accent-300);\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n/* Field Values in Comprehensive Details */\n.field-comprehensive-details .field-values-comprehensive {\n margin-bottom: 12px;\n padding: 12px;\n background: var(--mj-color-warning-50);\n border: 1px solid var(--mj-color-warning-500);\n border-radius: 8px;\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-color-warning-900);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-color-warning-500) 30%, transparent);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-header .fa-solid {\n color: var(--mj-color-warning-500);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-track {\n background: var(--mj-color-warning-50);\n border-radius: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-thumb {\n background: var(--mj-color-warning-500);\n border-radius: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-thumb:hover {\n background: var(--mj-color-warning-900);\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main .value-text {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main .value-code {\n font-size: 9px;\n color: var(--mj-color-warning-900);\n background: var(--mj-color-warning-50);\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-color-warning-500);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-description {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n/* Related Entity Items - List Item Style */\n.related-entity-item {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item:hover {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item:hover .zoom-indicator {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item:hover .fa-database {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-color-warning-500));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item .fa-solid {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item .fa-database {\n font-size: 14px;\n}\n\n.related-entity-item .entity-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item .zoom-indicator {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n"] }]
674
+ args: [{ standalone: false, selector: 'mj-entity-details', template: "<div class=\"details-panel\">\n <div class=\"panel-header\">\n <h3>{{ selectedEntity?.Name || selectedEntity?.SchemaName }}</h3>\n <div class=\"panel-actions\">\n <button class=\"open-btn\" (click)=\"onOpenEntity()\" title=\"Open Entity Record\">\n <span class=\"fa-solid fa-external-link-alt\"></span>\n Open\n </button>\n <button class=\"close-btn\" (click)=\"onClosePanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n </div>\n\n <div class=\"entity-info\">\n <div class=\"info-row\">\n <label>Schema:</label>\n <span>{{ selectedEntity?.SchemaName }}</span>\n </div>\n <div class=\"info-row\">\n <label>Table:</label>\n <span>{{ selectedEntity?.BaseTable }}</span>\n </div>\n @if (selectedEntity?.Description) {\n <div class=\"info-row\">\n <label>Description:</label>\n <span>{{ selectedEntity?.Description }}</span>\n </div>\n }\n </div>\n\n <div class=\"fields-section\" [class.section-expanded]=\"fieldsSectionExpanded\" [class.section-collapsed]=\"!fieldsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleFieldsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"fieldsSectionExpanded\"\n title=\"Toggle fields section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Fields ({{ selectedEntity ? getEntityFields(selectedEntity.ID).length : 0 }})</h4>\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"field-filters\">\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'all'\"\n (click)=\"setFieldFilter('all')\"\n title=\"Show all fields\">\n All\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'keys'\"\n (click)=\"setFieldFilter('keys')\"\n title=\"Show primary keys and ID fields\">\n Keys\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'foreign_keys'\"\n (click)=\"setFieldFilter('foreign_keys')\"\n title=\"Show foreign key fields only\">\n FKs\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'regular'\"\n (click)=\"setFieldFilter('regular')\"\n title=\"Show regular data fields\">\n Regular\n </button>\n </div>\n }\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"fields-list\" #fieldsListContainer>\n @for (field of getEntityFields(selectedEntity?.ID || ''); track field.ID) {\n <div class=\"field-item\"\n [class]=\"{\n 'primary-key-field': field.IsPrimaryKey,\n 'foreign-key-field': field.RelatedEntityID && !field.IsPrimaryKey,\n 'regular-field': !field.IsPrimaryKey && !field.RelatedEntityID,\n 'field-expanded': isFieldDetailsExpanded(field.ID)\n }\"\n (click)=\"onFieldClick(field)\"\n [title]=\"'Click to see more details about ' + field.Name\">\n <div class=\"field-header\">\n <div class=\"field-name\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-icon fa-solid fa-key\" title=\"Primary Key\"></span>\n } @else if (field.RelatedEntityID) {\n <span class=\"field-icon fa-solid fa-link\" title=\"Foreign Key\"></span>\n }\n {{ field.Name }}\n </div>\n <div class=\"field-actions\">\n @if (hasFieldPossibleValues(field)) {\n <button\n class=\"field-values-btn\"\n (click)=\"toggleFieldValues(field.ID)\"\n [class.expanded]=\"isFieldValuesExpanded(field.ID)\"\n title=\"Toggle possible values\">\n <span class=\"fa-solid fa-list\"></span>\n </button>\n }\n @if (field.Description) {\n <button\n class=\"field-info-btn\"\n (click)=\"toggleFieldDescription(field.ID)\"\n [class.expanded]=\"isFieldDescriptionExpanded(field.ID)\"\n title=\"Toggle field description\">\n <span class=\"fa-solid fa-info-circle\"></span>\n </button>\n }\n <div class=\"field-badges\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-badge primary-key\">PK</span>\n }\n @if (field.RelatedEntityID && !field.IsPrimaryKey) {\n <span class=\"field-badge foreign-key\">FK</span>\n }\n </div>\n </div>\n </div>\n <div class=\"field-details\">\n <div class=\"field-type\">{{ field.Type }}</div>\n @if (field.RelatedEntityID) {\n <div class=\"field-relation\">\n <span class=\"fa-solid fa-arrow-right\"></span>\n Related Entity\n </div>\n }\n </div>\n @if (field.Description && isFieldDescriptionExpanded(field.ID)) {\n <div class=\"field-description\">\n <div class=\"description-text\">{{ field.Description }}</div>\n </div>\n }\n @if (hasFieldPossibleValues(field) && isFieldValuesExpanded(field.ID)) {\n <div class=\"field-values\">\n <div class=\"values-header\">Possible Values:</div>\n <div class=\"values-list\">\n @for (value of getFieldPossibleValues(field); track value; let i = $index) {\n <span class=\"value-tag\">{{ value }}</span>\n }\n </div>\n </div>\n }\n @if (isFieldDetailsExpanded(field.ID)) {\n <div class=\"field-comprehensive-details\">\n @if (field.Description) {\n <div class=\"comprehensive-description-top\">\n <div class=\"description-content\">{{ field.Description }}</div>\n </div>\n }\n @if (field.EntityFieldValues && field.EntityFieldValues.length > 0) {\n <div class=\"field-values-comprehensive\">\n <div class=\"values-header\">\n <span class=\"fa-solid fa-list\"></span>\n Possible Values ({{ field.EntityFieldValues.length }})\n </div>\n <div class=\"values-grid\">\n @for (fieldValue of getSortedEntityFieldValues(field); track fieldValue.ID) {\n <div class=\"value-item\">\n <div class=\"value-main\">\n <span class=\"value-text\">{{ fieldValue.Value }}</span>\n @if (fieldValue.Code && fieldValue.Code !== fieldValue.Value) {\n <span class=\"value-code\">[{{ fieldValue.Code }}]</span>\n }\n </div>\n @if (fieldValue.Description && fieldValue.Description !== fieldValue.Value) {\n <div class=\"value-description\">{{ fieldValue.Description }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n <div class=\"details-grid\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Data Type:</span>\n <span class=\"detail-value\">{{ field.Type }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Nullable:</span>\n <span class=\"detail-value\" [class]=\"field.AllowsNull ? 'nullable-yes' : 'nullable-no'\">\n {{ field.AllowsNull ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.Length && field.Length > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Max Length:</span>\n <span class=\"detail-value\">{{ field.Length }}</span>\n </div>\n }\n @if (field.Precision && field.Precision > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Precision:</span>\n <span class=\"detail-value\">{{ field.Precision }}</span>\n </div>\n }\n @if (field.Scale && field.Scale > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scale:</span>\n <span class=\"detail-value\">{{ field.Scale }}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Virtual Field:</span>\n <span class=\"detail-value\" [class]=\"field.IsVirtual ? 'virtual-yes' : 'virtual-no'\">\n {{ field.IsVirtual ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.DefaultValue) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Default Value:</span>\n <span class=\"detail-value default-value\">{{ field.DefaultValue }}</span>\n </div>\n }\n @if (field.RelatedEntityID) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Related Entity:</span>\n <span class=\"detail-value related-entity\"\n (click)=\"onRelatedEntityClick($event, field)\"\n title=\"Click to select {{ field.RelatedEntity }} in ERD\">\n {{ field.RelatedEntity }}\n <span class=\"fa-solid fa-arrow-right\"></span>\n </span>\n </div>\n }\n @if (field.AutoIncrement) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Auto Increment:</span>\n <span class=\"detail-value auto-increment\">Yes</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"relationships-section\" [class.section-expanded]=\"relationshipsSectionExpanded\" [class.section-collapsed]=\"!relationshipsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleRelationshipsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"relationshipsSectionExpanded\"\n title=\"Toggle relationships section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Related Entities ({{ selectedEntity ? getRelatedEntities(selectedEntity.ID).length : 0 }})</h4>\n </div>\n </div>\n @if (relationshipsSectionExpanded) {\n <div class=\"related-entities-list\" #relationshipsListContainer>\n @for (relatedEntity of getRelatedEntities(selectedEntity?.ID || ''); track relatedEntity.ID) {\n <div class=\"related-entity-item\" (click)=\"selectEntity(relatedEntity, true)\">\n <span class=\"fa-solid fa-database\"></span>\n <span class=\"entity-name\">{{ relatedEntity.Name || relatedEntity.SchemaName }}</span>\n <span class=\"zoom-indicator fa-solid fa-search-plus\" title=\"Click to zoom to entity\"></span>\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: ["/**\n * Entity Details Component - MJ Design Token Styled\n * MemberJunction design tokens for the entity details panel\n */\n\n.details-panel {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.details-panel .panel-header {\n flex-shrink: 0;\n}\n\n.details-panel .entity-info {\n flex-shrink: 0;\n}\n\n.details-panel .fields-section,\n.details-panel .relationships-section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n transition: flex 0.3s ease;\n}\n\n.details-panel .fields-section.section-expanded,\n.details-panel .relationships-section.section-expanded {\n flex: 1;\n}\n\n.details-panel .fields-section.section-collapsed,\n.details-panel .relationships-section.section-collapsed {\n flex: 0 0 auto;\n}\n\n.details-panel .fields-section:last-child,\n.details-panel .relationships-section:last-child {\n border-bottom: none;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n/* Filled Button for Open */\n.open-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border: none;\n border-radius: 20px;\n font-size: 11px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.open-btn:hover {\n box-shadow: var(--mj-shadow-md);\n}\n\n/* Icon Button for Close */\n.close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n/* Entity Info Section */\n.entity-info {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n}\n\n.info-row:last-child {\n margin-bottom: 0;\n}\n\n.info-row label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n min-width: 60px;\n}\n\n.info-row span {\n color: var(--mj-text-primary);\n flex: 1;\n text-align: right;\n}\n\n/* Status Badges */\n.status-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-success);\n}\n\n.status-badge.status-deprecated {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-warning);\n}\n\n.status-badge.status-disabled {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface-card));\n color: var(--mj-status-error);\n}\n\n.extra-padding {\n padding: 4px;\n}\n\n/* Fields and Relationships Sections */\n.fields-section,\n.relationships-section {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section .section-header,\n.relationships-section .section-header {\n flex-shrink: 0;\n padding: 16px 16px 12px 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.fields-section .section-header .section-title-group,\n.relationships-section .section-header .section-title-group {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.fields-section h4,\n.relationships-section h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Expand Button */\n.expand-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.expand-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.expand-btn .fa-solid {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.expand-btn.expanded .fa-solid {\n transform: rotate(90deg);\n}\n\n.section-title-group {\n cursor: pointer;\n user-select: none;\n}\n\n.section-title-group:hover {\n opacity: 0.8;\n}\n\n/* Field Filter Buttons */\n.field-filters {\n display: flex;\n gap: 4px;\n}\n\n.filter-btn {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n font-size: 11px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.filter-btn:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n/* Fields and Related Entities Lists */\n.fields-list,\n.related-entities-list {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow-y: auto;\n padding: 6px 16px 16px 16px;\n min-height: 0;\n}\n\n.fields-list::-webkit-scrollbar,\n.related-entities-list::-webkit-scrollbar {\n width: 6px;\n}\n\n.fields-list::-webkit-scrollbar-track,\n.related-entities-list::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.fields-list::-webkit-scrollbar-thumb,\n.related-entities-list::-webkit-scrollbar-thumb {\n background: var(--mj-text-disabled);\n border-radius: 3px;\n}\n\n.fields-list::-webkit-scrollbar-thumb:hover,\n.related-entities-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary);\n}\n\n/* Field Items - Card Style */\n.field-item {\n padding: 10px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.field-item:hover {\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-item.field-expanded {\n box-shadow: var(--mj-shadow-lg);\n transform: scale(1.01);\n}\n\n/* Primary Key Field - Success Accent */\n.field-item.primary-key-field {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-status-success);\n}\n\n.field-item.primary-key-field.field-expanded {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n}\n\n/* Foreign Key Field - Primary Accent */\n.field-item.foreign-key-field {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface-card));\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.field-item.foreign-key-field.field-expanded {\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n/* Regular Field */\n.field-item.regular-field {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-item.regular-field.field-expanded {\n box-shadow: var(--mj-shadow-md);\n}\n\n.field-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 4px;\n}\n\n.field-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-icon {\n font-size: 10px;\n}\n\n.field-icon.fa-key {\n color: var(--mj-status-success);\n}\n\n.field-icon.fa-link {\n color: var(--mj-brand-primary);\n}\n\n/* Field Badges */\n.field-badges {\n display: flex;\n gap: 4px;\n}\n\n.field-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.field-badge.primary-key {\n background: var(--mj-status-success);\n color: var(--mj-brand-on-primary);\n}\n\n.field-badge.foreign-key {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.field-type {\n color: var(--mj-text-secondary);\n font-size: 11px;\n}\n\n.field-relation {\n color: var(--mj-brand-primary);\n font-size: 11px;\n margin-top: 4px;\n}\n\n.field-relation .fa-solid {\n margin-right: 4px;\n}\n\n/* Field Info and Values Buttons */\n.field-info-btn,\n.field-values-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.field-info-btn:hover,\n.field-values-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn.expanded,\n.field-values-btn.expanded {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n color: var(--mj-brand-primary);\n}\n\n.field-info-btn .fa-solid,\n.field-values-btn .fa-solid {\n font-size: 10px;\n}\n\n/* Field Description */\n.field-description {\n margin-top: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 0 8px 8px 0;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.field-description .description-text {\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n font-style: italic;\n}\n\n.field-details {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Field Values - Warning Accent */\n.field-values {\n margin-top: 8px;\n padding: 8px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-left: 3px solid var(--mj-status-warning);\n border-radius: 0 8px 8px 0;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.field-values .values-header {\n font-size: 11px;\n color: var(--mj-text-primary);\n font-weight: 600;\n margin-bottom: 6px;\n}\n\n.field-values .values-list {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.field-values .value-tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-size: 9px;\n border-radius: 12px;\n font-weight: 500;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-values .value-tag:hover {\n background: var(--mj-bg-surface-active);\n cursor: default;\n}\n\n/* Field Comprehensive Details */\n.field-comprehensive-details {\n margin-top: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n animation: slideDown 0.3s ease-out;\n}\n\n.field-comprehensive-details .details-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .details-header .fa-solid {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details .details-grid {\n display: grid;\n gap: 6px;\n}\n\n.field-comprehensive-details .detail-row {\n display: grid;\n grid-template-columns: 100px 1fr;\n gap: 8px;\n font-size: 12px;\n align-items: center;\n}\n\n.field-comprehensive-details .detail-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-align: right;\n}\n\n.field-comprehensive-details .detail-value {\n color: var(--mj-text-primary);\n font-family: \"Courier New\", monospace;\n background: var(--mj-bg-page);\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .detail-value.nullable-yes,\n.field-comprehensive-details .detail-value.nullable-no {\n color: var(--mj-text-primary);\n background: var(--mj-bg-page);\n border-color: var(--mj-border-default);\n}\n\n.field-comprehensive-details .detail-value.virtual-yes {\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details .detail-value.virtual-no {\n color: var(--mj-text-secondary);\n}\n\n.field-comprehensive-details .detail-value.default-value {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details .detail-value.related-entity {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.field-comprehensive-details .detail-value.related-entity:hover {\n text-decoration: underline;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface-card));\n transform: translateX(2px);\n}\n\n.field-comprehensive-details .detail-value.related-entity .fa-external-link-alt {\n font-size: 8px;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n}\n\n.field-comprehensive-details .detail-value.related-entity:hover .fa-external-link-alt {\n opacity: 1;\n}\n\n.field-comprehensive-details .detail-value.auto-increment {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-status-success);\n}\n\n.field-comprehensive-details .comprehensive-description-top {\n margin-bottom: 12px;\n padding-bottom: 10px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.field-comprehensive-details .comprehensive-description-top .description-content {\n font-size: 12px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n font-style: italic;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n/* Field Values in Comprehensive Details */\n.field-comprehensive-details .field-values-comprehensive {\n margin-bottom: 12px;\n padding: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border: 1px solid var(--mj-status-warning);\n border-radius: 8px;\n border-left: 4px solid var(--mj-status-warning);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-header .fa-solid {\n color: var(--mj-status-warning);\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar {\n width: 4px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-track {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n border-radius: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-thumb {\n background: var(--mj-status-warning);\n border-radius: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .values-grid::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-primary);\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item {\n padding: 8px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main .value-text {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-main .value-code {\n font-size: 9px;\n color: var(--mj-text-primary);\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface-card));\n padding: 1px 4px;\n border-radius: 4px;\n border: 1px solid var(--mj-status-warning);\n font-family: \"Courier New\", monospace;\n}\n\n.field-comprehensive-details .field-values-comprehensive .value-item .value-description {\n font-size: 9px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n font-style: italic;\n margin-top: 2px;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n max-height: 0;\n }\n to {\n opacity: 1;\n transform: translateY(0);\n max-height: 500px;\n }\n}\n\n/* Related Entity Items - List Item Style */\n.related-entity-item {\n padding: 12px 14px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n transition: all 0.3s ease;\n position: relative;\n max-width: calc(100% - 4px);\n min-width: 0;\n flex-shrink: 1;\n}\n\n.related-entity-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n border-color: var(--mj-brand-primary);\n transform: translateX(4px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.related-entity-item:hover .zoom-indicator {\n opacity: 1;\n transform: scale(1.1);\n}\n\n.related-entity-item:hover .fa-database {\n color: var(--mj-brand-primary);\n transform: scale(1.1);\n}\n\n.related-entity-item:hover::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(to bottom, var(--mj-brand-primary), var(--mj-status-warning));\n border-radius: 0 3px 3px 0;\n}\n\n.related-entity-item .fa-solid {\n margin-right: 10px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.related-entity-item .fa-database {\n font-size: 14px;\n}\n\n.related-entity-item .entity-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.related-entity-item .zoom-indicator {\n opacity: 0.4;\n color: var(--mj-brand-primary);\n font-size: 11px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n"] }]
675
675
  }], null, { fieldsListContainer: [{
676
676
  type: ViewChild,
677
677
  args: ['fieldsListContainer', { static: false }]
@@ -459,6 +459,8 @@ export declare class ERDDiagramComponent implements AfterViewInit, OnDestroy, On
459
459
  private usesDagreLayout;
460
460
  private createVisualization;
461
461
  private renderNodeFields;
462
+ /** Truncate an SVG text element to fit within maxWidth, adding "…" if needed */
463
+ private truncateTextElement;
462
464
  private attachNodeEventHandlers;
463
465
  private attachLinkEventHandlers;
464
466
  private updatePositions;
@@ -1 +1 @@
1
- {"version":3,"file":"erd-diagram.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"erd-diagram.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts"],"names":[],"mappings":"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"}
@@ -1236,7 +1236,7 @@ export class ERDDiagramComponent {
1236
1236
  .data(this.visibleLinks)
1237
1237
  .enter()
1238
1238
  .append('g')
1239
- .attr('class', 'link-group');
1239
+ .attr('class', (d) => d.isSelfReference ? 'link-group self-reference' : 'link-group');
1240
1240
  link
1241
1241
  .append('path')
1242
1242
  .attr('class', 'link')
@@ -1247,12 +1247,10 @@ export class ERDDiagramComponent {
1247
1247
  .attr('marker-end', (d) => (d.isSelfReference ? 'none' : 'url(#end-arrow)'));
1248
1248
  if (cfg.showRelationshipLabels) {
1249
1249
  // Add background rect for label (will be sized after text is rendered)
1250
- // Self-referencing links get a green background to stand out
1250
+ // Self-referencing links get distinct styling via .self-reference CSS class
1251
1251
  link
1252
1252
  .append('rect')
1253
1253
  .attr('class', 'link-label-bg')
1254
- .attr('fill', (d) => d.isSelfReference ? '#e8f5e9' : 'white')
1255
- .attr('stroke', (d) => d.isSelfReference ? '#4CAF50' : colors.linkColor)
1256
1254
  .attr('stroke-width', 0.5)
1257
1255
  .attr('stroke-opacity', (d) => d.isSelfReference ? 0.6 : 0.4)
1258
1256
  .attr('rx', 2)
@@ -1262,7 +1260,6 @@ export class ERDDiagramComponent {
1262
1260
  .append('text')
1263
1261
  .attr('class', 'link-label')
1264
1262
  .attr('font-size', '10px')
1265
- .attr('fill', (d) => d.isSelfReference ? '#2e7d32' : colors.linkColor)
1266
1263
  .attr('text-anchor', 'middle')
1267
1264
  .attr('dominant-baseline', 'middle')
1268
1265
  .text((d) => d.sourceField.name || '');
@@ -1314,7 +1311,7 @@ export class ERDDiagramComponent {
1314
1311
  .attr('y', (d) => -d.height / 2 + 15)
1315
1312
  .attr('fill', colors.nodeHeader);
1316
1313
  // Node name
1317
- nodeGroup
1314
+ const entityNameText = nodeGroup
1318
1315
  .append('text')
1319
1316
  .attr('class', 'entity-name')
1320
1317
  .attr('text-anchor', 'middle')
@@ -1323,6 +1320,10 @@ export class ERDDiagramComponent {
1323
1320
  .attr('font-weight', 'bold')
1324
1321
  .attr('fill', colors.nodeHeaderText)
1325
1322
  .text((d) => d.name);
1323
+ // Truncate entity names that overflow the header
1324
+ entityNameText.each((_d, i, nodes) => {
1325
+ this.truncateTextElement(nodes[i], cfg.nodeWidth - 16);
1326
+ });
1326
1327
  // Add fields if configured
1327
1328
  if (cfg.showFieldDetails) {
1328
1329
  this.renderNodeFields(nodeGroup, colors);
@@ -1408,7 +1409,7 @@ export class ERDDiagramComponent {
1408
1409
  .attr('font-size', '10px')
1409
1410
  .attr('fill', colors.primaryKeyText)
1410
1411
  .text('🔑');
1411
- fieldGroup
1412
+ const pkNameEl = fieldGroup
1412
1413
  .append('text')
1413
1414
  .attr('class', 'field-name')
1414
1415
  .attr('x', -d.width / 2 + 25)
@@ -1416,7 +1417,10 @@ export class ERDDiagramComponent {
1416
1417
  .attr('font-size', '11px')
1417
1418
  .attr('font-weight', 'bold')
1418
1419
  .attr('fill', colors.primaryKeyText)
1419
- .text(pk.name || '');
1420
+ .text(pk.name || '')
1421
+ .node();
1422
+ if (pkNameEl)
1423
+ this.truncateTextElement(pkNameEl, d.width - 33);
1420
1424
  currentY += 20;
1421
1425
  });
1422
1426
  // Foreign keys
@@ -1438,18 +1442,41 @@ export class ERDDiagramComponent {
1438
1442
  .attr('font-size', '10px')
1439
1443
  .attr('fill', colors.foreignKeyText)
1440
1444
  .text('🔗');
1441
- fieldGroup
1445
+ const fkNameEl = fieldGroup
1442
1446
  .append('text')
1443
1447
  .attr('class', 'field-name')
1444
1448
  .attr('x', -d.width / 2 + 25)
1445
1449
  .attr('y', currentY - 2)
1446
1450
  .attr('font-size', '11px')
1447
1451
  .attr('fill', colors.foreignKeyText)
1448
- .text(fk.name || '');
1452
+ .text(fk.name || '')
1453
+ .node();
1454
+ if (fkNameEl)
1455
+ this.truncateTextElement(fkNameEl, d.width - 33);
1449
1456
  currentY += 20;
1450
1457
  });
1451
1458
  });
1452
1459
  }
1460
+ /** Truncate an SVG text element to fit within maxWidth, adding "…" if needed */
1461
+ truncateTextElement(textEl, maxWidth) {
1462
+ const original = textEl.textContent || '';
1463
+ if (!original || textEl.getComputedTextLength() <= maxWidth)
1464
+ return;
1465
+ // Binary search for the longest fitting substring
1466
+ let lo = 0;
1467
+ let hi = original.length;
1468
+ while (lo < hi) {
1469
+ const mid = Math.ceil((lo + hi) / 2);
1470
+ textEl.textContent = original.slice(0, mid) + '…';
1471
+ if (textEl.getComputedTextLength() <= maxWidth) {
1472
+ lo = mid;
1473
+ }
1474
+ else {
1475
+ hi = mid - 1;
1476
+ }
1477
+ }
1478
+ textEl.textContent = lo < original.length ? original.slice(0, lo) + '…' : original;
1479
+ }
1453
1480
  attachNodeEventHandlers(nodeGroup) {
1454
1481
  nodeGroup
1455
1482
  .on('click', (event, d) => {
@@ -1767,8 +1794,8 @@ export class ERDDiagramComponent {
1767
1794
  .classed('highlighted', false)
1768
1795
  .classed('relationship-highlighted', false)
1769
1796
  .classed('connection-highlighted', false)
1770
- .style('stroke', this.mergedConfig.colors?.nodeBorder || '#333')
1771
- .style('stroke-width', '2px')
1797
+ .style('stroke', null)
1798
+ .style('stroke-width', null)
1772
1799
  .style('filter', null);
1773
1800
  this.svg.selectAll('.link-group')
1774
1801
  .classed('highlighted', false);
@@ -1780,36 +1807,28 @@ export class ERDDiagramComponent {
1780
1807
  updateSelectionHighlighting() {
1781
1808
  if (!this.svg)
1782
1809
  return;
1783
- // Clear previous selection styling
1810
+ // Clear previous selection styling — remove inline styles so CSS classes take over
1784
1811
  this.svg.selectAll('.node')
1785
1812
  .classed('selected', false)
1786
1813
  .select('.entity-rect')
1787
- .style('stroke', this.mergedConfig.colors?.nodeBorder || '#333')
1788
- .style('stroke-width', '2px')
1814
+ .style('stroke', null)
1815
+ .style('stroke-width', null)
1789
1816
  .style('filter', null);
1790
1817
  if (this.selectedNodeId) {
1791
- const selectedColor = this.mergedConfig.colors?.selectedBorder || '#4CAF50';
1792
1818
  this.svg.selectAll('.node')
1793
1819
  .filter((d) => d.id === this.selectedNodeId)
1794
- .classed('selected', true)
1795
- .select('.entity-rect')
1796
- .style('stroke', selectedColor)
1797
- .style('stroke-width', '4px')
1798
- .style('filter', `drop-shadow(0 0 8px ${selectedColor}80)`);
1820
+ .classed('selected', true);
1799
1821
  }
1800
1822
  }
1801
1823
  updateHighlighting() {
1802
1824
  if (!this.svg)
1803
1825
  return;
1804
- const highlightColor = this.mergedConfig.colors?.highlightBorder || '#ff9800';
1805
1826
  const highlightSet = new Set(this.highlightedNodeIds);
1806
1827
  this.svg.selectAll('.node')
1807
1828
  .classed('highlighted', (d) => highlightSet.has(d.id))
1808
1829
  .filter((d) => highlightSet.has(d.id))
1809
1830
  .select('.entity-rect')
1810
- .style('stroke', highlightColor)
1811
- .style('stroke-width', '3px')
1812
- .style('filter', `drop-shadow(0 0 6px ${highlightColor}80)`);
1831
+ .classed('highlighted', true);
1813
1832
  }
1814
1833
  emitStateChange() {
1815
1834
  const state = this.getState();
@@ -1875,11 +1894,11 @@ export class ERDDiagramComponent {
1875
1894
  i0.ɵɵconditional(ctx.showHeader ? 1 : -1);
1876
1895
  i0.ɵɵadvance(3);
1877
1896
  i0.ɵɵconditional(ctx.isRefreshing ? 4 : -1);
1878
- } }, styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.erd-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-400);\n color: var(--mj-text-primary);\n}\n\n.control-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.erd-container[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n width: 100%;\n min-height: 400px;\n box-sizing: border-box;\n}\n\n.erd-container[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 100% !important;\n height: 100% !important;\n box-sizing: border-box;\n}\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-page);\n opacity: 0.95;\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n}\n\n.spinner-ring[_ngcontent-%COMP%] {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s linear infinite;\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-top-color: var(--mj-brand-primary);\n animation-delay: 0s;\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-top-color: var(--mj-color-warning-500);\n animation-delay: 0.3s;\n transform: scale(0.8);\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-top-color: var(--mj-status-success);\n animation-delay: 0.6s;\n transform: scale(0.6);\n}\n\n.loading-text[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-weight: 500;\n text-align: center;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .node .entity-rect.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-rect {\n stroke: #4CAF50 !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px rgba(76, 175, 80, 0.5));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-header {\n fill: #388E3C !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-header-bottom {\n fill: #388E3C !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-name {\n fill: white !important;\n font-weight: bold !important;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-rect.relationship-highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-header {\n fill: var(--mj-status-success) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-header-bottom {\n fill: var(--mj-status-success) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-rect.connection-highlighted {\n stroke: var(--mj-color-warning-500) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-color-warning-500) 50%, transparent));\n opacity: 0.9;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-header {\n fill: var(--mj-color-warning-500) !important;\n opacity: 0.8;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-header-bottom {\n fill: var(--mj-color-warning-500) !important;\n opacity: 0.8;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .link-group .link {\n stroke-width: 2px;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link:hover {\n stroke-width: 3px;\n stroke: var(--mj-status-success);\n opacity: 1;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n opacity: 1 !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label {\n font-family: Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n opacity: 0.8;\n pointer-events: none;\n transition: opacity 0.2s ease;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label.highlighted {\n opacity: 1;\n font-weight: bold;\n fill: var(--mj-status-success);\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group.highlighted {\n z-index: 10;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .field-group .field-bg {\n transition: fill 0.2s;\n}\n\n[_nghost-%COMP%] .erd-container svg .field-group:hover .field-bg {\n fill: var(--mj-color-accent-300) !important;\n}"] });
1897
+ } }, styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.erd-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.control-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.erd-container[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n width: 100%;\n min-height: 400px;\n box-sizing: border-box;\n}\n\n.erd-container[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 100% !important;\n height: 100% !important;\n box-sizing: border-box;\n}\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-page);\n opacity: 0.95;\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in-out;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n}\n\n.spinner-ring[_ngcontent-%COMP%] {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s linear infinite;\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-top-color: var(--mj-brand-primary);\n animation-delay: 0s;\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-top-color: var(--mj-status-warning);\n animation-delay: 0.3s;\n transform: scale(0.8);\n}\n\n.spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-top-color: var(--mj-status-success);\n animation-delay: 0.6s;\n transform: scale(0.6);\n}\n\n.loading-text[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-weight: 500;\n text-align: center;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .node .entity-rect {\n fill: var(--mj-bg-surface-card);\n stroke: var(--mj-text-primary);\n}\n\n[_nghost-%COMP%] .erd-container svg .node .entity-header, \n[_nghost-%COMP%] .erd-container svg .node .entity-header-bottom {\n fill: var(--mj-brand-primary);\n}\n\n[_nghost-%COMP%] .erd-container svg .node .entity-name {\n fill: var(--mj-text-inverse);\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .field-group.primary-key .field-bg {\n fill: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface-card));\n}\n\n[_nghost-%COMP%] .erd-container svg .field-group.primary-key .field-name, \n[_nghost-%COMP%] .erd-container svg .field-group.primary-key .field-icon {\n fill: var(--mj-text-primary);\n}\n\n[_nghost-%COMP%] .erd-container svg .field-group.foreign-key .field-bg {\n fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n}\n\n[_nghost-%COMP%] .erd-container svg .field-group.foreign-key .field-name, \n[_nghost-%COMP%] .erd-container svg .field-group.foreign-key .field-icon {\n fill: var(--mj-text-primary);\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label-bg {\n fill: var(--mj-bg-surface-card);\n stroke: var(--mj-text-muted);\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label {\n fill: var(--mj-text-muted);\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link {\n stroke: var(--mj-text-muted);\n}\n\n[_nghost-%COMP%] .erd-container svg #end-arrow path {\n fill: var(--mj-text-muted);\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .node .entity-rect.highlighted {\n stroke: var(--mj-status-warning) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-rect {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-header {\n fill: color-mix(in srgb, var(--mj-status-success) 85%, black) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-header-bottom {\n fill: color-mix(in srgb, var(--mj-status-success) 85%, black) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.selected .entity-name {\n fill: var(--mj-text-inverse) !important;\n font-weight: bold !important;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-rect.relationship-highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-header {\n fill: var(--mj-status-success) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.relationship-connected .entity-header-bottom {\n fill: var(--mj-status-success) !important;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-rect.connection-highlighted {\n stroke: var(--mj-status-warning) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent));\n opacity: 0.9;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-header {\n fill: var(--mj-status-warning) !important;\n opacity: 0.8;\n}\n\n[_nghost-%COMP%] .erd-container svg .node.entity-connections-highlighted .entity-header-bottom {\n fill: var(--mj-status-warning) !important;\n opacity: 0.8;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .link-group.self-reference .link-label-bg {\n fill: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n stroke: var(--mj-status-success);\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group.self-reference .link-label {\n fill: color-mix(in srgb, var(--mj-status-success) 80%, var(--mj-text-primary));\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .link-group .link {\n stroke-width: 2px;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link:hover {\n stroke-width: 3px;\n stroke: var(--mj-status-success);\n opacity: 1;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n opacity: 1 !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label {\n font-family: Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n opacity: 0.8;\n pointer-events: none;\n transition: opacity 0.2s ease;\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group .link-label.highlighted {\n opacity: 1;\n font-weight: bold;\n fill: var(--mj-status-success);\n}\n\n[_nghost-%COMP%] .erd-container svg .link-group.highlighted {\n z-index: 10;\n}\n\n\n\n[_nghost-%COMP%] .erd-container svg .field-group .field-bg {\n transition: fill 0.2s;\n}\n\n[_nghost-%COMP%] .erd-container svg .field-group:hover .field-bg {\n fill: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface-card)) !important;\n}"] });
1879
1898
  }
1880
1899
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ERDDiagramComponent, [{
1881
1900
  type: Component,
1882
- args: [{ standalone: false, selector: 'mj-erd-diagram', template: "<div class=\"erd-section\">\n @if (showHeader) {\n <div class=\"section-header\">\n <h3>{{ headerTitle }}</h3>\n <div class=\"erd-controls\">\n <button class=\"control-btn\" (click)=\"zoomIn()\" title=\"Zoom In\">\n <span class=\"fa-solid fa-search-plus\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"zoomOut()\" title=\"Zoom Out\">\n <span class=\"fa-solid fa-search-minus\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"resetZoom()\" title=\"Reset Zoom\">\n <span class=\"fa-solid fa-expand\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"refresh(); refreshRequested.emit()\" title=\"Refresh Diagram\">\n <span class=\"fa-solid fa-refresh\"></span>\n </button>\n </div>\n </div>\n }\n <div class=\"erd-container\" #erdContainer>\n @if (isRefreshing) {\n <div class=\"loading-overlay\">\n <div class=\"loading-content\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading diagram...</div>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["/**\n * ERD Diagram Component - MJ Design Tokens\n * MJ theming for the Entity Relationship Diagram visualization\n */\n\n:host {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-section {\n background: var(--mj-bg-page);\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.section-header h3 {\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.erd-controls {\n display: flex;\n gap: 8px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.control-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-400);\n color: var(--mj-text-primary);\n}\n\n.control-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.erd-container {\n flex: 1;\n position: relative;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n width: 100%;\n min-height: 400px;\n box-sizing: border-box;\n}\n\n.erd-container svg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100% !important;\n height: 100% !important;\n box-sizing: border-box;\n}\n\n/* Loading overlay - using mj-loading component styling */\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-page);\n opacity: 0.95;\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n}\n\n.spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s linear infinite;\n}\n\n.spinner-ring:nth-child(1) {\n border-top-color: var(--mj-brand-primary);\n animation-delay: 0s;\n}\n\n.spinner-ring:nth-child(2) {\n border-top-color: var(--mj-color-warning-500);\n animation-delay: 0.3s;\n transform: scale(0.8);\n}\n\n.spinner-ring:nth-child(3) {\n border-top-color: var(--mj-status-success);\n animation-delay: 0.6s;\n transform: scale(0.6);\n}\n\n.loading-text {\n color: var(--mj-text-secondary);\n font-weight: 500;\n text-align: center;\n}\n\n/* Animations */\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* Node highlighting styles */\n:host ::ng-deep .erd-container svg .node .entity-rect.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-rect {\n stroke: #4CAF50 !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px rgba(76, 175, 80, 0.5));\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-header {\n fill: #388E3C !important;\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-header-bottom {\n fill: #388E3C !important;\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-name {\n fill: white !important;\n font-weight: bold !important;\n}\n\n/* Related/connected nodes - using tertiary accent */\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-rect.relationship-highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-header {\n fill: var(--mj-status-success) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-header-bottom {\n fill: var(--mj-status-success) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-rect.connection-highlighted {\n stroke: var(--mj-color-warning-500) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-color-warning-500) 50%, transparent));\n opacity: 0.9;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-header {\n fill: var(--mj-color-warning-500) !important;\n opacity: 0.8;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-header-bottom {\n fill: var(--mj-color-warning-500) !important;\n opacity: 0.8;\n}\n\n/* Link styles */\n:host ::ng-deep .erd-container svg .link-group .link {\n stroke-width: 2px;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link:hover {\n stroke-width: 3px;\n stroke: var(--mj-status-success);\n opacity: 1;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n opacity: 1 !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .link-group .link-label {\n font-family: Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n opacity: 0.8;\n pointer-events: none;\n transition: opacity 0.2s ease;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link-label.highlighted {\n opacity: 1;\n font-weight: bold;\n fill: var(--mj-status-success);\n}\n\n:host ::ng-deep .erd-container svg .link-group.highlighted {\n z-index: 10;\n}\n\n/* Field hover */\n:host ::ng-deep .erd-container svg .field-group .field-bg {\n transition: fill 0.2s;\n}\n\n:host ::ng-deep .erd-container svg .field-group:hover .field-bg {\n fill: var(--mj-color-accent-300) !important;\n}\n\n"] }]
1901
+ args: [{ standalone: false, selector: 'mj-erd-diagram', template: "<div class=\"erd-section\">\n @if (showHeader) {\n <div class=\"section-header\">\n <h3>{{ headerTitle }}</h3>\n <div class=\"erd-controls\">\n <button class=\"control-btn\" (click)=\"zoomIn()\" title=\"Zoom In\">\n <span class=\"fa-solid fa-search-plus\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"zoomOut()\" title=\"Zoom Out\">\n <span class=\"fa-solid fa-search-minus\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"resetZoom()\" title=\"Reset Zoom\">\n <span class=\"fa-solid fa-expand\"></span>\n </button>\n <button class=\"control-btn\" (click)=\"refresh(); refreshRequested.emit()\" title=\"Refresh Diagram\">\n <span class=\"fa-solid fa-refresh\"></span>\n </button>\n </div>\n </div>\n }\n <div class=\"erd-container\" #erdContainer>\n @if (isRefreshing) {\n <div class=\"loading-overlay\">\n <div class=\"loading-content\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading diagram...</div>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["/**\n * ERD Diagram Component - MJ Design Tokens\n * MJ theming for the Entity Relationship Diagram visualization\n */\n\n:host {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-section {\n background: var(--mj-bg-page);\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.section-header h3 {\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.erd-controls {\n display: flex;\n gap: 8px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-page);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.control-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.control-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.erd-container {\n flex: 1;\n position: relative;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n width: 100%;\n min-height: 400px;\n box-sizing: border-box;\n}\n\n.erd-container svg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100% !important;\n height: 100% !important;\n box-sizing: border-box;\n}\n\n/* Loading overlay - using mj-loading component styling */\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-page);\n opacity: 0.95;\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.3s ease-in-out;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n}\n\n.spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s linear infinite;\n}\n\n.spinner-ring:nth-child(1) {\n border-top-color: var(--mj-brand-primary);\n animation-delay: 0s;\n}\n\n.spinner-ring:nth-child(2) {\n border-top-color: var(--mj-status-warning);\n animation-delay: 0.3s;\n transform: scale(0.8);\n}\n\n.spinner-ring:nth-child(3) {\n border-top-color: var(--mj-status-success);\n animation-delay: 0.6s;\n transform: scale(0.6);\n}\n\n.loading-text {\n color: var(--mj-text-secondary);\n font-weight: 500;\n text-align: center;\n}\n\n/* Animations */\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* \u2500\u2500 Base node colors (override D3 presentation attributes) \u2500\u2500 */\n:host ::ng-deep .erd-container svg .node .entity-rect {\n fill: var(--mj-bg-surface-card);\n stroke: var(--mj-text-primary);\n}\n\n:host ::ng-deep .erd-container svg .node .entity-header,\n:host ::ng-deep .erd-container svg .node .entity-header-bottom {\n fill: var(--mj-brand-primary);\n}\n\n:host ::ng-deep .erd-container svg .node .entity-name {\n fill: var(--mj-text-inverse);\n}\n\n/* Field backgrounds and text */\n:host ::ng-deep .erd-container svg .field-group.primary-key .field-bg {\n fill: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface-card));\n}\n\n:host ::ng-deep .erd-container svg .field-group.primary-key .field-name,\n:host ::ng-deep .erd-container svg .field-group.primary-key .field-icon {\n fill: var(--mj-text-primary);\n}\n\n:host ::ng-deep .erd-container svg .field-group.foreign-key .field-bg {\n fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface-card));\n}\n\n:host ::ng-deep .erd-container svg .field-group.foreign-key .field-name,\n:host ::ng-deep .erd-container svg .field-group.foreign-key .field-icon {\n fill: var(--mj-text-primary);\n}\n\n/* \u2500\u2500 Link colors \u2500\u2500 */\n:host ::ng-deep .erd-container svg .link-group .link-label-bg {\n fill: var(--mj-bg-surface-card);\n stroke: var(--mj-text-muted);\n}\n\n:host ::ng-deep .erd-container svg .link-group .link-label {\n fill: var(--mj-text-muted);\n}\n\n:host ::ng-deep .erd-container svg .link-group .link {\n stroke: var(--mj-text-muted);\n}\n\n:host ::ng-deep .erd-container svg #end-arrow path {\n fill: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 Node highlighting styles \u2500\u2500 */\n:host ::ng-deep .erd-container svg .node .entity-rect.highlighted {\n stroke: var(--mj-status-warning) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-rect {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n filter: drop-shadow(0 0 8px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-header {\n fill: color-mix(in srgb, var(--mj-status-success) 85%, black) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-header-bottom {\n fill: color-mix(in srgb, var(--mj-status-success) 85%, black) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.selected .entity-name {\n fill: var(--mj-text-inverse) !important;\n font-weight: bold !important;\n}\n\n/* Related/connected nodes - using tertiary accent */\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-rect.relationship-highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-header {\n fill: var(--mj-status-success) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.relationship-connected .entity-header-bottom {\n fill: var(--mj-status-success) !important;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-rect.connection-highlighted {\n stroke: var(--mj-status-warning) !important;\n stroke-width: 3px !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent));\n opacity: 0.9;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-header {\n fill: var(--mj-status-warning) !important;\n opacity: 0.8;\n}\n\n:host ::ng-deep .erd-container svg .node.entity-connections-highlighted .entity-header-bottom {\n fill: var(--mj-status-warning) !important;\n opacity: 0.8;\n}\n\n/* Self-referencing links \u2014 distinct green accent */\n:host ::ng-deep .erd-container svg .link-group.self-reference .link-label-bg {\n fill: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface-card));\n stroke: var(--mj-status-success);\n}\n\n:host ::ng-deep .erd-container svg .link-group.self-reference .link-label {\n fill: color-mix(in srgb, var(--mj-status-success) 80%, var(--mj-text-primary));\n}\n\n/* Link styles */\n:host ::ng-deep .erd-container svg .link-group .link {\n stroke-width: 2px;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link:hover {\n stroke-width: 3px;\n stroke: var(--mj-status-success);\n opacity: 1;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link.highlighted {\n stroke: var(--mj-status-success) !important;\n stroke-width: 4px !important;\n opacity: 1 !important;\n filter: drop-shadow(0 0 6px color-mix(in srgb, var(--mj-status-success) 60%, transparent));\n}\n\n:host ::ng-deep .erd-container svg .link-group .link-label {\n font-family: Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n opacity: 0.8;\n pointer-events: none;\n transition: opacity 0.2s ease;\n}\n\n:host ::ng-deep .erd-container svg .link-group .link-label.highlighted {\n opacity: 1;\n font-weight: bold;\n fill: var(--mj-status-success);\n}\n\n:host ::ng-deep .erd-container svg .link-group.highlighted {\n z-index: 10;\n}\n\n/* Field hover */\n:host ::ng-deep .erd-container svg .field-group .field-bg {\n transition: fill 0.2s;\n}\n\n:host ::ng-deep .erd-container svg .field-group:hover .field-bg {\n fill: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface-card)) !important;\n}\n\n"] }]
1883
1902
  }], null, { erdContainer: [{
1884
1903
  type: ViewChild,
1885
1904
  args: ['erdContainer', { static: false }]