@memberjunction/ng-entity-relationship-diagram 6.1.0-edge.4 → 6.1.0-edge.6

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.
@@ -670,7 +670,7 @@ export class EntityDetailsComponent extends BaseAngularComponent {
670
670
  i0.ɵɵproperty("Fill", true)("FlushBody", true)("Expanded", ctx.relationshipsSectionExpanded);
671
671
  i0.ɵɵadvance(2);
672
672
  i0.ɵɵconditional(ctx.relationshipsSectionExpanded ? 28 : -1);
673
- } }, dependencies: [i1.MJAccordionPanelComponent, i1.MJAccordionTitleDirective, i1.MJAccordionActionsDirective], 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 min-height: 0; \n\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\n\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\n\n\n\n.erd-section-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\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}"] });
673
+ } }, dependencies: [i1.MJAccordionPanelComponent, i1.MJAccordionTitleDirective, i1.MJAccordionActionsDirective], styles: ["\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 min-height: 0; \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\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.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.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.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.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\n\n.erd-section-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\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.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.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.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.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.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.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.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.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.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.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.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.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}"] });
674
674
  }
675
675
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityDetailsComponent, [{
676
676
  type: Component,
@@ -142,7 +142,7 @@ export class EntityFilterPanelComponent {
142
142
  i0.ɵɵtwoWayProperty("ngModel", ctx.filters.baseTable);
143
143
  i0.ɵɵadvance(5);
144
144
  i0.ɵɵproperty("Data", ctx.statusOptions)("ValuePrimitive", true)("ngModel", ctx.filters.entityStatus);
145
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDropdownComponent], styles: ["\n\n\n\n\n\n\n.filter-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n.filter-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 min-width: 0;\n}\n\n.filter-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 flex: 1;\n min-width: 0;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.filter-content[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n overflow-x: hidden;\n flex: 1;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.filter-label[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n\n\n.filter-dropdown[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.filter-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.filter-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.reset-btn[_ngcontent-%COMP%] {\n width: 100%;\n}"] });
145
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i2.MJDropdownComponent], styles: ["\n\n\n\n\n\n.filter-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-page);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n.filter-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 min-width: 0;\n}\n\n.filter-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 flex: 1;\n min-width: 0;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 8px;\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.filter-summary-inline[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.filter-content[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n overflow-x: hidden;\n flex: 1;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.filter-label[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n\n.filter-dropdown[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.filter-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.filter-actions[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.reset-btn[_ngcontent-%COMP%] {\n width: 100%;\n}"] });
146
146
  }
147
147
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityFilterPanelComponent, [{
148
148
  type: Component,
@@ -390,7 +390,7 @@ export class ERDCompositeComponent extends BaseAngularComponent {
390
390
  i0.ɵɵproperty("entities", ctx.filteredEntities)("allEntities", ctx.entities)("selectedEntityId", (ctx.selectedEntity == null ? null : ctx.selectedEntity.ID) || null)("focusEntityId", (ctx.selectedEntity == null ? null : ctx.selectedEntity.ID) || null)("isRefreshing", ctx.isRefreshingERD)("depth", ctx.depth)("includeIncoming", true)("includeOutgoing", true)("showHeader", ctx.showHeader)("config", ctx.erdConfig);
391
391
  i0.ɵɵadvance();
392
392
  i0.ɵɵconditional(ctx.selectedEntity ? 6 : -1);
393
- } }, dependencies: [i1.SplitComponent, i1.SplitAreaComponent, i2.MJEntityERDComponent, i3.EntityDetailsComponent, i4.EntityFilterPanelComponent], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-composite[_ngcontent-%COMP%] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] {\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] .k-pane[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.erd-pane-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n\n\n.floating-details-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n right: 20px;\n width: 380px;\n max-height: calc(100% - 40px);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 28px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n overflow: hidden;\n transform: translateY(-50%);\n animation: _ngcontent-%COMP%_slideInFromRight 0.3s ease-out;\n}\n\n@media (max-width: 768px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n right: 10px;\n left: 10px;\n width: auto;\n max-width: none;\n border-radius: 20px;\n }\n}\n\n@media (max-height: 600px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n top: 20px;\n transform: none;\n max-height: calc(100vh - 40px);\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromRight {\n from {\n transform: translateY(-50%) translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateY(-50%) translateX(0);\n opacity: 1;\n }\n}\n\n\n\n.explorer-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.explorer-header-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n\n\n.back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-400);\n color: var(--mj-text-primary);\n}\n\n.back-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.back-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.explorer-container[_ngcontent-%COMP%] mj-entity-explorer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}"] });
393
+ } }, dependencies: [i1.SplitComponent, i1.SplitAreaComponent, i2.MJEntityERDComponent, i3.EntityDetailsComponent, i4.EntityFilterPanelComponent], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n}\n\n.erd-composite[_ngcontent-%COMP%] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] {\n height: 100%;\n width: 100%;\n}\n\n.main-splitter[_ngcontent-%COMP%] .k-pane[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n.erd-pane-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n\n.floating-details-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n right: 20px;\n width: 380px;\n max-height: calc(100% - 40px);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 28px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1000;\n overflow: hidden;\n transform: translateY(-50%);\n animation: _ngcontent-%COMP%_slideInFromRight 0.3s ease-out;\n}\n\n@media (max-width: 768px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n right: 10px;\n left: 10px;\n width: auto;\n max-width: none;\n border-radius: 20px;\n }\n}\n\n@media (max-height: 600px) {\n .floating-details-panel[_ngcontent-%COMP%] {\n top: 20px;\n transform: none;\n max-height: calc(100vh - 40px);\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromRight {\n from {\n transform: translateY(-50%) translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateY(-50%) translateX(0);\n opacity: 1;\n }\n}\n\n\n.explorer-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.explorer-header-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n\n.back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-page);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-400);\n color: var(--mj-text-primary);\n}\n\n.back-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.back-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.explorer-container[_ngcontent-%COMP%] mj-entity-explorer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}"] });
394
394
  }
395
395
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ERDCompositeComponent, [{
396
396
  type: Component,
@@ -21,16 +21,16 @@ import * as i0 from "@angular/core";
21
21
  import * as i1 from "@memberjunction/ng-ui-components";
22
22
  const _c0 = ["canvasRef"];
23
23
  function ERDDiagramComponent_Conditional_0_Conditional_16_Template(rf, ctx) { if (rf & 1) {
24
- const _r4 = i0.ɵɵgetCurrentView();
24
+ const _r3 = i0.ɵɵgetCurrentView();
25
25
  i0.ɵɵelementStart(0, "button", 44);
26
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onClearSearch()); });
26
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onClearSearch()); });
27
27
  i0.ɵɵtext(1, "\u00D7");
28
28
  i0.ɵɵelementEnd();
29
29
  } }
30
30
  function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
31
- const _r5 = i0.ɵɵgetCurrentView();
31
+ const _r4 = i0.ɵɵgetCurrentView();
32
32
  i0.ɵɵelementStart(0, "button", 46);
33
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template_button_click_0_listener() { const chip_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onSchemaChipToggle(chip_r6.name)); });
33
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template_button_click_0_listener() { const chip_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onSchemaChipToggle(chip_r5.name)); });
34
34
  i0.ɵɵelementStart(1, "span", 47);
35
35
  i0.ɵɵtext(2);
36
36
  i0.ɵɵelementEnd();
@@ -38,25 +38,25 @@ function ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template(rf, ctx
38
38
  i0.ɵɵtext(4);
39
39
  i0.ɵɵelementEnd()();
40
40
  } if (rf & 2) {
41
- const chip_r6 = ctx.$implicit;
42
- i0.ɵɵclassProp("active", chip_r6.active);
43
- i0.ɵɵattribute("aria-pressed", chip_r6.active);
41
+ const chip_r5 = ctx.$implicit;
42
+ i0.ɵɵclassProp("active", chip_r5.active);
43
+ i0.ɵɵattribute("aria-pressed", chip_r5.active);
44
44
  i0.ɵɵadvance(2);
45
- i0.ɵɵtextInterpolate(chip_r6.name);
45
+ i0.ɵɵtextInterpolate(chip_r5.name);
46
46
  i0.ɵɵadvance(2);
47
- i0.ɵɵtextInterpolate(chip_r6.count);
47
+ i0.ɵɵtextInterpolate(chip_r5.count);
48
48
  } }
49
49
  function ERDDiagramComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
50
50
  i0.ɵɵelementStart(0, "div", 30);
51
51
  i0.ɵɵrepeaterCreate(1, ERDDiagramComponent_Conditional_0_Conditional_18_For_2_Template, 5, 5, "button", 45, i0.ɵɵcomponentInstance().trackByChip, true);
52
52
  i0.ɵɵelementEnd();
53
53
  } if (rf & 2) {
54
- const ctx_r2 = i0.ɵɵnextContext(2);
54
+ const ctx_r1 = i0.ɵɵnextContext(2);
55
55
  i0.ɵɵadvance();
56
- i0.ɵɵrepeater(ctx_r2.schemaChips);
56
+ i0.ɵɵrepeater(ctx_r1.schemaChips);
57
57
  } }
58
58
  function ERDDiagramComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
59
- const _r2 = i0.ɵɵgetCurrentView();
59
+ const _r1 = i0.ɵɵgetCurrentView();
60
60
  i0.ɵɵelementStart(0, "header", 1)(1, "div", 19)(2, "div", 20);
61
61
  i0.ɵɵtext(3);
62
62
  i0.ɵɵelementEnd();
@@ -75,57 +75,57 @@ function ERDDiagramComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
75
75
  i0.ɵɵelementStart(13, "label", 25);
76
76
  i0.ɵɵelement(14, "i", 26);
77
77
  i0.ɵɵelementStart(15, "input", 27);
78
- i0.ɵɵlistener("input", function ERDDiagramComponent_Conditional_0_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSearchChange($event.target.value)); });
78
+ i0.ɵɵlistener("input", function ERDDiagramComponent_Conditional_0_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSearchChange($event.target.value)); });
79
79
  i0.ɵɵelementEnd();
80
80
  i0.ɵɵconditionalCreate(16, ERDDiagramComponent_Conditional_0_Conditional_16_Template, 2, 0, "button", 28);
81
81
  i0.ɵɵelementEnd();
82
82
  i0.ɵɵelementStart(17, "div", 29);
83
83
  i0.ɵɵconditionalCreate(18, ERDDiagramComponent_Conditional_0_Conditional_18_Template, 3, 0, "div", 30);
84
84
  i0.ɵɵelementStart(19, "div", 31)(20, "button", 32);
85
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.setLayoutAlgorithm("schema-grid")); });
85
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setLayoutAlgorithm("schema-grid")); });
86
86
  i0.ɵɵelement(21, "i", 33);
87
87
  i0.ɵɵelementEnd();
88
88
  i0.ɵɵelementStart(22, "button", 34);
89
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.setLayoutAlgorithm("dagre")); });
89
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setLayoutAlgorithm("dagre")); });
90
90
  i0.ɵɵelement(23, "i", 35);
91
91
  i0.ɵɵelementEnd()();
92
92
  i0.ɵɵelementStart(24, "div", 36)(25, "button", 37);
93
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.zoomBy(1.2)); });
93
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.zoomBy(1.2)); });
94
94
  i0.ɵɵelement(26, "i", 38);
95
95
  i0.ɵɵelementEnd();
96
96
  i0.ɵɵelementStart(27, "button", 39);
97
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.zoomBy(0.83)); });
97
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.zoomBy(0.83)); });
98
98
  i0.ɵɵelement(28, "i", 40);
99
99
  i0.ɵɵelementEnd();
100
100
  i0.ɵɵelementStart(29, "button", 41);
101
- i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.fitToView()); });
101
+ i0.ɵɵlistener("click", function ERDDiagramComponent_Conditional_0_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.fitToView()); });
102
102
  i0.ɵɵelement(30, "i", 42);
103
103
  i0.ɵɵelementEnd();
104
104
  i0.ɵɵelementStart(31, "span", 43);
105
105
  i0.ɵɵtext(32);
106
106
  i0.ɵɵelementEnd()()()();
107
107
  } if (rf & 2) {
108
- const ctx_r2 = i0.ɵɵnextContext();
108
+ const ctx_r1 = i0.ɵɵnextContext();
109
109
  i0.ɵɵadvance(3);
110
- i0.ɵɵtextInterpolate(ctx_r2.headerTitle);
110
+ i0.ɵɵtextInterpolate(ctx_r1.headerTitle);
111
111
  i0.ɵɵadvance(3);
112
- i0.ɵɵtextInterpolate(ctx_r2.visibleCount);
112
+ i0.ɵɵtextInterpolate(ctx_r1.visibleCount);
113
113
  i0.ɵɵadvance(2);
114
- i0.ɵɵtextInterpolate1("of ", ctx_r2.totalCount, " entities");
114
+ i0.ɵɵtextInterpolate1("of ", ctx_r1.totalCount, " entities");
115
115
  i0.ɵɵadvance(4);
116
- i0.ɵɵtextInterpolate1("", ctx_r2.layout.edges.length, " relationships");
116
+ i0.ɵɵtextInterpolate1("", ctx_r1.layout.edges.length, " relationships");
117
117
  i0.ɵɵadvance(3);
118
- i0.ɵɵproperty("value", ctx_r2.searchQuery);
118
+ i0.ɵɵproperty("value", ctx_r1.searchQuery);
119
119
  i0.ɵɵadvance();
120
- i0.ɵɵconditional(ctx_r2.searchQuery ? 16 : -1);
120
+ i0.ɵɵconditional(ctx_r1.searchQuery ? 16 : -1);
121
121
  i0.ɵɵadvance(2);
122
- i0.ɵɵconditional(ctx_r2.schemaChips.length > 1 ? 18 : -1);
122
+ i0.ɵɵconditional(ctx_r1.schemaChips.length > 1 ? 18 : -1);
123
123
  i0.ɵɵadvance(2);
124
- i0.ɵɵclassProp("active", ctx_r2.activeLayout === "schema-grid");
124
+ i0.ɵɵclassProp("active", ctx_r1.activeLayout === "schema-grid");
125
125
  i0.ɵɵadvance(2);
126
- i0.ɵɵclassProp("active", ctx_r2.activeLayout === "dagre");
126
+ i0.ɵɵclassProp("active", ctx_r1.activeLayout === "dagre");
127
127
  i0.ɵɵadvance(10);
128
- i0.ɵɵtextInterpolate(ctx_r2.zoomPercent);
128
+ i0.ɵɵtextInterpolate(ctx_r1.zoomPercent);
129
129
  } }
130
130
  function ERDDiagramComponent_Conditional_14_For_1_Template(rf, ctx) { if (rf & 1) {
131
131
  i0.ɵɵnamespaceSVG();
@@ -135,28 +135,28 @@ function ERDDiagramComponent_Conditional_14_For_1_Template(rf, ctx) { if (rf & 1
135
135
  i0.ɵɵtext(3);
136
136
  i0.ɵɵelementEnd()();
137
137
  } if (rf & 2) {
138
- const band_r7 = ctx.$implicit;
138
+ const band_r6 = ctx.$implicit;
139
139
  i0.ɵɵadvance();
140
- i0.ɵɵattribute("x", band_r7.x)("y", band_r7.y)("width", band_r7.width)("height", band_r7.height);
140
+ i0.ɵɵattribute("x", band_r6.x)("y", band_r6.y)("width", band_r6.width)("height", band_r6.height);
141
141
  i0.ɵɵadvance();
142
- i0.ɵɵattribute("x", band_r7.x + band_r7.width / 2)("y", band_r7.y + 32);
142
+ i0.ɵɵattribute("x", band_r6.x + band_r6.width / 2)("y", band_r6.y + 32);
143
143
  i0.ɵɵadvance();
144
- i0.ɵɵtextInterpolate1(" ", band_r7.schemaName, " ");
144
+ i0.ɵɵtextInterpolate1(" ", band_r6.schemaName, " ");
145
145
  } }
146
146
  function ERDDiagramComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
147
147
  i0.ɵɵrepeaterCreate(0, ERDDiagramComponent_Conditional_14_For_1_Template, 4, 7, ":svg:g", 49, i0.ɵɵcomponentInstance().trackByBand, true);
148
148
  } if (rf & 2) {
149
- const ctx_r2 = i0.ɵɵnextContext();
150
- i0.ɵɵrepeater(ctx_r2.layout.bands);
149
+ const ctx_r1 = i0.ɵɵnextContext();
150
+ i0.ɵɵrepeater(ctx_r1.layout.bands);
151
151
  } }
152
152
  function ERDDiagramComponent_For_17_Template(rf, ctx) { if (rf & 1) {
153
153
  i0.ɵɵnamespaceSVG();
154
154
  i0.ɵɵelement(0, "path", 52);
155
155
  } if (rf & 2) {
156
- const edge_r8 = ctx.$implicit;
157
- const ctx_r2 = i0.ɵɵnextContext();
158
- i0.ɵɵclassProp("erd-edge-active", ctx_r2.isEdgeActive(edge_r8))("erd-edge-dimmed", ctx_r2.isEdgeDimmed(edge_r8));
159
- i0.ɵɵattribute("d", ctx_r2.edgePath(edge_r8))("marker-start", ctx_r2.config.crowsFoot ?? true ? ctx_r2.isEdgeActive(edge_r8) ? "url(#erd-many-active)" : "url(#erd-many)" : null)("marker-end", ctx_r2.isEdgeActive(edge_r8) ? "url(#erd-arrow-active)" : "url(#erd-arrow)");
156
+ const edge_r7 = ctx.$implicit;
157
+ const ctx_r1 = i0.ɵɵnextContext();
158
+ i0.ɵɵclassProp("erd-edge-active", ctx_r1.isEdgeActive(edge_r7))("erd-edge-dimmed", ctx_r1.isEdgeDimmed(edge_r7));
159
+ i0.ɵɵattribute("d", ctx_r1.edgePath(edge_r7))("marker-start", ctx_r1.config.crowsFoot ?? true ? ctx_r1.isEdgeActive(edge_r7) ? "url(#erd-many-active)" : "url(#erd-many)" : null)("marker-end", ctx_r1.isEdgeActive(edge_r7) ? "url(#erd-arrow-active)" : "url(#erd-arrow)");
160
160
  } }
161
161
  function ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
162
162
  i0.ɵɵnamespaceSVG();
@@ -166,25 +166,25 @@ function ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template(rf, ctx
166
166
  i0.ɵɵtext(3);
167
167
  i0.ɵɵelementEnd()();
168
168
  } if (rf & 2) {
169
- const edge_r9 = i0.ɵɵnextContext().$implicit;
170
- const pos_r10 = i0.ɵɵreadContextLet(0);
171
- const ctx_r2 = i0.ɵɵnextContext(2);
172
- i0.ɵɵclassProp("erd-edge-label-active", ctx_r2.isEdgeActive(edge_r9))("erd-edge-label-dimmed", ctx_r2.isEdgeDimmed(edge_r9));
169
+ const edge_r8 = i0.ɵɵnextContext().$implicit;
170
+ const pos_r9 = i0.ɵɵreadContextLet(0);
171
+ const ctx_r1 = i0.ɵɵnextContext(2);
172
+ i0.ɵɵclassProp("erd-edge-label-active", ctx_r1.isEdgeActive(edge_r8))("erd-edge-label-dimmed", ctx_r1.isEdgeDimmed(edge_r8));
173
173
  i0.ɵɵadvance();
174
- i0.ɵɵattribute("x", pos_r10.x - pos_r10.w / 2 - 4)("y", pos_r10.y - 8)("width", pos_r10.w + 8);
174
+ i0.ɵɵattribute("x", pos_r9.x - pos_r9.w / 2 - 4)("y", pos_r9.y - 8)("width", pos_r9.w + 8);
175
175
  i0.ɵɵadvance();
176
- i0.ɵɵattribute("x", pos_r10.x)("y", pos_r10.y + 4);
176
+ i0.ɵɵattribute("x", pos_r9.x)("y", pos_r9.y + 4);
177
177
  i0.ɵɵadvance();
178
- i0.ɵɵtextInterpolate(edge_r9.sourceField.name);
178
+ i0.ɵɵtextInterpolate(edge_r8.sourceField.name);
179
179
  } }
180
180
  function ERDDiagramComponent_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
181
181
  i0.ɵɵdeclareLet(0);
182
182
  i0.ɵɵconditionalCreate(1, ERDDiagramComponent_Conditional_18_For_2_Conditional_1_Template, 4, 10, ":svg:g", 53);
183
183
  } if (rf & 2) {
184
- const edge_r9 = ctx.$implicit;
185
- const pos_r11 = i0.ɵɵstoreLet(i0.ɵɵnextContext(2).edgeLabelPosition(edge_r9));
184
+ const edge_r8 = ctx.$implicit;
185
+ const pos_r10 = i0.ɵɵstoreLet(i0.ɵɵnextContext(2).edgeLabelPosition(edge_r8));
186
186
  i0.ɵɵadvance();
187
- i0.ɵɵconditional(pos_r11 ? 1 : -1);
187
+ i0.ɵɵconditional(pos_r10 ? 1 : -1);
188
188
  } }
189
189
  function ERDDiagramComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
190
190
  i0.ɵɵnamespaceSVG();
@@ -192,19 +192,19 @@ function ERDDiagramComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
192
192
  i0.ɵɵrepeaterCreate(1, ERDDiagramComponent_Conditional_18_For_2_Template, 2, 2, null, null, i0.ɵɵcomponentInstance().trackByEdge, true);
193
193
  i0.ɵɵelementEnd();
194
194
  } if (rf & 2) {
195
- const ctx_r2 = i0.ɵɵnextContext();
195
+ const ctx_r1 = i0.ɵɵnextContext();
196
196
  i0.ɵɵadvance();
197
- i0.ɵɵrepeater(ctx_r2.layout.edges);
197
+ i0.ɵɵrepeater(ctx_r1.layout.edges);
198
198
  } }
199
199
  function ERDDiagramComponent_For_21_Conditional_8_Template(rf, ctx) { if (rf & 1) {
200
200
  i0.ɵɵelementStart(0, "span", 64);
201
201
  i0.ɵɵtext(1);
202
202
  i0.ɵɵelementEnd();
203
203
  } if (rf & 2) {
204
- const node_r13 = i0.ɵɵnextContext().$implicit;
205
- const ctx_r2 = i0.ɵɵnextContext();
204
+ const node_r12 = i0.ɵɵnextContext().$implicit;
205
+ const ctx_r1 = i0.ɵɵnextContext();
206
206
  i0.ɵɵadvance();
207
- i0.ɵɵtextInterpolate(ctx_r2.formatCount(node_r13.customData.rows));
207
+ i0.ɵɵtextInterpolate(ctx_r1.formatCount(node_r12.customData.rows));
208
208
  } }
209
209
  function ERDDiagramComponent_For_21_For_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
210
210
  i0.ɵɵelementStart(0, "span", 70);
@@ -221,10 +221,10 @@ function ERDDiagramComponent_For_21_For_11_Conditional_6_Template(rf, ctx) { if
221
221
  i0.ɵɵtext(1);
222
222
  i0.ɵɵelementEnd();
223
223
  } if (rf & 2) {
224
- const field_r14 = i0.ɵɵnextContext().$implicit;
225
- i0.ɵɵproperty("title", field_r14.type);
224
+ const field_r13 = i0.ɵɵnextContext().$implicit;
225
+ i0.ɵɵproperty("title", field_r13.type);
226
226
  i0.ɵɵadvance();
227
- i0.ɵɵtextInterpolate(field_r14.type);
227
+ i0.ɵɵtextInterpolate(field_r13.type);
228
228
  } }
229
229
  function ERDDiagramComponent_For_21_For_11_Template(rf, ctx) { if (rf & 1) {
230
230
  i0.ɵɵnamespaceSVG();
@@ -238,41 +238,41 @@ function ERDDiagramComponent_For_21_For_11_Template(rf, ctx) { if (rf & 1) {
238
238
  i0.ɵɵconditionalCreate(6, ERDDiagramComponent_For_21_For_11_Conditional_6_Template, 2, 2, "span", 73);
239
239
  i0.ɵɵelementEnd()();
240
240
  } if (rf & 2) {
241
- const field_r14 = ctx.$implicit;
242
- const ɵ$index_149_r15 = ctx.$index;
243
- const node_r13 = i0.ɵɵnextContext().$implicit;
244
- i0.ɵɵattribute("y", 36 + ɵ$index_149_r15 * 22)("width", node_r13.width);
241
+ const field_r13 = ctx.$implicit;
242
+ const ɵ$index_149_r14 = ctx.$index;
243
+ const node_r12 = i0.ɵɵnextContext().$implicit;
244
+ i0.ɵɵattribute("y", 36 + ɵ$index_149_r14 * 22)("width", node_r12.width);
245
245
  i0.ɵɵadvance();
246
- i0.ɵɵclassProp("erd-field-pk", field_r14.isPrimaryKey)("erd-field-fk", !field_r14.isPrimaryKey && field_r14.relatedNodeId);
246
+ i0.ɵɵclassProp("erd-field-pk", field_r13.isPrimaryKey)("erd-field-fk", !field_r13.isPrimaryKey && field_r13.relatedNodeId);
247
247
  i0.ɵɵadvance();
248
- i0.ɵɵconditional(field_r14.isPrimaryKey ? 2 : field_r14.relatedNodeId ? 3 : -1);
248
+ i0.ɵɵconditional(field_r13.isPrimaryKey ? 2 : field_r13.relatedNodeId ? 3 : -1);
249
249
  i0.ɵɵadvance(2);
250
- i0.ɵɵproperty("title", field_r14.name);
250
+ i0.ɵɵproperty("title", field_r13.name);
251
251
  i0.ɵɵadvance();
252
- i0.ɵɵtextInterpolate(field_r14.name);
252
+ i0.ɵɵtextInterpolate(field_r13.name);
253
253
  i0.ɵɵadvance();
254
- i0.ɵɵconditional(field_r14.type ? 6 : -1);
254
+ i0.ɵɵconditional(field_r13.type ? 6 : -1);
255
255
  } }
256
256
  function ERDDiagramComponent_For_21_Conditional_12_Template(rf, ctx) { if (rf & 1) {
257
- const _r16 = i0.ɵɵgetCurrentView();
257
+ const _r15 = i0.ɵɵgetCurrentView();
258
258
  i0.ɵɵnamespaceSVG();
259
259
  i0.ɵɵelementStart(0, "foreignObject", 74);
260
- i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Conditional_12_Template_foreignObject_click_0_listener($event) { i0.ɵɵrestoreView(_r16); const node_r13 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleExpand(node_r13.id, $event)); });
260
+ i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Conditional_12_Template_foreignObject_click_0_listener($event) { i0.ɵɵrestoreView(_r15); const node_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onToggleExpand(node_r12.id, $event)); });
261
261
  i0.ɵɵnamespaceHTML();
262
262
  i0.ɵɵelementStart(1, "div", 75);
263
263
  i0.ɵɵtext(2);
264
264
  i0.ɵɵelementEnd()();
265
265
  } if (rf & 2) {
266
- const node_r13 = i0.ɵɵnextContext().$implicit;
267
- i0.ɵɵattribute("y", 36 + node_r13.visibleFields.length * 22 + 6)("width", node_r13.width - 8);
266
+ const node_r12 = i0.ɵɵnextContext().$implicit;
267
+ i0.ɵɵattribute("y", 36 + node_r12.visibleFields.length * 22 + 6)("width", node_r12.width - 8);
268
268
  i0.ɵɵadvance(2);
269
- i0.ɵɵtextInterpolate1(" + ", node_r13.fields.length - node_r13.visibleFields.length, " more fields ");
269
+ i0.ɵɵtextInterpolate1(" + ", node_r12.fields.length - node_r12.visibleFields.length, " more fields ");
270
270
  } }
271
271
  function ERDDiagramComponent_For_21_Template(rf, ctx) { if (rf & 1) {
272
- const _r12 = i0.ɵɵgetCurrentView();
272
+ const _r11 = i0.ɵɵgetCurrentView();
273
273
  i0.ɵɵnamespaceSVG();
274
274
  i0.ɵɵelementStart(0, "g", 57);
275
- i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Template_g_click_0_listener($event) { const node_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeClick(node_r13, $event)); })("mouseenter", function ERDDiagramComponent_For_21_Template_g_mouseenter_0_listener($event) { const node_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeMouseEnter(node_r13, $event)); })("mouseleave", function ERDDiagramComponent_For_21_Template_g_mouseleave_0_listener() { const node_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeMouseLeave(node_r13)); });
275
+ i0.ɵɵlistener("click", function ERDDiagramComponent_For_21_Template_g_click_0_listener($event) { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeClick(node_r12, $event)); })("mouseenter", function ERDDiagramComponent_For_21_Template_g_mouseenter_0_listener($event) { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeMouseEnter(node_r12, $event)); })("mouseleave", function ERDDiagramComponent_For_21_Template_g_mouseleave_0_listener() { const node_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNodeMouseLeave(node_r12)); });
276
276
  i0.ɵɵelement(1, "rect", 58)(2, "rect", 59)(3, "rect", 60);
277
277
  i0.ɵɵelementStart(4, "foreignObject", 61);
278
278
  i0.ɵɵnamespaceHTML();
@@ -288,38 +288,38 @@ function ERDDiagramComponent_For_21_Template(rf, ctx) { if (rf & 1) {
288
288
  i0.ɵɵelement(13, "rect", 68);
289
289
  i0.ɵɵelementEnd();
290
290
  } if (rf & 2) {
291
- const node_r13 = ctx.$implicit;
292
- const ctx_r2 = i0.ɵɵnextContext();
293
- i0.ɵɵclassProp("erd-node-focus", ctx_r2.isFocus(node_r13.id))("erd-node-neighbour", ctx_r2.isNeighbour(node_r13.id))("erd-node-dimmed", ctx_r2.isDimmed(node_r13.id));
294
- i0.ɵɵattribute("transform", "translate(" + node_r13.x + " " + node_r13.y + ")");
291
+ const node_r12 = ctx.$implicit;
292
+ const ctx_r1 = i0.ɵɵnextContext();
293
+ i0.ɵɵclassProp("erd-node-focus", ctx_r1.isFocus(node_r12.id))("erd-node-neighbour", ctx_r1.isNeighbour(node_r12.id))("erd-node-dimmed", ctx_r1.isDimmed(node_r12.id));
294
+ i0.ɵɵattribute("transform", "translate(" + node_r12.x + " " + node_r12.y + ")");
295
295
  i0.ɵɵadvance();
296
- i0.ɵɵattribute("width", node_r13.width)("height", node_r13.height);
296
+ i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
297
297
  i0.ɵɵadvance();
298
- i0.ɵɵattribute("width", node_r13.width)("height", node_r13.height);
298
+ i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
299
299
  i0.ɵɵadvance();
300
- i0.ɵɵattribute("width", node_r13.width);
300
+ i0.ɵɵattribute("width", node_r12.width);
301
301
  i0.ɵɵadvance();
302
- i0.ɵɵattribute("width", node_r13.width - 28);
302
+ i0.ɵɵattribute("width", node_r12.width - 28);
303
303
  i0.ɵɵadvance(2);
304
- i0.ɵɵproperty("title", node_r13.name);
304
+ i0.ɵɵproperty("title", node_r12.name);
305
305
  i0.ɵɵadvance();
306
- i0.ɵɵtextInterpolate(node_r13.name);
306
+ i0.ɵɵtextInterpolate(node_r12.name);
307
307
  i0.ɵɵadvance();
308
- i0.ɵɵconditional(node_r13.customData && node_r13.customData.rows != null ? 8 : -1);
308
+ i0.ɵɵconditional(node_r12.customData && node_r12.customData.rows != null ? 8 : -1);
309
309
  i0.ɵɵadvance();
310
- i0.ɵɵattribute("x2", node_r13.width);
310
+ i0.ɵɵattribute("x2", node_r12.width);
311
311
  i0.ɵɵadvance();
312
- i0.ɵɵrepeater(node_r13.visibleFields);
312
+ i0.ɵɵrepeater(node_r12.visibleFields);
313
313
  i0.ɵɵadvance(2);
314
- i0.ɵɵconditional(node_r13.hasMore ? 12 : -1);
314
+ i0.ɵɵconditional(node_r12.hasMore ? 12 : -1);
315
315
  i0.ɵɵadvance();
316
- i0.ɵɵattribute("width", node_r13.width)("height", node_r13.height);
316
+ i0.ɵɵattribute("width", node_r12.width)("height", node_r12.height);
317
317
  } }
318
318
  function ERDDiagramComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
319
319
  i0.ɵɵelement(0, "mj-empty-state", 17);
320
320
  } if (rf & 2) {
321
- const ctx_r2 = i0.ɵɵnextContext();
322
- i0.ɵɵproperty("Variant", ctx_r2.totalCount === 0 ? "empty" : "no-results")("Icon", ctx_r2.emptyStateIcon)("Title", ctx_r2.emptyStateTitle)("Message", ctx_r2.totalCount > 0 ? "Try adjusting schema filters or clearing search" : "");
321
+ const ctx_r1 = i0.ɵɵnextContext();
322
+ i0.ɵɵproperty("Variant", ctx_r1.totalCount === 0 ? "empty" : "no-results")("Icon", ctx_r1.emptyStateIcon)("Title", ctx_r1.emptyStateTitle)("Message", ctx_r1.totalCount > 0 ? "Try adjusting schema filters or clearing search" : "");
323
323
  } }
324
324
  function ERDDiagramComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
325
325
  i0.ɵɵelementStart(0, "div", 18)(1, "div", 76);
@@ -976,12 +976,11 @@ export class ERDDiagramComponent {
976
976
  } }, hostVars: 2, hostBindings: function ERDDiagramComponent_HostBindings(rf, ctx) { if (rf & 2) {
977
977
  i0.ɵɵclassProp("erd-root", ctx.rootClass);
978
978
  } }, inputs: { nodes: "nodes", selectedNodeId: "selectedNodeId", highlightedNodeIds: "highlightedNodeIds", focusNodeId: "focusNodeId", focusDepth: "focusDepth", isRefreshing: "isRefreshing", readOnly: "readOnly", config: "config", showHeader: "showHeader", headerTitle: "headerTitle" }, outputs: { nodeClick: "nodeClick", nodeDoubleClick: "nodeDoubleClick", nodeSelected: "nodeSelected", nodeDeselected: "nodeDeselected", linkClick: "linkClick", nodeHover: "nodeHover", nodeHoverEnd: "nodeHoverEnd", linkHover: "linkHover", linkHoverEnd: "linkHoverEnd", nodeContextMenu: "nodeContextMenu", linkContextMenu: "linkContextMenu", diagramContextMenu: "diagramContextMenu", nodeDragStart: "nodeDragStart", nodeDragEnd: "nodeDragEnd", zoomChange: "zoomChange", refreshRequested: "refreshRequested", layoutComplete: "layoutComplete", stateChange: "stateChange" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 24, vars: 7, consts: [["canvasRef", ""], [1, "erd-chrome"], [1, "erd-canvas-wrap"], [1, "erd-canvas", 3, "mousedown", "wheel"], ["id", "erd-arrow", "viewBox", "0 0 10 10", "refX", "9", "refY", "5", "markerWidth", "7", "markerHeight", "7", "orient", "auto"], ["d", "M 0 0 L 10 5 L 0 10 z", 1, "erd-marker"], ["id", "erd-arrow-active", "viewBox", "0 0 10 10", "refX", "9", "refY", "5", "markerWidth", "7", "markerHeight", "7", "orient", "auto"], ["d", "M 0 0 L 10 5 L 0 10 z", 1, "erd-marker", "erd-marker-active"], ["id", "erd-many", "viewBox", "-10 -6 14 12", "refX", "-8", "refY", "0", "markerWidth", "14", "markerHeight", "14", "orient", "auto"], ["d", "M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0", 1, "erd-marker-stroke"], ["id", "erd-many-active", "viewBox", "-10 -6 14 12", "refX", "-8", "refY", "0", "markerWidth", "14", "markerHeight", "14", "orient", "auto"], ["d", "M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0", 1, "erd-marker-stroke", "erd-marker-active"], [1, "erd-edges"], ["fill", "none", 1, "erd-edge", 3, "erd-edge-active", "erd-edge-dimmed"], [1, "erd-edge-labels"], [1, "erd-nodes"], [1, "erd-node", 3, "erd-node-focus", "erd-node-neighbour", "erd-node-dimmed"], [1, "erd-empty", 3, "Variant", "Icon", "Title", "Message"], [1, "erd-loading-overlay"], [1, "erd-title-group"], [1, "erd-title"], [1, "erd-subtitle"], [1, "erd-count-pill"], [1, "erd-count-label"], [1, "erd-dot"], [1, "erd-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Search entities, schemas, fields\u2026", "spellcheck", "false", "aria-label", "Search entities", 3, "input", "value"], ["type", "button", "aria-label", "Clear search", 1, "erd-search-clear"], [1, "erd-chrome-right"], ["role", "group", "aria-label", "Filter by schema", 1, "erd-schema-chips"], ["role", "group", "aria-label", "Layout mode", 1, "erd-toolbar"], ["type", "button", "title", "Schema grid \u2014 grouped by schema, predictable", "aria-label", "Schema-grid layout", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-table-cells"], ["type", "button", "title", "Hierarchical \u2014 classic ERD, relationship-driven", "aria-label", "Hierarchical layout", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sitemap"], ["role", "group", "aria-label", "Zoom controls", 1, "erd-toolbar"], ["type", "button", "title", "Zoom in", "aria-label", "Zoom in", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass-plus"], ["type", "button", "title", "Zoom out", "aria-label", "Zoom out", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass-minus"], ["type", "button", "title", "Fit to view", "aria-label", "Fit to view", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-expand"], [1, "erd-zoom-val"], ["type", "button", "aria-label", "Clear search", 1, "erd-search-clear", 3, "click"], ["type", "button", 1, "erd-chip", 3, "active"], ["type", "button", 1, "erd-chip", 3, "click"], [1, "erd-chip-label"], [1, "erd-chip-count"], [1, "erd-band"], ["rx", "16", 1, "erd-band-rect"], ["text-anchor", "middle", 1, "erd-band-title"], ["fill", "none", 1, "erd-edge"], [1, "erd-edge-label", 3, "erd-edge-label-active", "erd-edge-label-dimmed"], [1, "erd-edge-label"], ["height", "16", "rx", "3", 1, "erd-edge-label-bg"], ["text-anchor", "middle", 1, "erd-edge-label-text"], [1, "erd-node", 3, "click", "mouseenter", "mouseleave"], ["x", "0", "y", "2", "rx", "8", 1, "erd-node-shadow"], ["x", "0", "y", "0", "rx", "8", 1, "erd-node-body"], ["x", "0", "y", "0", "height", "36", "rx", "6", 1, "erd-node-header"], ["x", "14", "y", "8", "height", "22"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-node-header-content"], [1, "erd-node-name", 3, "title"], [1, "erd-node-rows"], ["x1", "0", "y1", "36", "y2", "36", 1, "erd-node-separator"], ["x", "0", "height", "22"], ["x", "4", "height", "14"], ["x", "0", "y", "0", "rx", "8", 1, "erd-node-frame"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-field-row"], [1, "erd-field-chip", "erd-field-chip-pk"], [1, "erd-field-chip", "erd-field-chip-fk"], [1, "erd-field-name", 3, "title"], [1, "erd-field-type", 3, "title"], ["x", "4", "height", "14", 3, "click"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "erd-field-more"], [1, "erd-loading-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-notch", "fa-spin"]], template: function ERDDiagramComponent_Template(rf, ctx) { if (rf & 1) {
979
- const _r1 = i0.ɵɵgetCurrentView();
980
979
  i0.ɵɵconditionalCreate(0, ERDDiagramComponent_Conditional_0_Template, 33, 12, "header", 1);
981
980
  i0.ɵɵelementStart(1, "div", 2);
982
981
  i0.ɵɵnamespaceSVG();
983
982
  i0.ɵɵelementStart(2, "svg", 3, 0);
984
- i0.ɵɵlistener("mousedown", function ERDDiagramComponent_Template_svg_mousedown_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onBackgroundMouseDown($event)); })("wheel", function ERDDiagramComponent_Template_svg_wheel_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onWheel($event)); });
983
+ i0.ɵɵlistener("mousedown", function ERDDiagramComponent_Template_svg_mousedown_2_listener($event) { return ctx.onBackgroundMouseDown($event); })("wheel", function ERDDiagramComponent_Template_svg_wheel_2_listener($event) { return ctx.onWheel($event); });
985
984
  i0.ɵɵelementStart(4, "defs")(5, "marker", 4);
986
985
  i0.ɵɵelement(6, "path", 5);
987
986
  i0.ɵɵelementEnd();
@@ -1024,7 +1023,7 @@ export class ERDDiagramComponent {
1024
1023
  i0.ɵɵconditional(ctx.visibleCount === 0 ? 22 : -1);
1025
1024
  i0.ɵɵadvance();
1026
1025
  i0.ɵɵconditional(ctx.isRefreshing ? 23 : -1);
1027
- } }, dependencies: [i1.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex !important;\n flex-direction: column !important;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n --erd-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace;\n}\n\n\n\n\n.erd-chrome[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n min-height: 64px;\n}\n\n.erd-title-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.erd-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n\n.erd-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.erd-count-pill[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n line-height: 1.3;\n}\n\n.erd-count-label[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.erd-dot[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.erd-search[_ngcontent-%COMP%] {\n flex: 1;\n max-width: 440px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n transition: border-color .12s, background .12s, box-shadow .12s;\n}\n\n.erd-search[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.erd-search[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-muted); }\n\n.erd-search-clear[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 0 4px;\n}\n\n.erd-search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.erd-chrome-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: auto;\n}\n\n\n\n.erd-schema-chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.erd-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n background: transparent;\n border-radius: 7px;\n font-family: var(--erd-mono);\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background .1s, color .1s;\n}\n\n.erd-chip[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-chip.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.erd-chip-count[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 80%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n\n.erd-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: 0;\n background: transparent;\n border-radius: 5px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: background .1s, color .1s;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-zoom-val[_ngcontent-%COMP%] {\n padding: 0 8px;\n font-family: var(--erd-mono);\n font-size: 10px;\n color: var(--mj-text-secondary);\n min-width: 42px;\n text-align: right;\n}\n\n\n\n\n.erd-canvas-wrap[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n min-height: 300px;\n}\n\n.erd-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n user-select: none;\n cursor: grab;\n display: block;\n}\n\n.erd-canvas[data-panning=\"true\"][_ngcontent-%COMP%] { cursor: grabbing; }\n\n.erd-canvas[_ngcontent-%COMP%] text[_ngcontent-%COMP%] { pointer-events: none; }\n\n\n\n.erd-band-rect[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n.erd-band-title[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--mj-text-muted);\n}\n\n\n\n.erd-edge[_ngcontent-%COMP%] {\n stroke: var(--mj-border-strong);\n stroke-width: 1.2;\n transition: stroke-width .15s, opacity .15s;\n}\n\n.erd-edge-active[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 1.8;\n}\n\n.erd-edge-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n\n.erd-edge-label[_ngcontent-%COMP%] {\n pointer-events: none;\n transition: opacity .15s;\n}\n\n.erd-edge-label-bg[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n stroke: var(--mj-border-default);\n stroke-width: 0.75;\n}\n\n.erd-edge-label-text[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n fill: var(--mj-text-secondary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-bg[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-text[_ngcontent-%COMP%] {\n fill: var(--mj-brand-primary);\n}\n\n.erd-edge-label-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n.erd-marker[_ngcontent-%COMP%] { fill: var(--mj-border-strong); }\n.erd-marker-active[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker-stroke[_ngcontent-%COMP%] { fill: var(--mj-brand-primary); stroke: var(--mj-brand-primary); }\n.erd-marker-stroke[_ngcontent-%COMP%] { stroke: var(--mj-border-strong); stroke-width: 1.4; fill: none; stroke-linecap: round; }\n\n\n\n.erd-node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity .15s;\n}\n\n.erd-node-dimmed[_ngcontent-%COMP%] { opacity: 0.22; }\n\n.erd-node-shadow[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.erd-node-body[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n}\n\n\n\n\n\n.erd-node-frame[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 1;\n pointer-events: none;\n}\n\n.erd-node-focus[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 2;\n}\n\n.erd-node-neighbour[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke-width: 1.5;\n}\n\n.erd-node-header[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface-card);\n}\n\n.erd-node-separator[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n\n\n.erd-node-header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n height: 22px;\n color: var(--mj-text-primary);\n}\n\n.erd-node-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-node-rows[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n\n\n.erd-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 22px;\n padding: 0 12px 0 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n box-sizing: border-box;\n}\n\n.erd-field-chip[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 14px;\n border-radius: 3px;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 0.05em;\n line-height: 1;\n}\n\n.erd-field-chip-pk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n.erd-field-chip-fk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-field-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 11px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-field-type[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 10px;\n color: var(--mj-text-muted);\n \n\n max-width: 45%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.erd-field-more[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 14px;\n border-radius: 3px;\n background: var(--mj-bg-surface-card);\n opacity: 0.7;\n font-family: inherit;\n font-size: 9px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: opacity .1s;\n}\n\n.erd-field-more[_ngcontent-%COMP%]:hover { opacity: 1; }\n\n\n\n\n\n\n.erd-empty[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.erd-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 90%, transparent);\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}"], changeDetection: 0 });
1026
+ } }, dependencies: [i1.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex !important;\n flex-direction: column !important;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n --erd-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, \"Liberation Mono\", monospace;\n}\n\n\n\n.erd-chrome[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 24px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n min-height: 64px;\n}\n\n.erd-title-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.erd-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n\n.erd-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.erd-count-pill[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n line-height: 1.3;\n}\n\n.erd-count-label[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n.erd-dot[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.erd-search[_ngcontent-%COMP%] {\n flex: 1;\n max-width: 440px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n transition: border-color .12s, background .12s, box-shadow .12s;\n}\n\n.erd-search[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.erd-search[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.erd-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-muted); }\n\n.erd-search-clear[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n padding: 0 4px;\n}\n\n.erd-search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n.erd-chrome-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: auto;\n}\n\n\n.erd-schema-chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.erd-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 0;\n background: transparent;\n border-radius: 7px;\n font-family: var(--erd-mono);\n font-size: 11px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background .1s, color .1s;\n}\n\n.erd-chip[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-chip.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.erd-chip-count[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 80%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n.erd-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: 0;\n background: transparent;\n border-radius: 5px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n transition: background .1s, color .1s;\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.erd-toolbar[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-zoom-val[_ngcontent-%COMP%] {\n padding: 0 8px;\n font-family: var(--erd-mono);\n font-size: 10px;\n color: var(--mj-text-secondary);\n min-width: 42px;\n text-align: right;\n}\n\n\n\n.erd-canvas-wrap[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-sunken);\n min-height: 300px;\n}\n\n.erd-canvas[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n user-select: none;\n cursor: grab;\n display: block;\n}\n\n.erd-canvas[data-panning=\"true\"][_ngcontent-%COMP%] { cursor: grabbing; }\n\n.erd-canvas[_ngcontent-%COMP%] text[_ngcontent-%COMP%] { pointer-events: none; }\n\n\n.erd-band-rect[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n.erd-band-title[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--mj-text-muted);\n}\n\n\n.erd-edge[_ngcontent-%COMP%] {\n stroke: var(--mj-border-strong);\n stroke-width: 1.2;\n transition: stroke-width .15s, opacity .15s;\n}\n\n.erd-edge-active[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 1.8;\n}\n\n.erd-edge-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n\n.erd-edge-label[_ngcontent-%COMP%] {\n pointer-events: none;\n transition: opacity .15s;\n}\n\n.erd-edge-label-bg[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n stroke: var(--mj-border-default);\n stroke-width: 0.75;\n}\n\n.erd-edge-label-text[_ngcontent-%COMP%] {\n font-family: var(--erd-mono);\n font-size: 11px;\n fill: var(--mj-text-secondary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-bg[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n}\n\n.erd-edge-label-active[_ngcontent-%COMP%] .erd-edge-label-text[_ngcontent-%COMP%] {\n fill: var(--mj-brand-primary);\n}\n\n.erd-edge-label-dimmed[_ngcontent-%COMP%] { opacity: 0.18; }\n\n\n.erd-marker[_ngcontent-%COMP%] { fill: var(--mj-border-strong); }\n.erd-marker-active[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker[_ngcontent-%COMP%], \n.erd-marker-active.erd-marker-stroke[_ngcontent-%COMP%] { fill: var(--mj-brand-primary); stroke: var(--mj-brand-primary); }\n.erd-marker-stroke[_ngcontent-%COMP%] { stroke: var(--mj-border-strong); stroke-width: 1.4; fill: none; stroke-linecap: round; }\n\n\n.erd-node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: opacity .15s;\n}\n\n.erd-node-dimmed[_ngcontent-%COMP%] { opacity: 0.22; }\n\n.erd-node-shadow[_ngcontent-%COMP%] {\n fill: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.erd-node-body[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface);\n}\n\n\n\n\n.erd-node-frame[_ngcontent-%COMP%] {\n fill: none;\n stroke: var(--mj-border-default);\n stroke-width: 1;\n pointer-events: none;\n}\n\n.erd-node-focus[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke: var(--mj-brand-primary);\n stroke-width: 2;\n}\n\n.erd-node-neighbour[_ngcontent-%COMP%] .erd-node-frame[_ngcontent-%COMP%] {\n stroke-width: 1.5;\n}\n\n.erd-node-header[_ngcontent-%COMP%] {\n fill: var(--mj-bg-surface-card);\n}\n\n.erd-node-separator[_ngcontent-%COMP%] {\n stroke: var(--mj-border-default);\n stroke-width: 1;\n}\n\n\n.erd-node-header-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n height: 22px;\n color: var(--mj-text-primary);\n}\n\n.erd-node-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-node-rows[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n\n.erd-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 22px;\n padding: 0 12px 0 8px;\n font-family: var(--erd-mono);\n line-height: 22px;\n box-sizing: border-box;\n}\n\n.erd-field-chip[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 14px;\n border-radius: 3px;\n font-size: 8px;\n font-weight: 700;\n letter-spacing: 0.05em;\n line-height: 1;\n}\n\n.erd-field-chip-pk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n.erd-field-chip-fk[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.erd-field-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 11px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.erd-field-type[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 10px;\n color: var(--mj-text-muted);\n \n max-width: 45%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n.erd-field-more[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 14px;\n border-radius: 3px;\n background: var(--mj-bg-surface-card);\n opacity: 0.7;\n font-family: inherit;\n font-size: 9px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: opacity .1s;\n}\n\n.erd-field-more[_ngcontent-%COMP%]:hover { opacity: 1; }\n\n\n\n\n.erd-empty[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.erd-loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 90%, transparent);\n backdrop-filter: blur(2px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.erd-loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}"], changeDetection: 0 });
1028
1027
  }
1029
1028
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ERDDiagramComponent, [{
1030
1029
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Icon for the empty state — honours `config.emptyStateIcon` when provided. */\n public get emptyStateIcon(): string {\n return this.config.emptyStateIcon || 'fa-solid fa-diagram-project';\n }\n\n /** Title for the empty state — distinguishes \"nothing here\" from \"filtered to nothing\". */\n public get emptyStateTitle(): string {\n return this.totalCount === 0\n ? (this.config.emptyStateMessage || 'No entities to display')\n : 'No entities match';\n }\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <mj-empty-state\n class=\"erd-empty\"\n [Variant]=\"totalCount === 0 ? 'empty' : 'no-results'\"\n [Icon]=\"emptyStateIcon\"\n [Title]=\"emptyStateTitle\"\n [Message]=\"totalCount > 0 ? 'Try adjusting schema filters or clearing search' : ''\" />\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
1
+ {"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Icon for the empty state — honours `config.emptyStateIcon` when provided. */\n public get emptyStateIcon(): string {\n return this.config.emptyStateIcon || 'fa-solid fa-diagram-project';\n }\n\n /** Title for the empty state — distinguishes \"nothing here\" from \"filtered to nothing\". */\n public get emptyStateTitle(): string {\n return this.totalCount === 0\n ? (this.config.emptyStateMessage || 'No entities to display')\n : 'No entities match';\n }\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <mj-empty-state\n class=\"erd-empty\"\n [Variant]=\"totalCount === 0 ? 'empty' : 'no-results'\"\n [Icon]=\"emptyStateIcon\"\n [Title]=\"emptyStateTitle\"\n [Message]=\"totalCount > 0 ? 'Try adjusting schema filters or clearing search' : ''\" />\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-entity-relationship-diagram",
3
- "version": "6.1.0-edge.4",
3
+ "version": "6.1.0-edge.6",
4
4
  "description": "MemberJunction: Entity Relationship Diagram (ERD) component for visualizing entity relationships using D3.js force-directed graphs",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -18,24 +18,24 @@
18
18
  "author": "",
19
19
  "license": "BUSL-1.1",
20
20
  "devDependencies": {
21
- "@angular/compiler": "21.1.3",
22
- "@angular/compiler-cli": "21.1.3",
23
- "@memberjunction/ng-test-utils": "6.1.0-edge.4",
21
+ "@angular/compiler": "21.2.22",
22
+ "@angular/compiler-cli": "21.2.22",
23
+ "@memberjunction/ng-test-utils": "6.1.0-edge.6",
24
24
  "sass": "^1.97.3",
25
25
  "vitest": "^4.0.18"
26
26
  },
27
27
  "peerDependencies": {
28
- "@angular/common": "^21.1.3",
29
- "@angular/core": "^21.1.3",
30
- "@angular/platform-browser": "^21.1.3"
28
+ "@angular/common": "^21.2.22",
29
+ "@angular/core": "^21.2.22",
30
+ "@angular/forms": "^21.2.22",
31
+ "@angular/platform-browser": "^21.2.22"
31
32
  },
32
33
  "dependencies": {
33
- "@angular/forms": "21.1.3",
34
34
  "@dagrejs/dagre": "^1.1.8",
35
- "@memberjunction/core": "6.1.0-edge.4",
36
- "@memberjunction/ng-base-types": "6.1.0-edge.4",
37
- "@memberjunction/global": "6.1.0-edge.4",
38
- "@memberjunction/ng-ui-components": "6.1.0-edge.4",
35
+ "@memberjunction/core": "6.1.0-edge.6",
36
+ "@memberjunction/ng-base-types": "6.1.0-edge.6",
37
+ "@memberjunction/global": "6.1.0-edge.6",
38
+ "@memberjunction/ng-ui-components": "6.1.0-edge.6",
39
39
  "@types/d3": "^7.4.3",
40
40
  "angular-split": "^20.0.0",
41
41
  "d3": "^7.9.0",