@memberjunction/ng-entity-relationship-diagram 5.30.1 → 5.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/__tests__/compute-erd-layout.test.d.ts +2 -0
  2. package/dist/__tests__/compute-erd-layout.test.d.ts.map +1 -0
  3. package/dist/__tests__/compute-erd-layout.test.js +207 -0
  4. package/dist/__tests__/compute-erd-layout.test.js.map +1 -0
  5. package/dist/lib/components/entity-details/entity-details.component.d.ts +2 -1
  6. package/dist/lib/components/entity-details/entity-details.component.d.ts.map +1 -1
  7. package/dist/lib/components/entity-details/entity-details.component.js +7 -7
  8. package/dist/lib/components/entity-details/entity-details.component.js.map +1 -1
  9. package/dist/lib/components/entity-filter-panel/entity-filter-panel.component.d.ts +10 -4
  10. package/dist/lib/components/entity-filter-panel/entity-filter-panel.component.d.ts.map +1 -1
  11. package/dist/lib/components/entity-filter-panel/entity-filter-panel.component.js +60 -72
  12. package/dist/lib/components/entity-filter-panel/entity-filter-panel.component.js.map +1 -1
  13. package/dist/lib/components/erd-composite/erd-composite.component.d.ts +4 -1
  14. package/dist/lib/components/erd-composite/erd-composite.component.d.ts.map +1 -1
  15. package/dist/lib/components/erd-composite/erd-composite.component.js +22 -8
  16. package/dist/lib/components/erd-composite/erd-composite.component.js.map +1 -1
  17. package/dist/lib/components/erd-diagram.component.d.ts +169 -443
  18. package/dist/lib/components/erd-diagram.component.d.ts.map +1 -1
  19. package/dist/lib/components/erd-diagram.component.js +916 -1777
  20. package/dist/lib/components/erd-diagram.component.js.map +1 -1
  21. package/dist/lib/components/mj-entity-erd.component.d.ts +3 -2
  22. package/dist/lib/components/mj-entity-erd.component.d.ts.map +1 -1
  23. package/dist/lib/components/mj-entity-erd.component.js +6 -6
  24. package/dist/lib/components/mj-entity-erd.component.js.map +1 -1
  25. package/dist/lib/entity-relationship-diagram.module.d.ts +2 -1
  26. package/dist/lib/entity-relationship-diagram.module.d.ts.map +1 -1
  27. package/dist/lib/entity-relationship-diagram.module.js +9 -3
  28. package/dist/lib/entity-relationship-diagram.module.js.map +1 -1
  29. package/dist/lib/interfaces/erd-types.d.ts +38 -7
  30. package/dist/lib/interfaces/erd-types.d.ts.map +1 -1
  31. package/dist/lib/interfaces/erd-types.js.map +1 -1
  32. package/dist/lib/layout/compute-dagre-layout.d.ts +32 -0
  33. package/dist/lib/layout/compute-dagre-layout.d.ts.map +1 -0
  34. package/dist/lib/layout/compute-dagre-layout.js +168 -0
  35. package/dist/lib/layout/compute-dagre-layout.js.map +1 -0
  36. package/dist/lib/layout/compute-erd-layout.d.ts +103 -0
  37. package/dist/lib/layout/compute-erd-layout.d.ts.map +1 -0
  38. package/dist/lib/layout/compute-erd-layout.js +254 -0
  39. package/dist/lib/layout/compute-erd-layout.js.map +1 -0
  40. package/package.json +6 -5
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compute-erd-layout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-erd-layout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute-erd-layout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,207 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { computeErdLayout, pointsToPath, getNeighbors } from '../lib/layout/compute-erd-layout';
3
+ const pk = (id, name = 'ID') => ({ id, name, type: 'uniqueidentifier', isPrimaryKey: true });
4
+ const fk = (id, name, targetId) => ({
5
+ id, name, type: 'uniqueidentifier', isPrimaryKey: false, relatedNodeId: targetId,
6
+ });
7
+ const col = (id, name) => ({ id, name, type: 'nvarchar', isPrimaryKey: false });
8
+ const node = (id, schema, name, fields) => ({
9
+ id, name, schemaName: schema, fields,
10
+ });
11
+ describe('computeErdLayout', () => {
12
+ describe('empty input', () => {
13
+ it('returns empty layout for no nodes', () => {
14
+ const layout = computeErdLayout([]);
15
+ expect(layout.nodes).toEqual([]);
16
+ expect(layout.edges).toEqual([]);
17
+ expect(layout.bands).toEqual([]);
18
+ });
19
+ });
20
+ describe('single node', () => {
21
+ it('creates one node in one band', () => {
22
+ const n = node('u', 'core', 'Users', [pk('u:id')]);
23
+ const layout = computeErdLayout([n]);
24
+ expect(layout.nodes).toHaveLength(1);
25
+ expect(layout.bands).toHaveLength(1);
26
+ expect(layout.bands[0].schemaName).toBe('core');
27
+ expect(layout.nodes[0].id).toBe('u');
28
+ expect(layout.nodes[0].width).toBeGreaterThan(0);
29
+ expect(layout.nodes[0].height).toBeGreaterThan(0);
30
+ });
31
+ it('uses the synthetic default schema when schemaName is missing', () => {
32
+ const n = node('u', undefined, 'Users', [pk('u:id')]);
33
+ const layout = computeErdLayout([n]);
34
+ expect(layout.bands).toHaveLength(1);
35
+ expect(layout.bands[0].schemaName).toBe('_');
36
+ });
37
+ });
38
+ describe('column layout rules', () => {
39
+ const make = (count, schema = 'core') => Array.from({ length: count }, (_, i) => node(`${schema}-${i}`, schema, `Entity${i}`, [pk(`${i}:id`)]));
40
+ it('uses 1 column when count <= 3', () => {
41
+ const layout = computeErdLayout(make(3));
42
+ const xs = new Set(layout.nodes.map(n => n.x));
43
+ expect(xs.size).toBe(1);
44
+ });
45
+ it('uses 2 columns when count is between 4 and 8', () => {
46
+ const layout = computeErdLayout(make(6));
47
+ const xs = new Set(layout.nodes.map(n => n.x));
48
+ expect(xs.size).toBe(2);
49
+ });
50
+ it('uses 3 columns when count > 8', () => {
51
+ const layout = computeErdLayout(make(12));
52
+ const xs = new Set(layout.nodes.map(n => n.x));
53
+ expect(xs.size).toBe(3);
54
+ });
55
+ });
56
+ describe('schema bands', () => {
57
+ it('creates one band per distinct schema', () => {
58
+ const nodes = [
59
+ node('a', 'core', 'A', [pk('a:id')]),
60
+ node('b', 'ai', 'B', [pk('b:id')]),
61
+ node('c', 'core', 'C', [pk('c:id')]),
62
+ ];
63
+ const layout = computeErdLayout(nodes, { schemaOrder: ['core', 'ai'] });
64
+ expect(layout.bands.map(b => b.schemaName)).toEqual(['core', 'ai']);
65
+ });
66
+ it('aligns all band heights to the tallest', () => {
67
+ const nodes = [
68
+ node('a', 'core', 'A', [pk('a:id')]),
69
+ node('b', 'core', 'B', [pk('b:id')]),
70
+ node('c', 'core', 'C', [pk('c:id')]),
71
+ node('d', 'core', 'D', [pk('d:id')]),
72
+ node('e', 'ai', 'E', [pk('e:id')]),
73
+ ];
74
+ const layout = computeErdLayout(nodes);
75
+ const heights = new Set(layout.bands.map(b => b.height));
76
+ expect(heights.size).toBe(1);
77
+ });
78
+ it('sorts entities alphabetically within a band', () => {
79
+ const nodes = [
80
+ node('a', 'core', 'Charlie', [pk('c:id')]),
81
+ node('b', 'core', 'Alpha', [pk('a:id')]),
82
+ node('c', 'core', 'Bravo', [pk('b:id')]),
83
+ ];
84
+ const layout = computeErdLayout(nodes);
85
+ expect(layout.nodes.map(n => n.name)).toEqual(['Alpha', 'Bravo', 'Charlie']);
86
+ });
87
+ });
88
+ describe('field visibility', () => {
89
+ it('hides non-PK/FK fields by default (keys-only view)', () => {
90
+ const n = node('u', 'core', 'Users', [
91
+ pk('u:id'),
92
+ col('u:name', 'Name'),
93
+ col('u:email', 'Email'),
94
+ fk('u:role', 'RoleID', 'r'),
95
+ ]);
96
+ const layout = computeErdLayout([n]);
97
+ const visible = layout.nodes[0].visibleFields.map(f => f.name);
98
+ expect(visible).toEqual(['ID', 'RoleID']);
99
+ expect(layout.nodes[0].hasMore).toBe(true);
100
+ });
101
+ it('shows every field when showAllFields is true', () => {
102
+ const n = node('u', 'core', 'Users', [
103
+ pk('u:id'),
104
+ col('u:name', 'Name'),
105
+ col('u:email', 'Email'),
106
+ ]);
107
+ const layout = computeErdLayout([n], { showAllFields: true });
108
+ expect(layout.nodes[0].visibleFields.map(f => f.name)).toEqual(['ID', 'Name', 'Email']);
109
+ expect(layout.nodes[0].hasMore).toBe(false);
110
+ });
111
+ it('shows every field when the node is in the expanded set', () => {
112
+ const n = node('u', 'core', 'Users', [
113
+ pk('u:id'),
114
+ col('u:name', 'Name'),
115
+ ]);
116
+ const layout = computeErdLayout([n], { expandedNodeIds: new Set(['u']) });
117
+ expect(layout.nodes[0].visibleFields.map(f => f.name)).toEqual(['ID', 'Name']);
118
+ expect(layout.nodes[0].hasMore).toBe(false);
119
+ });
120
+ });
121
+ describe('edges', () => {
122
+ it('creates an edge for each FK field that has a resolvable target', () => {
123
+ const nodes = [
124
+ node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),
125
+ node('r', 'core', 'Roles', [pk('r:id')]),
126
+ ];
127
+ const layout = computeErdLayout(nodes);
128
+ expect(layout.edges).toHaveLength(1);
129
+ expect(layout.edges[0].sourceId).toBe('u');
130
+ expect(layout.edges[0].targetId).toBe('r');
131
+ });
132
+ it('skips FKs whose target isn\'t in the node list', () => {
133
+ const nodes = [node('u', 'core', 'Users', [pk('u:id'), fk('u:x', 'GhostID', 'ghost')])];
134
+ const layout = computeErdLayout(nodes);
135
+ expect(layout.edges).toEqual([]);
136
+ });
137
+ it('produces a 4-point orthogonal path for a cross-schema edge', () => {
138
+ const nodes = [
139
+ node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),
140
+ node('r', 'ai', 'Roles', [pk('r:id')]),
141
+ ];
142
+ const layout = computeErdLayout(nodes, { schemaOrder: ['core', 'ai'] });
143
+ expect(layout.edges[0].points).toHaveLength(4);
144
+ expect(layout.edges[0].selfReference).toBe(false);
145
+ expect(layout.edges[0].goingRight).toBe(true);
146
+ });
147
+ it('produces a 5-point loop path for a self-reference', () => {
148
+ const nodes = [
149
+ node('e', 'core', 'Employees', [pk('e:id'), fk('e:sup', 'SupervisorID', 'e')]),
150
+ ];
151
+ const layout = computeErdLayout(nodes);
152
+ expect(layout.edges).toHaveLength(1);
153
+ expect(layout.edges[0].selfReference).toBe(true);
154
+ expect(layout.edges[0].points).toHaveLength(5);
155
+ });
156
+ });
157
+ describe('schemaOrder override', () => {
158
+ it('honors explicit schema ordering', () => {
159
+ const nodes = [
160
+ node('z', 'zzz', 'Z', [pk('z:id')]),
161
+ node('a', 'aaa', 'A', [pk('a:id')]),
162
+ ];
163
+ const layout = computeErdLayout(nodes, { schemaOrder: ['zzz', 'aaa'] });
164
+ expect(layout.bands.map(b => b.schemaName)).toEqual(['zzz', 'aaa']);
165
+ });
166
+ it('appends schemas not mentioned in schemaOrder', () => {
167
+ const nodes = [
168
+ node('x', 'x', 'X', [pk('x:id')]),
169
+ node('y', 'y', 'Y', [pk('y:id')]),
170
+ ];
171
+ const layout = computeErdLayout(nodes, { schemaOrder: ['y'] });
172
+ expect(layout.bands.map(b => b.schemaName)).toEqual(['y', 'x']);
173
+ });
174
+ });
175
+ });
176
+ describe('pointsToPath', () => {
177
+ it('builds an SVG M/L path string', () => {
178
+ const d = pointsToPath([[0, 0], [10, 0], [10, 10]]);
179
+ expect(d).toBe('M0 0 L10 0 L10 10');
180
+ });
181
+ it('returns empty string for empty points', () => {
182
+ expect(pointsToPath([])).toBe('');
183
+ });
184
+ });
185
+ describe('getNeighbors', () => {
186
+ it('returns just the node id when no relationships exist', () => {
187
+ const nodes = [node('a', 'x', 'A', [pk('a:id')])];
188
+ expect([...getNeighbors(nodes, 'a')]).toEqual(['a']);
189
+ });
190
+ it('includes nodes referenced via outgoing FK', () => {
191
+ const nodes = [
192
+ node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),
193
+ node('r', 'core', 'Roles', [pk('r:id')]),
194
+ ];
195
+ const set = getNeighbors(nodes, 'u');
196
+ expect(set.has('r')).toBe(true);
197
+ });
198
+ it('includes nodes that reference the target via incoming FK', () => {
199
+ const nodes = [
200
+ node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),
201
+ node('r', 'core', 'Roles', [pk('r:id')]),
202
+ ];
203
+ const set = getNeighbors(nodes, 'r');
204
+ expect(set.has('u')).toBe(true);
205
+ });
206
+ });
207
+ //# sourceMappingURL=compute-erd-layout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-erd-layout.test.js","sourceRoot":"","sources":["../../src/__tests__/compute-erd-layout.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport { computeErdLayout, pointsToPath, getNeighbors } from '../lib/layout/compute-erd-layout';\nimport type { ERDNode } from '../lib/interfaces/erd-types';\n\nconst pk = (id: string, name = 'ID') => ({ id, name, type: 'uniqueidentifier', isPrimaryKey: true });\nconst fk = (id: string, name: string, targetId: string) => ({\n id, name, type: 'uniqueidentifier', isPrimaryKey: false, relatedNodeId: targetId,\n});\nconst col = (id: string, name: string) => ({ id, name, type: 'nvarchar', isPrimaryKey: false });\n\nconst node = (id: string, schema: string | undefined, name: string, fields: ERDNode['fields']): ERDNode => ({\n id, name, schemaName: schema, fields,\n});\n\ndescribe('computeErdLayout', () => {\n\n describe('empty input', () => {\n it('returns empty layout for no nodes', () => {\n const layout = computeErdLayout([]);\n expect(layout.nodes).toEqual([]);\n expect(layout.edges).toEqual([]);\n expect(layout.bands).toEqual([]);\n });\n });\n\n describe('single node', () => {\n it('creates one node in one band', () => {\n const n = node('u', 'core', 'Users', [pk('u:id')]);\n const layout = computeErdLayout([n]);\n expect(layout.nodes).toHaveLength(1);\n expect(layout.bands).toHaveLength(1);\n expect(layout.bands[0].schemaName).toBe('core');\n expect(layout.nodes[0].id).toBe('u');\n expect(layout.nodes[0].width).toBeGreaterThan(0);\n expect(layout.nodes[0].height).toBeGreaterThan(0);\n });\n\n it('uses the synthetic default schema when schemaName is missing', () => {\n const n = node('u', undefined, 'Users', [pk('u:id')]);\n const layout = computeErdLayout([n]);\n expect(layout.bands).toHaveLength(1);\n expect(layout.bands[0].schemaName).toBe('_');\n });\n });\n\n describe('column layout rules', () => {\n const make = (count: number, schema = 'core'): ERDNode[] =>\n Array.from({ length: count }, (_, i) => node(`${schema}-${i}`, schema, `Entity${i}`, [pk(`${i}:id`)]));\n\n it('uses 1 column when count <= 3', () => {\n const layout = computeErdLayout(make(3));\n const xs = new Set(layout.nodes.map(n => n.x));\n expect(xs.size).toBe(1);\n });\n\n it('uses 2 columns when count is between 4 and 8', () => {\n const layout = computeErdLayout(make(6));\n const xs = new Set(layout.nodes.map(n => n.x));\n expect(xs.size).toBe(2);\n });\n\n it('uses 3 columns when count > 8', () => {\n const layout = computeErdLayout(make(12));\n const xs = new Set(layout.nodes.map(n => n.x));\n expect(xs.size).toBe(3);\n });\n });\n\n describe('schema bands', () => {\n it('creates one band per distinct schema', () => {\n const nodes = [\n node('a', 'core', 'A', [pk('a:id')]),\n node('b', 'ai', 'B', [pk('b:id')]),\n node('c', 'core', 'C', [pk('c:id')]),\n ];\n const layout = computeErdLayout(nodes, { schemaOrder: ['core', 'ai'] });\n expect(layout.bands.map(b => b.schemaName)).toEqual(['core', 'ai']);\n });\n\n it('aligns all band heights to the tallest', () => {\n const nodes = [\n node('a', 'core', 'A', [pk('a:id')]),\n node('b', 'core', 'B', [pk('b:id')]),\n node('c', 'core', 'C', [pk('c:id')]),\n node('d', 'core', 'D', [pk('d:id')]),\n node('e', 'ai', 'E', [pk('e:id')]),\n ];\n const layout = computeErdLayout(nodes);\n const heights = new Set(layout.bands.map(b => b.height));\n expect(heights.size).toBe(1);\n });\n\n it('sorts entities alphabetically within a band', () => {\n const nodes = [\n node('a', 'core', 'Charlie', [pk('c:id')]),\n node('b', 'core', 'Alpha', [pk('a:id')]),\n node('c', 'core', 'Bravo', [pk('b:id')]),\n ];\n const layout = computeErdLayout(nodes);\n expect(layout.nodes.map(n => n.name)).toEqual(['Alpha', 'Bravo', 'Charlie']);\n });\n });\n\n describe('field visibility', () => {\n it('hides non-PK/FK fields by default (keys-only view)', () => {\n const n = node('u', 'core', 'Users', [\n pk('u:id'),\n col('u:name', 'Name'),\n col('u:email', 'Email'),\n fk('u:role', 'RoleID', 'r'),\n ]);\n const layout = computeErdLayout([n]);\n const visible = layout.nodes[0].visibleFields.map(f => f.name);\n expect(visible).toEqual(['ID', 'RoleID']);\n expect(layout.nodes[0].hasMore).toBe(true);\n });\n\n it('shows every field when showAllFields is true', () => {\n const n = node('u', 'core', 'Users', [\n pk('u:id'),\n col('u:name', 'Name'),\n col('u:email', 'Email'),\n ]);\n const layout = computeErdLayout([n], { showAllFields: true });\n expect(layout.nodes[0].visibleFields.map(f => f.name)).toEqual(['ID', 'Name', 'Email']);\n expect(layout.nodes[0].hasMore).toBe(false);\n });\n\n it('shows every field when the node is in the expanded set', () => {\n const n = node('u', 'core', 'Users', [\n pk('u:id'),\n col('u:name', 'Name'),\n ]);\n const layout = computeErdLayout([n], { expandedNodeIds: new Set(['u']) });\n expect(layout.nodes[0].visibleFields.map(f => f.name)).toEqual(['ID', 'Name']);\n expect(layout.nodes[0].hasMore).toBe(false);\n });\n });\n\n describe('edges', () => {\n it('creates an edge for each FK field that has a resolvable target', () => {\n const nodes = [\n node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),\n node('r', 'core', 'Roles', [pk('r:id')]),\n ];\n const layout = computeErdLayout(nodes);\n expect(layout.edges).toHaveLength(1);\n expect(layout.edges[0].sourceId).toBe('u');\n expect(layout.edges[0].targetId).toBe('r');\n });\n\n it('skips FKs whose target isn\\'t in the node list', () => {\n const nodes = [node('u', 'core', 'Users', [pk('u:id'), fk('u:x', 'GhostID', 'ghost')])];\n const layout = computeErdLayout(nodes);\n expect(layout.edges).toEqual([]);\n });\n\n it('produces a 4-point orthogonal path for a cross-schema edge', () => {\n const nodes = [\n node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),\n node('r', 'ai', 'Roles', [pk('r:id')]),\n ];\n const layout = computeErdLayout(nodes, { schemaOrder: ['core', 'ai'] });\n expect(layout.edges[0].points).toHaveLength(4);\n expect(layout.edges[0].selfReference).toBe(false);\n expect(layout.edges[0].goingRight).toBe(true);\n });\n\n it('produces a 5-point loop path for a self-reference', () => {\n const nodes = [\n node('e', 'core', 'Employees', [pk('e:id'), fk('e:sup', 'SupervisorID', 'e')]),\n ];\n const layout = computeErdLayout(nodes);\n expect(layout.edges).toHaveLength(1);\n expect(layout.edges[0].selfReference).toBe(true);\n expect(layout.edges[0].points).toHaveLength(5);\n });\n });\n\n describe('schemaOrder override', () => {\n it('honors explicit schema ordering', () => {\n const nodes = [\n node('z', 'zzz', 'Z', [pk('z:id')]),\n node('a', 'aaa', 'A', [pk('a:id')]),\n ];\n const layout = computeErdLayout(nodes, { schemaOrder: ['zzz', 'aaa'] });\n expect(layout.bands.map(b => b.schemaName)).toEqual(['zzz', 'aaa']);\n });\n\n it('appends schemas not mentioned in schemaOrder', () => {\n const nodes = [\n node('x', 'x', 'X', [pk('x:id')]),\n node('y', 'y', 'Y', [pk('y:id')]),\n ];\n const layout = computeErdLayout(nodes, { schemaOrder: ['y'] });\n expect(layout.bands.map(b => b.schemaName)).toEqual(['y', 'x']);\n });\n });\n});\n\ndescribe('pointsToPath', () => {\n it('builds an SVG M/L path string', () => {\n const d = pointsToPath([[0, 0], [10, 0], [10, 10]]);\n expect(d).toBe('M0 0 L10 0 L10 10');\n });\n\n it('returns empty string for empty points', () => {\n expect(pointsToPath([])).toBe('');\n });\n});\n\ndescribe('getNeighbors', () => {\n it('returns just the node id when no relationships exist', () => {\n const nodes = [node('a', 'x', 'A', [pk('a:id')])];\n expect([...getNeighbors(nodes, 'a')]).toEqual(['a']);\n });\n\n it('includes nodes referenced via outgoing FK', () => {\n const nodes = [\n node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),\n node('r', 'core', 'Roles', [pk('r:id')]),\n ];\n const set = getNeighbors(nodes, 'u');\n expect(set.has('r')).toBe(true);\n });\n\n it('includes nodes that reference the target via incoming FK', () => {\n const nodes = [\n node('u', 'core', 'Users', [pk('u:id'), fk('u:r', 'RoleID', 'r')]),\n node('r', 'core', 'Roles', [pk('r:id')]),\n ];\n const set = getNeighbors(nodes, 'r');\n expect(set.has('u')).toBe(true);\n });\n});\n"]}
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter, OnChanges, SimpleChanges, ElementRef } from '@angular/core';
2
2
  import { EntityInfo, EntityFieldInfo, EntityFieldValueInfo } from '@memberjunction/core';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
4
  import * as i0 from "@angular/core";
4
5
  /**
5
6
  * Event emitted when requesting to open an entity record.
@@ -15,7 +16,7 @@ export interface EntityDetailsOpenRecordEvent {
15
16
  * This component is designed to be used alongside the ERD diagram to provide
16
17
  * a detailed view of the currently selected entity.
17
18
  */
18
- export declare class EntityDetailsComponent implements OnChanges {
19
+ export declare class EntityDetailsComponent extends BaseAngularComponent implements OnChanges {
19
20
  fieldsListContainer: ElementRef;
20
21
  relationshipsListContainer: ElementRef;
21
22
  /** The currently selected entity to display details for */
@@ -1 +1 @@
1
- {"version":3,"file":"entity-details.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/entity-details/entity-details.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,oBAAoB,EAAY,MAAM,sBAAsB,CAAC;;AAGnG;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAMa,sBAAuB,YAAW,SAAS;IACD,mBAAmB,EAAG,UAAU,CAAC;IAC1B,0BAA0B,EAAG,UAAU,CAAC;IAEpG,2DAA2D;IAClD,cAAc,EAAE,UAAU,GAAG,IAAI,CAAQ;IAElD,yDAAyD;IAChD,eAAe,EAAE,eAAe,EAAE,CAAM;IAEjD,6CAA6C;IACpC,qBAAqB,UAAQ;IAEtC,oDAAoD;IAC3C,4BAA4B,UAAQ;IAE7C,yDAAyD;IAC/C,UAAU,2BAAkC;IAEtD,gDAAgD;IACtC,UAAU,qBAA4B;IAEhD,6CAA6C;IACnC,mBAAmB,qBAA4B;IAEzD,oDAAoD;IAC1C,0BAA0B,qBAA4B;IAEhE,gFAAgF;IACtE,cAAc,2BAAkC;IAE1D,uDAAuD;IAC7C,UAAU,6CAAoD;IAEjE,WAAW,EAAE,KAAK,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,CAAS;IACjE,yBAAyB,cAAqB;IAC9C,mBAAmB,cAAqB;IACxC,oBAAoB,cAAqB;IAChD,OAAO,CAAC,wBAAwB,CAAuB;IAEvD,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAczC,OAAO,CAAC,oBAAoB;IAYrB,YAAY,IAAI,IAAI;IASpB,YAAY,IAAI,IAAI;IAIpB,mBAAmB,IAAI,IAAI;IAI3B,0BAA0B,IAAI,IAAI;IAIlC,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,IAAI;IAIzE,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE;IAiBpD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IA+BlD,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI1C,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ7C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQxC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQzC,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIpD,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI/C,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIhD,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAIvD,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE;IAKxD,0BAA0B,CAAC,KAAK,EAAE,eAAe,GAAG,oBAAoB,EAAE;IAU1E,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAYhE,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,OAAe,GAAG,IAAI;yCAlN5D,sBAAsB;2CAAtB,sBAAsB;CAqNlC"}
1
+ {"version":3,"file":"entity-details.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/entity-details/entity-details.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAMa,sBAAuB,SAAQ,oBAAqB,YAAW,SAAS;IAC9B,mBAAmB,EAAG,UAAU,CAAC;IAC1B,0BAA0B,EAAG,UAAU,CAAC;IAEpG,2DAA2D;IAClD,cAAc,EAAE,UAAU,GAAG,IAAI,CAAQ;IAElD,yDAAyD;IAChD,eAAe,EAAE,eAAe,EAAE,CAAM;IAEjD,6CAA6C;IACpC,qBAAqB,UAAQ;IAEtC,oDAAoD;IAC3C,4BAA4B,UAAQ;IAE7C,yDAAyD;IAC/C,UAAU,2BAAkC;IAEtD,gDAAgD;IACtC,UAAU,qBAA4B;IAEhD,6CAA6C;IACnC,mBAAmB,qBAA4B;IAEzD,oDAAoD;IAC1C,0BAA0B,qBAA4B;IAEhE,gFAAgF;IACtE,cAAc,2BAAkC;IAE1D,uDAAuD;IAC7C,UAAU,6CAAoD;IAEjE,WAAW,EAAE,KAAK,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,CAAS;IACjE,yBAAyB,cAAqB;IAC9C,mBAAmB,cAAqB;IACxC,oBAAoB,cAAqB;IAChD,OAAO,CAAC,wBAAwB,CAAuB;IAEvD,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAczC,OAAO,CAAC,oBAAoB;IAYrB,YAAY,IAAI,IAAI;IASpB,YAAY,IAAI,IAAI;IAIpB,mBAAmB,IAAI,IAAI;IAI3B,0BAA0B,IAAI,IAAI;IAIlC,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,IAAI;IAIzE,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE;IAiBpD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IA+BlD,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI1C,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ7C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQxC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQzC,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIpD,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI/C,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIhD,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAIvD,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE;IAKxD,0BAA0B,CAAC,KAAK,EAAE,eAAe,GAAG,oBAAoB,EAAE;IAU1E,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAYhE,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,OAAe,GAAG,IAAI;yCAlN5D,sBAAsB;2CAAtB,sBAAsB;CAqNlC"}
@@ -1,6 +1,6 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
- import { Metadata } from '@memberjunction/core';
3
2
  import { UUIDsEqual } from '@memberjunction/global';
3
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
4
4
  import * as i0 from "@angular/core";
5
5
  const _c0 = ["fieldsListContainer"];
6
6
  const _c1 = ["relationshipsListContainer"];
@@ -405,7 +405,7 @@ function EntityDetailsComponent_Conditional_38_Template(rf, ctx) { if (rf & 1) {
405
405
  * This component is designed to be used alongside the ERD diagram to provide
406
406
  * a detailed view of the currently selected entity.
407
407
  */
408
- export class EntityDetailsComponent {
408
+ export class EntityDetailsComponent extends BaseAngularComponent {
409
409
  fieldsListContainer;
410
410
  relationshipsListContainer;
411
411
  /** The currently selected entity to display details for */
@@ -505,7 +505,7 @@ export class EntityDetailsComponent {
505
505
  // Remove the current entity from the set (don't return self-references)
506
506
  relatedEntityIds.delete(entityId);
507
507
  // Convert to actual EntityInfo objects
508
- const md = new Metadata();
508
+ const md = this.ProviderToUse;
509
509
  const allEntities = md.Entities;
510
510
  const retVals = [];
511
511
  relatedEntityIds.forEach(id => {
@@ -574,7 +574,7 @@ export class EntityDetailsComponent {
574
574
  event.stopPropagation();
575
575
  if (field.RelatedEntityID) {
576
576
  // Find the related entity and select it in the ERD
577
- const md = new Metadata();
577
+ const md = this.ProviderToUse;
578
578
  const relatedEntity = md.Entities.find(e => UUIDsEqual(e.ID, field.RelatedEntityID));
579
579
  if (relatedEntity) {
580
580
  this.entitySelected.emit(relatedEntity);
@@ -584,14 +584,14 @@ export class EntityDetailsComponent {
584
584
  selectEntity(entity, _zoomTo = false) {
585
585
  this.entitySelected.emit(entity);
586
586
  }
587
- static ɵfac = function EntityDetailsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || EntityDetailsComponent)(); };
587
+ static ɵfac = /*@__PURE__*/ (() => { let ɵEntityDetailsComponent_BaseFactory; return function EntityDetailsComponent_Factory(__ngFactoryType__) { return (ɵEntityDetailsComponent_BaseFactory || (ɵEntityDetailsComponent_BaseFactory = i0.ɵɵgetInheritedFactory(EntityDetailsComponent)))(__ngFactoryType__ || EntityDetailsComponent); }; })();
588
588
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityDetailsComponent, selectors: [["mj-entity-details"]], viewQuery: function EntityDetailsComponent_Query(rf, ctx) { if (rf & 1) {
589
589
  i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
590
590
  } if (rf & 2) {
591
591
  let _t;
592
592
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fieldsListContainer = _t.first);
593
593
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.relationshipsListContainer = _t.first);
594
- } }, inputs: { selectedEntity: "selectedEntity", allEntityFields: "allEntityFields", fieldsSectionExpanded: "fieldsSectionExpanded", relationshipsSectionExpanded: "relationshipsSectionExpanded" }, outputs: { openEntity: "openEntity", closePanel: "closePanel", fieldsSectionToggle: "fieldsSectionToggle", relationshipsSectionToggle: "relationshipsSectionToggle", entitySelected: "entitySelected", openRecord: "openRecord" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 39, vars: 21, consts: [["fieldsListContainer", ""], ["relationshipsListContainer", ""], [1, "details-panel"], [1, "panel-header"], [1, "panel-actions"], ["title", "Open Entity Record", 1, "open-btn", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "entity-info"], [1, "info-row"], [1, "fields-section"], [1, "section-header", "extra-padding"], [1, "section-title-group", 3, "click"], ["title", "Toggle fields section", 1, "expand-btn"], [1, "fa-solid", "fa-chevron-right"], [1, "field-filters"], [1, "fields-list"], [1, "relationships-section"], ["title", "Toggle relationships section", 1, "expand-btn"], [1, "related-entities-list"], ["title", "Show all fields", 1, "filter-btn", 3, "click"], ["title", "Show primary keys and ID fields", 1, "filter-btn", 3, "click"], ["title", "Show foreign key fields only", 1, "filter-btn", 3, "click"], ["title", "Show regular data fields", 1, "filter-btn", 3, "click"], [1, "field-item", 3, "class", "title"], [1, "field-item", 3, "click", "title"], [1, "field-header"], [1, "field-name"], ["title", "Primary Key", 1, "field-icon", "fa-solid", "fa-key"], ["title", "Foreign Key", 1, "field-icon", "fa-solid", "fa-link"], [1, "field-actions"], ["title", "Toggle possible values", 1, "field-values-btn", 3, "expanded"], ["title", "Toggle field description", 1, "field-info-btn", 3, "expanded"], [1, "field-badges"], [1, "field-badge", "primary-key"], [1, "field-badge", "foreign-key"], [1, "field-details"], [1, "field-type"], [1, "field-relation"], [1, "field-description"], [1, "field-values"], [1, "field-comprehensive-details"], ["title", "Toggle possible values", 1, "field-values-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["title", "Toggle field description", 1, "field-info-btn", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-arrow-right"], [1, "description-text"], [1, "values-header"], [1, "values-list"], [1, "value-tag"], [1, "comprehensive-description-top"], [1, "field-values-comprehensive"], [1, "details-grid"], [1, "detail-row"], [1, "detail-label"], [1, "detail-value"], [1, "description-content"], [1, "values-grid"], [1, "value-item"], [1, "value-main"], [1, "value-text"], [1, "value-code"], [1, "value-description"], [1, "detail-value", "default-value"], [1, "detail-value", "related-entity", 3, "click", "title"], [1, "detail-value", "auto-increment"], [1, "related-entity-item"], [1, "related-entity-item", 3, "click"], [1, "fa-solid", "fa-database"], [1, "entity-name"], ["title", "Click to zoom to entity", 1, "zoom-indicator", "fa-solid", "fa-search-plus"]], template: function EntityDetailsComponent_Template(rf, ctx) { if (rf & 1) {
594
+ } }, inputs: { selectedEntity: "selectedEntity", allEntityFields: "allEntityFields", fieldsSectionExpanded: "fieldsSectionExpanded", relationshipsSectionExpanded: "relationshipsSectionExpanded" }, outputs: { openEntity: "openEntity", closePanel: "closePanel", fieldsSectionToggle: "fieldsSectionToggle", relationshipsSectionToggle: "relationshipsSectionToggle", entitySelected: "entitySelected", openRecord: "openRecord" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 39, vars: 21, consts: [["fieldsListContainer", ""], ["relationshipsListContainer", ""], [1, "details-panel"], [1, "panel-header"], [1, "panel-actions"], ["title", "Open Entity Record", 1, "open-btn", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "entity-info"], [1, "info-row"], [1, "fields-section"], [1, "section-header", "extra-padding"], [1, "section-title-group", 3, "click"], ["title", "Toggle fields section", 1, "expand-btn"], [1, "fa-solid", "fa-chevron-right"], [1, "field-filters"], [1, "fields-list"], [1, "relationships-section"], ["title", "Toggle relationships section", 1, "expand-btn"], [1, "related-entities-list"], ["title", "Show all fields", 1, "filter-btn", 3, "click"], ["title", "Show primary keys and ID fields", 1, "filter-btn", 3, "click"], ["title", "Show foreign key fields only", 1, "filter-btn", 3, "click"], ["title", "Show regular data fields", 1, "filter-btn", 3, "click"], [1, "field-item", 3, "class", "title"], [1, "field-item", 3, "click", "title"], [1, "field-header"], [1, "field-name"], ["title", "Primary Key", 1, "field-icon", "fa-solid", "fa-key"], ["title", "Foreign Key", 1, "field-icon", "fa-solid", "fa-link"], [1, "field-actions"], ["title", "Toggle possible values", 1, "field-values-btn", 3, "expanded"], ["title", "Toggle field description", 1, "field-info-btn", 3, "expanded"], [1, "field-badges"], [1, "field-badge", "primary-key"], [1, "field-badge", "foreign-key"], [1, "field-details"], [1, "field-type"], [1, "field-relation"], [1, "field-description"], [1, "field-values"], [1, "field-comprehensive-details"], ["title", "Toggle possible values", 1, "field-values-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["title", "Toggle field description", 1, "field-info-btn", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-arrow-right"], [1, "description-text"], [1, "values-header"], [1, "values-list"], [1, "value-tag"], [1, "comprehensive-description-top"], [1, "field-values-comprehensive"], [1, "details-grid"], [1, "detail-row"], [1, "detail-label"], [1, "detail-value"], [1, "description-content"], [1, "values-grid"], [1, "value-item"], [1, "value-main"], [1, "value-text"], [1, "value-code"], [1, "value-description"], [1, "detail-value", "default-value"], [1, "detail-value", "related-entity", 3, "click", "title"], [1, "detail-value", "auto-increment"], [1, "related-entity-item"], [1, "related-entity-item", 3, "click"], [1, "fa-solid", "fa-database"], [1, "entity-name"], ["title", "Click to zoom to entity", 1, "zoom-indicator", "fa-solid", "fa-search-plus"]], template: function EntityDetailsComponent_Template(rf, ctx) { if (rf & 1) {
595
595
  i0.ɵɵelementStart(0, "div", 2)(1, "div", 3)(2, "h3");
596
596
  i0.ɵɵtext(3);
597
597
  i0.ɵɵelementEnd();
@@ -699,5 +699,5 @@ export class EntityDetailsComponent {
699
699
  }], openRecord: [{
700
700
  type: Output
701
701
  }] }); })();
702
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityDetailsComponent, { className: "EntityDetailsComponent", filePath: "src/lib/components/entity-details/entity-details.component.ts", lineNumber: 26 }); })();
702
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityDetailsComponent, { className: "EntityDetailsComponent", filePath: "src/lib/components/entity-details/entity-details.component.ts", lineNumber: 27 }); })();
703
703
  //# sourceMappingURL=entity-details.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity-details.component.js","sourceRoot":"","sources":["../../../../src/lib/components/entity-details/entity-details.component.ts","../../../../src/lib/components/entity-details/entity-details.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAA4B,SAAS,EAAc,MAAM,eAAe,CAAC;AACxH,OAAO,EAAqD,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;;;ICuB5C,AADF,+BAAsB,YACb;IAAA,4BAAY;IAAA,iBAAQ;IAC3B,4BAAM;IAAA,YAAiC;IACzC,AADyC,iBAAO,EAC1C;;;IADE,eAAiC;IAAjC,8FAAiC;;;;IAkBrC,AADF,+BAA2B,iBAKC;IADxB,2LAAS,sBAAe,KAAK,CAAC,KAAC;IAE/B,qBACF;IAAA,iBAAS;IACT,kCAI0C;IADxC,2LAAS,sBAAe,MAAM,CAAC,KAAC;IAEhC,sBACF;IAAA,iBAAS;IACT,kCAIuC;IADrC,2LAAS,sBAAe,cAAc,CAAC,KAAC;IAExC,qBACF;IAAA,iBAAS;IACT,kCAImC;IADjC,2LAAS,sBAAe,SAAS,CAAC,KAAC;IAEnC,yBACF;IACF,AADE,iBAAS,EACL;;;IA1BF,cAAsC;IAAtC,sDAAsC;IAOtC,eAAuC;IAAvC,uDAAuC;IAOvC,eAA+C;IAA/C,+DAA+C;IAO/C,eAA0C;IAA1C,0DAA0C;;;IAuBpC,2BAAoE;;;IAEpE,2BAAqE;;;;IAMrE,kCAIiC;IAF/B,+PAAS,qCAA2B,KAAC;IAGrC,2BAAsC;IACxC,iBAAS;;;;IAHP,qEAAkD;;;;IAMpD,kCAImC;IAFjC,+PAAS,0CAAgC,KAAC;IAG1C,2BAA6C;IAC/C,iBAAS;;;;IAHP,0EAAuD;;;IAOvD,gCAAsC;IAAA,kBAAE;IAAA,iBAAO;;;IAG/C,gCAAsC;IAAA,kBAAE;IAAA,iBAAO;;;IAQnD,+BAA4B;IAC1B,2BAA6C;IAC7C,gCACF;IAAA,iBAAM;;;IAKN,AADF,+BAA+B,cACC;IAAA,YAAuB;IACvD,AADuD,iBAAM,EACvD;;;IAD0B,eAAuB;IAAvB,0CAAuB;;;IAQjD,gCAAwB;IAAA,YAAW;IAAA,iBAAO;;;IAAlB,cAAW;IAAX,8BAAW;;;IAHvC,AADF,+BAA0B,cACG;IAAA,gCAAgB;IAAA,iBAAM;IACjD,+BAAyB;IACvB,iJAEC;IAEL,AADE,iBAAM,EACF;;;;IAJF,eAEC;IAFD,cAAA,uCAA6B,CAE5B;;;IAQC,AADF,+BAA2C,cACR;IAAA,YAAuB;IAC1D,AAD0D,iBAAM,EAC1D;;;IAD6B,eAAuB;IAAvB,0CAAuB;;;IAe9C,gCAAyB;IAAA,YAAuB;IAAA,iBAAO;;;IAA9B,cAAuB;IAAvB,mDAAuB;;;IAIlD,+BAA+B;IAAA,YAA4B;IAAA,iBAAM;;;IAAlC,cAA4B;IAA5B,+CAA4B;;;IAN3D,AADF,AADF,+BAAwB,cACE,eACG;IAAA,YAAsB;IAAA,iBAAO;IACtD,kJAA+D;IAGjE,iBAAM;IACN,iJAA6E;IAG/E,iBAAM;;;IARuB,eAAsB;IAAtB,yCAAsB;IAC/C,cAEC;IAFD,2FAEC;IAEH,cAEC;IAFD,yGAEC;;;IAfP,AADF,+BAAwC,cACX;IACzB,2BAAsC;IACtC,YACF;IAAA,iBAAM;IACN,+BAAyB;IACvB,4IAYC;IAEL,AADE,iBAAM,EACF;;;;IAjBF,eACF;IADE,oFACF;IAEE,eAYC;IAZD,cAAA,2CAAiC,CAYhC;;;IAiBD,AADF,+BAAwB,eACK;IAAA,2BAAW;IAAA,iBAAO;IAC7C,gCAA2B;IAAA,YAAkB;IAC/C,AAD+C,iBAAO,EAChD;;;IADuB,eAAkB;IAAlB,qCAAkB;;;IAK7C,AADF,+BAAwB,eACK;IAAA,0BAAU;IAAA,iBAAO;IAC5C,gCAA2B;IAAA,YAAqB;IAClD,AADkD,iBAAO,EACnD;;;IADuB,eAAqB;IAArB,wCAAqB;;;IAKhD,AADF,+BAAwB,eACK;IAAA,sBAAM;IAAA,iBAAO;IACxC,gCAA2B;IAAA,YAAiB;IAC9C,AAD8C,iBAAO,EAC/C;;;IADuB,eAAiB;IAAjB,oCAAiB;;;IAW5C,AADF,+BAAwB,eACK;IAAA,8BAAc;IAAA,iBAAO;IAChD,gCAAyC;IAAA,YAAwB;IACnE,AADmE,iBAAO,EACpE;;;IADqC,eAAwB;IAAxB,2CAAwB;;;;IAKjE,AADF,+BAAwB,eACK;IAAA,+BAAe;IAAA,iBAAO;IACjD,gCAE+D;IADzD,oRAAS,6CAAmC,KAAC;IAEjD,YACA;IAAA,2BAA6C;IAEjD,AADE,iBAAO,EACH;;;IAJE,eAAwD;IAAxD,uBAAA,wEAAwD,CAAA;IAC5D,cACA;IADA,uDACA;;;IAMF,AADF,+BAAwB,eACK;IAAA,+BAAe;IAAA,iBAAO;IACjD,gCAA0C;IAAA,mBAAG;IAC/C,AAD+C,iBAAO,EAChD;;;IArFZ,+BAAyC;IACvC,6HAAyB;IAKzB,6HAAqE;IAyBjE,AADF,AADF,+BAA0B,cACA,eACK;IAAA,0BAAU;IAAA,iBAAO;IAC5C,gCAA2B;IAAA,YAAgB;IAC7C,AAD6C,iBAAO,EAC9C;IAEJ,AADF,+BAAwB,gBACK;IAAA,0BAAS;IAAA,iBAAO;IAC3C,iCAAuF;IACrF,aACF;IACF,AADE,iBAAO,EACH;IACN,+HAAwC;IAMxC,+HAA8C;IAM9C,+HAAsC;IAOpC,AADF,gCAAwB,gBACK;IAAA,+BAAc;IAAA,iBAAO;IAChD,iCAAoF;IAClF,aACF;IACF,AADE,iBAAO,EACH;IACN,+HAA0B;IAM1B,+HAA6B;IAW7B,+HAA2B;IAO/B,AADE,iBAAM,EACF;;;IAvFJ,cAIC;IAJD,+CAIC;IACD,cAsBC;IAtBD,8FAsBC;IAI8B,eAAgB;IAAhB,mCAAgB;IAIhB,eAA2D;IAA3D,mEAA2D;IACpF,cACF;IADE,mEACF;IAEF,cAKC;IALD,kEAKC;IACD,cAKC;IALD,wEAKC;IACD,cAKC;IALD,gEAKC;IAG4B,eAAwD;IAAxD,gEAAwD;IACjF,cACF;IADE,kEACF;IAEF,cAKC;IALD,iDAKC;IACD,cAUC;IAVD,oDAUC;IACD,cAKC;IALD,kDAKC;;;;IA9JT,+BAQ+D;IAD1D,0NAAS,6BAAmB,KAAC;IAG9B,AADF,+BAA0B,cACA;IAGpB,AAFF,+GAA0B,yFAEU;IAGpC,YACF;IAAA,iBAAM;IACN,+BAA2B;IACzB,iHAAqC;IASrC,iHAAyB;IASzB,+BAA0B;IACxB,iHAA0B;IAG1B,iHAAoD;IAK1D,AADE,AADE,iBAAM,EACF,EACF;IAEJ,AADF,gCAA2B,eACD;IAAA,aAAgB;IAAA,iBAAM;IAC9C,gHAA6B;IAM/B,iBAAM;IACN,gHAAiE;IAKjE,gHAAwE;IAUxE,kHAAwC;IA2F1C,iBAAM;;;;IAjKD,sNAKE;IAEF,0EAAyD;IAGxD,eAIC;IAJD,+EAIC;IACD,eACF;IADE,8CACF;IAEE,eAQC;IARD,kEAQC;IACD,cAQC;IARD,+CAQC;IAEC,eAEC;IAFD,iDAEC;IACD,cAEC;IAFD,8EAEC;IAKmB,eAAgB;IAAhB,mCAAgB;IACxC,cAKC;IALD,oDAKC;IAEH,cAIC;IAJD,kGAIC;IACD,cASC;IATD,gHASC;IACD,cA0FC;IA1FD,sEA0FC;;;IAnKP,kCAA8C;IAC5C,2GAoKC;IACH,iBAAM;;;IArKJ,eAoKC;IApKD,cAAA,4FAAsC,EAAE,CAAC,CAoKxC;;;;IAoBC,+BAA6E;IAA5C,oOAAS,uCAA4B,IAAI,CAAC,KAAC;IAC1E,2BAA0C;IAC1C,gCAA0B;IAAA,YAAoD;IAAA,iBAAO;IACrF,2BAA4F;IAC9F,iBAAM;;;IAFsB,eAAoD;IAApD,4EAAoD;;;IAJpF,kCAA+D;IAC7D,yGAMC;IACH,iBAAM;;;IAPJ,eAMC;IAND,cAAA,+FAAyC,EAAE,CAAC,CAM3C;;AD9PT;;;;;;GAMG;AAOH,MAAM,OAAO,sBAAsB;IACoB,mBAAmB,CAAc;IAC1B,0BAA0B,CAAc;IAEpG,2DAA2D;IAClD,cAAc,GAAsB,IAAI,CAAC;IAElD,yDAAyD;IAChD,eAAe,GAAsB,EAAE,CAAC;IAEjD,6CAA6C;IACpC,qBAAqB,GAAG,IAAI,CAAC;IAEtC,oDAAoD;IAC3C,4BAA4B,GAAG,IAAI,CAAC;IAE7C,yDAAyD;IAC/C,UAAU,GAAG,IAAI,YAAY,EAAc,CAAC;IAEtD,gDAAgD;IACtC,UAAU,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEhD,6CAA6C;IACnC,mBAAmB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEzD,oDAAoD;IAC1C,0BAA0B,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEhE,gFAAgF;IACtE,cAAc,GAAG,IAAI,YAAY,EAAc,CAAC;IAE1D,uDAAuD;IAC7C,UAAU,GAAG,IAAI,YAAY,EAAgC,CAAC;IAEjE,WAAW,GAAgD,KAAK,CAAC;IACjE,yBAAyB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9C,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,wBAAwB,GAAkB,IAAI,CAAC;IAEvD,WAAW,CAAC,OAAsB;QAChC,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAC;YACxE,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,IAAI,CAAC;YAExD,mCAAmC;YACnC,IAAI,eAAe,KAAK,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBACtD,6CAA6C;gBAC7C,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAE5B,IAAI,CAAC,wBAAwB,GAAG,eAAe,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAEO,oBAAoB;QAC1B,8CAA8C;QAC9C,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,IAAI,CAAC,mBAAmB,EAAE,aAAa,EAAE,CAAC;gBAC5C,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,IAAI,CAAC,0BAA0B,EAAE,aAAa,EAAE,CAAC;gBACnD,IAAI,CAAC,0BAA0B,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAEM,YAAY;QACjB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnB,UAAU,EAAE,cAAc;gBAC1B,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAEM,mBAAmB;QACxB,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAEM,0BAA0B;QAC/B,IAAI,CAAC,0BAA0B,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAEM,cAAc,CAAC,MAAmD;QACvE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC5B,CAAC;IAEM,eAAe,CAAC,QAAgB;QACrC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEzB,IAAI,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QAEhF,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,KAAK,MAAM;gBACT,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YACnF,KAAK,cAAc;gBACjB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;YAClE,KAAK,SAAS;gBACZ,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YACnE;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAEM,kBAAkB,CAAC,QAAgB;QACxC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEzB,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE3C,0DAA0D;QAC1D,IAAI,CAAC,eAAe;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC;aAClE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,eAAgB,CAAC,CAAC,CAAC;QAE1D,0CAA0C;QAC1C,IAAI,CAAC,eAAe;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;aACpD,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAElD,wEAAwE;QACxE,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAElC,uCAAuC;QACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,EAAE,CAAC,QAAQ,CAAC;QAChC,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YAC5B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC3D,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,YAAY,CAAC,KAAsB;QACxC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAEM,sBAAsB,CAAC,OAAe;QAC3C,IAAI,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEM,iBAAiB,CAAC,OAAe;QACtC,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAEM,kBAAkB,CAAC,OAAe;QACvC,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAEM,0BAA0B,CAAC,OAAe;QAC/C,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;IAEM,qBAAqB,CAAC,OAAe;QAC1C,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAEM,sBAAsB,CAAC,OAAe;QAC3C,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAEM,sBAAsB,CAAC,KAAsB;QAClD,OAAO,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;IACvE,CAAC;IAEM,sBAAsB,CAAC,KAAsB;QAClD,IAAI,CAAC,KAAK,CAAC,iBAAiB;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IAEM,0BAA0B,CAAC,KAAsB;QACtD,IAAI,CAAC,KAAK,CAAC,iBAAiB;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3C,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACzD,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;YACjC,CAAC;YACD,OAAO,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,oBAAoB,CAAC,KAAY,EAAE,KAAsB;QAC9D,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,mDAAmD;YACnD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,aAAa,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YACrF,IAAI,aAAa,EAAE,CAAC;gBAClB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAEM,YAAY,CAAC,MAAkB,EAAE,UAAmB,KAAK;QAC9D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;gHApNU,sBAAsB;6DAAtB,sBAAsB;;;;;;;YCvB/B,AADF,AADF,8BAA2B,aACC,SACpB;YAAA,YAAwD;YAAA,iBAAK;YAE/D,AADF,8BAA2B,gBACoD;YAApD,mGAAS,kBAAc,IAAC;YAC/C,0BAAmD;YACnD,sBACF;YAAA,iBAAS;YACT,iCAAmD;YAAzB,mGAAS,kBAAc,IAAC;YAChD,0BAAuC;YAG7C,AADE,AADE,iBAAS,EACL,EACF;YAIF,AADF,AADF,+BAAyB,eACD,aACb;YAAA,wBAAO;YAAA,iBAAQ;YACtB,6BAAM;YAAA,aAAgC;YACxC,AADwC,iBAAO,EACzC;YAEJ,AADF,gCAAsB,aACb;YAAA,uBAAM;YAAA,iBAAQ;YACrB,6BAAM;YAAA,aAA+B;YACvC,AADuC,iBAAO,EACxC;YACN,2FAAmC;YAMrC,iBAAM;YAIF,AADF,AADF,gCAAgI,eACpF,eACyB;YAAhC,iGAAS,yBAAqB,IAAC;YAC9D,mCAGgC;YAC9B,4BAA+C;YACjD,iBAAS;YACT,2BAAI;YAAA,aAA6E;YACnF,AADmF,iBAAK,EAClF;YACN,2FAA6B;YAgC/B,iBAAM;YACN,2FAA6B;YAyK/B,iBAAM;YAIF,AADF,AADF,gCAAqJ,eACzG,eACgC;YAAvC,iGAAS,gCAA4B,IAAC;YACrE,mCAGuC;YACrC,4BAA+C;YACjD,iBAAS;YACT,2BAAI;YAAA,aAA0F;YAElG,AADE,AADgG,iBAAK,EAC/F,EACF;YACN,2FAAoC;YAYxC,AADE,iBAAM,EACF;;YA5QE,eAAwD;YAAxD,0JAAwD;YAepD,gBAAgC;YAAhC,uFAAgC;YAIhC,eAA+B;YAA/B,sFAA+B;YAEvC,cAKC;YALD,gGAKC;YAGyB,cAAgD;YAAC,AAAjD,6DAAgD,iDAAmD;YAKvH,eAAwC;YAAxC,qDAAwC;YAItC,eAA6E;YAA7E,kHAA6E;YAEnF,cA+BC;YA/BD,qDA+BC;YAEH,cAwKC;YAxKD,qDAwKC;YAGgC,cAAuD;YAAC,AAAxD,oEAAuD,wDAA0D;YAK5I,eAA+C;YAA/C,4DAA+C;YAI7C,eAA0F;YAA1F,+HAA0F;YAGlG,cAUC;YAVD,4DAUC;;;iFDnPQ,sBAAsB;cANlC,SAAS;6BACI,KAAK,YACP,mBAAmB;;kBAK5B,SAAS;mBAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBAClD,SAAS;mBAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBAGzD,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kFAhCI,sBAAsB","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ViewChild, ElementRef } from '@angular/core';\nimport { EntityInfo, EntityFieldInfo, EntityFieldValueInfo, Metadata } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Event emitted when requesting to open an entity record.\n */\nexport interface EntityDetailsOpenRecordEvent {\n EntityName: string;\n RecordID: string;\n}\n\n/**\n * Entity details panel component that displays detailed information about a selected entity.\n * Shows entity metadata, fields with filtering capabilities, and related entities.\n *\n * This component is designed to be used alongside the ERD diagram to provide\n * a detailed view of the currently selected entity.\n */\n@Component({\n standalone: false,\n selector: 'mj-entity-details',\n templateUrl: './entity-details.component.html',\n styleUrls: ['./entity-details.component.css']\n})\nexport class EntityDetailsComponent implements OnChanges {\n @ViewChild('fieldsListContainer', { static: false }) fieldsListContainer!: ElementRef;\n @ViewChild('relationshipsListContainer', { static: false }) relationshipsListContainer!: ElementRef;\n\n /** The currently selected entity to display details for */\n @Input() selectedEntity: EntityInfo | null = null;\n\n /** All entity fields for looking up field information */\n @Input() allEntityFields: EntityFieldInfo[] = [];\n\n /** Whether the fields section is expanded */\n @Input() fieldsSectionExpanded = true;\n\n /** Whether the relationships section is expanded */\n @Input() relationshipsSectionExpanded = true;\n\n /** Emitted when user clicks to open the entity record */\n @Output() openEntity = new EventEmitter<EntityInfo>();\n\n /** Emitted when user clicks the close button */\n @Output() closePanel = new EventEmitter<void>();\n\n /** Emitted when fields section is toggled */\n @Output() fieldsSectionToggle = new EventEmitter<void>();\n\n /** Emitted when relationships section is toggled */\n @Output() relationshipsSectionToggle = new EventEmitter<void>();\n\n /** Emitted when a related entity is selected (clicked in relationships list) */\n @Output() entitySelected = new EventEmitter<EntityInfo>();\n\n /** Emitted when requesting to open an entity record */\n @Output() openRecord = new EventEmitter<EntityDetailsOpenRecordEvent>();\n\n public fieldFilter: 'all' | 'keys' | 'foreign_keys' | 'regular' = 'all';\n public expandedFieldDescriptions = new Set<string>();\n public expandedFieldValues = new Set<string>();\n public expandedFieldDetails = new Set<string>();\n private previousSelectedEntityId: string | null = null;\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['selectedEntity'] && !changes['selectedEntity'].firstChange) {\n const currentEntityId = this.selectedEntity?.ID || null;\n\n // Check if entity actually changed\n if (currentEntityId !== this.previousSelectedEntityId) {\n // Reset scroll positions when entity changes\n this.resetScrollPositions();\n\n this.previousSelectedEntityId = currentEntityId;\n }\n }\n }\n\n private resetScrollPositions(): void {\n // Use setTimeout to ensure the DOM is updated\n setTimeout(() => {\n if (this.fieldsListContainer?.nativeElement) {\n this.fieldsListContainer.nativeElement.scrollTop = 0;\n }\n if (this.relationshipsListContainer?.nativeElement) {\n this.relationshipsListContainer.nativeElement.scrollTop = 0;\n }\n }, 0);\n }\n\n public onOpenEntity(): void {\n if (this.selectedEntity) {\n this.openRecord.emit({\n EntityName: 'MJ: Entities',\n RecordID: this.selectedEntity.ID\n });\n }\n }\n\n public onClosePanel(): void {\n this.closePanel.emit();\n }\n\n public toggleFieldsSection(): void {\n this.fieldsSectionToggle.emit();\n }\n\n public toggleRelationshipsSection(): void {\n this.relationshipsSectionToggle.emit();\n }\n\n public setFieldFilter(filter: 'all' | 'keys' | 'foreign_keys' | 'regular'): void {\n this.fieldFilter = filter;\n }\n\n public getEntityFields(entityId: string): EntityFieldInfo[] {\n if (!entityId) return [];\n\n let fields = this.allEntityFields.filter(f => UUIDsEqual(f.EntityID, entityId));\n\n switch (this.fieldFilter) {\n case 'keys':\n return fields.filter(f => f.IsPrimaryKey || f.Name.toLowerCase().includes('id'));\n case 'foreign_keys':\n return fields.filter(f => f.RelatedEntityID && !f.IsPrimaryKey);\n case 'regular':\n return fields.filter(f => !f.IsPrimaryKey && !f.RelatedEntityID);\n default:\n return fields;\n }\n }\n\n public getRelatedEntities(entityId: string): EntityInfo[] {\n if (!entityId) return [];\n\n const relatedEntityIds = new Set<string>();\n\n // Get entities that this entity references (foreign keys)\n this.allEntityFields\n .filter(f => UUIDsEqual(f.EntityID, entityId) && f.RelatedEntityID)\n .forEach(f => relatedEntityIds.add(f.RelatedEntityID!));\n\n // Get entities that reference this entity\n this.allEntityFields\n .filter(f => UUIDsEqual(f.RelatedEntityID, entityId))\n .forEach(f => relatedEntityIds.add(f.EntityID));\n\n // Remove the current entity from the set (don't return self-references)\n relatedEntityIds.delete(entityId);\n\n // Convert to actual EntityInfo objects\n const md = new Metadata();\n const allEntities = md.Entities;\n const retVals: EntityInfo[] = [];\n relatedEntityIds.forEach(id => {\n const entity = allEntities.find(e => UUIDsEqual(e.ID, id));\n if (entity) {\n retVals.push(entity);\n }\n });\n return retVals;\n }\n\n public onFieldClick(field: EntityFieldInfo): void {\n this.toggleFieldDetails(field.ID);\n }\n\n public toggleFieldDescription(fieldId: string): void {\n if (this.expandedFieldDescriptions.has(fieldId)) {\n this.expandedFieldDescriptions.delete(fieldId);\n } else {\n this.expandedFieldDescriptions.add(fieldId);\n }\n }\n\n public toggleFieldValues(fieldId: string): void {\n if (this.expandedFieldValues.has(fieldId)) {\n this.expandedFieldValues.delete(fieldId);\n } else {\n this.expandedFieldValues.add(fieldId);\n }\n }\n\n public toggleFieldDetails(fieldId: string): void {\n if (this.expandedFieldDetails.has(fieldId)) {\n this.expandedFieldDetails.delete(fieldId);\n } else {\n this.expandedFieldDetails.add(fieldId);\n }\n }\n\n public isFieldDescriptionExpanded(fieldId: string): boolean {\n return this.expandedFieldDescriptions.has(fieldId);\n }\n\n public isFieldValuesExpanded(fieldId: string): boolean {\n return this.expandedFieldValues.has(fieldId);\n }\n\n public isFieldDetailsExpanded(fieldId: string): boolean {\n return this.expandedFieldDetails.has(fieldId);\n }\n\n public hasFieldPossibleValues(field: EntityFieldInfo): boolean {\n return field.EntityFieldValues && field.EntityFieldValues.length > 0;\n }\n\n public getFieldPossibleValues(field: EntityFieldInfo): string[] {\n if (!field.EntityFieldValues) return [];\n return field.EntityFieldValues.map(v => v.Value).slice(0, 10);\n }\n\n public getSortedEntityFieldValues(field: EntityFieldInfo): EntityFieldValueInfo[] {\n if (!field.EntityFieldValues) return [];\n return field.EntityFieldValues.sort((a, b) => {\n if (a.Sequence !== undefined && b.Sequence !== undefined) {\n return a.Sequence - b.Sequence;\n }\n return a.Value.localeCompare(b.Value);\n });\n }\n\n public onRelatedEntityClick(event: Event, field: EntityFieldInfo): void {\n event.stopPropagation();\n if (field.RelatedEntityID) {\n // Find the related entity and select it in the ERD\n const md = new Metadata();\n const relatedEntity = md.Entities.find(e => UUIDsEqual(e.ID, field.RelatedEntityID));\n if (relatedEntity) {\n this.entitySelected.emit(relatedEntity);\n }\n }\n }\n\n public selectEntity(entity: EntityInfo, _zoomTo: boolean = false): void {\n this.entitySelected.emit(entity);\n }\n}\n","<div class=\"details-panel\">\n <div class=\"panel-header\">\n <h3>{{ selectedEntity?.Name || selectedEntity?.SchemaName }}</h3>\n <div class=\"panel-actions\">\n <button class=\"open-btn\" (click)=\"onOpenEntity()\" title=\"Open Entity Record\">\n <span class=\"fa-solid fa-external-link-alt\"></span>\n Open\n </button>\n <button class=\"close-btn\" (click)=\"onClosePanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n </div>\n\n <div class=\"entity-info\">\n <div class=\"info-row\">\n <label>Schema:</label>\n <span>{{ selectedEntity?.SchemaName }}</span>\n </div>\n <div class=\"info-row\">\n <label>Table:</label>\n <span>{{ selectedEntity?.BaseTable }}</span>\n </div>\n @if (selectedEntity?.Description) {\n <div class=\"info-row\">\n <label>Description:</label>\n <span>{{ selectedEntity?.Description }}</span>\n </div>\n }\n </div>\n\n <div class=\"fields-section\" [class.section-expanded]=\"fieldsSectionExpanded\" [class.section-collapsed]=\"!fieldsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleFieldsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"fieldsSectionExpanded\"\n title=\"Toggle fields section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Fields ({{ selectedEntity ? getEntityFields(selectedEntity.ID).length : 0 }})</h4>\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"field-filters\">\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'all'\"\n (click)=\"setFieldFilter('all')\"\n title=\"Show all fields\">\n All\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'keys'\"\n (click)=\"setFieldFilter('keys')\"\n title=\"Show primary keys and ID fields\">\n Keys\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'foreign_keys'\"\n (click)=\"setFieldFilter('foreign_keys')\"\n title=\"Show foreign key fields only\">\n FKs\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'regular'\"\n (click)=\"setFieldFilter('regular')\"\n title=\"Show regular data fields\">\n Regular\n </button>\n </div>\n }\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"fields-list\" #fieldsListContainer>\n @for (field of getEntityFields(selectedEntity?.ID || ''); track field.ID) {\n <div class=\"field-item\"\n [class]=\"{\n 'primary-key-field': field.IsPrimaryKey,\n 'foreign-key-field': field.RelatedEntityID && !field.IsPrimaryKey,\n 'regular-field': !field.IsPrimaryKey && !field.RelatedEntityID,\n 'field-expanded': isFieldDetailsExpanded(field.ID)\n }\"\n (click)=\"onFieldClick(field)\"\n [title]=\"'Click to see more details about ' + field.Name\">\n <div class=\"field-header\">\n <div class=\"field-name\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-icon fa-solid fa-key\" title=\"Primary Key\"></span>\n } @else if (field.RelatedEntityID) {\n <span class=\"field-icon fa-solid fa-link\" title=\"Foreign Key\"></span>\n }\n {{ field.Name }}\n </div>\n <div class=\"field-actions\">\n @if (hasFieldPossibleValues(field)) {\n <button\n class=\"field-values-btn\"\n (click)=\"toggleFieldValues(field.ID)\"\n [class.expanded]=\"isFieldValuesExpanded(field.ID)\"\n title=\"Toggle possible values\">\n <span class=\"fa-solid fa-list\"></span>\n </button>\n }\n @if (field.Description) {\n <button\n class=\"field-info-btn\"\n (click)=\"toggleFieldDescription(field.ID)\"\n [class.expanded]=\"isFieldDescriptionExpanded(field.ID)\"\n title=\"Toggle field description\">\n <span class=\"fa-solid fa-info-circle\"></span>\n </button>\n }\n <div class=\"field-badges\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-badge primary-key\">PK</span>\n }\n @if (field.RelatedEntityID && !field.IsPrimaryKey) {\n <span class=\"field-badge foreign-key\">FK</span>\n }\n </div>\n </div>\n </div>\n <div class=\"field-details\">\n <div class=\"field-type\">{{ field.Type }}</div>\n @if (field.RelatedEntityID) {\n <div class=\"field-relation\">\n <span class=\"fa-solid fa-arrow-right\"></span>\n Related Entity\n </div>\n }\n </div>\n @if (field.Description && isFieldDescriptionExpanded(field.ID)) {\n <div class=\"field-description\">\n <div class=\"description-text\">{{ field.Description }}</div>\n </div>\n }\n @if (hasFieldPossibleValues(field) && isFieldValuesExpanded(field.ID)) {\n <div class=\"field-values\">\n <div class=\"values-header\">Possible Values:</div>\n <div class=\"values-list\">\n @for (value of getFieldPossibleValues(field); track value; let i = $index) {\n <span class=\"value-tag\">{{ value }}</span>\n }\n </div>\n </div>\n }\n @if (isFieldDetailsExpanded(field.ID)) {\n <div class=\"field-comprehensive-details\">\n @if (field.Description) {\n <div class=\"comprehensive-description-top\">\n <div class=\"description-content\">{{ field.Description }}</div>\n </div>\n }\n @if (field.EntityFieldValues && field.EntityFieldValues.length > 0) {\n <div class=\"field-values-comprehensive\">\n <div class=\"values-header\">\n <span class=\"fa-solid fa-list\"></span>\n Possible Values ({{ field.EntityFieldValues.length }})\n </div>\n <div class=\"values-grid\">\n @for (fieldValue of getSortedEntityFieldValues(field); track fieldValue.ID) {\n <div class=\"value-item\">\n <div class=\"value-main\">\n <span class=\"value-text\">{{ fieldValue.Value }}</span>\n @if (fieldValue.Code && fieldValue.Code !== fieldValue.Value) {\n <span class=\"value-code\">[{{ fieldValue.Code }}]</span>\n }\n </div>\n @if (fieldValue.Description && fieldValue.Description !== fieldValue.Value) {\n <div class=\"value-description\">{{ fieldValue.Description }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n <div class=\"details-grid\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Data Type:</span>\n <span class=\"detail-value\">{{ field.Type }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Nullable:</span>\n <span class=\"detail-value\" [class]=\"field.AllowsNull ? 'nullable-yes' : 'nullable-no'\">\n {{ field.AllowsNull ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.Length && field.Length > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Max Length:</span>\n <span class=\"detail-value\">{{ field.Length }}</span>\n </div>\n }\n @if (field.Precision && field.Precision > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Precision:</span>\n <span class=\"detail-value\">{{ field.Precision }}</span>\n </div>\n }\n @if (field.Scale && field.Scale > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scale:</span>\n <span class=\"detail-value\">{{ field.Scale }}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Virtual Field:</span>\n <span class=\"detail-value\" [class]=\"field.IsVirtual ? 'virtual-yes' : 'virtual-no'\">\n {{ field.IsVirtual ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.DefaultValue) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Default Value:</span>\n <span class=\"detail-value default-value\">{{ field.DefaultValue }}</span>\n </div>\n }\n @if (field.RelatedEntityID) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Related Entity:</span>\n <span class=\"detail-value related-entity\"\n (click)=\"onRelatedEntityClick($event, field)\"\n title=\"Click to select {{ field.RelatedEntity }} in ERD\">\n {{ field.RelatedEntity }}\n <span class=\"fa-solid fa-arrow-right\"></span>\n </span>\n </div>\n }\n @if (field.AutoIncrement) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Auto Increment:</span>\n <span class=\"detail-value auto-increment\">Yes</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"relationships-section\" [class.section-expanded]=\"relationshipsSectionExpanded\" [class.section-collapsed]=\"!relationshipsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleRelationshipsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"relationshipsSectionExpanded\"\n title=\"Toggle relationships section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Related Entities ({{ selectedEntity ? getRelatedEntities(selectedEntity.ID).length : 0 }})</h4>\n </div>\n </div>\n @if (relationshipsSectionExpanded) {\n <div class=\"related-entities-list\" #relationshipsListContainer>\n @for (relatedEntity of getRelatedEntities(selectedEntity?.ID || ''); track relatedEntity.ID) {\n <div class=\"related-entity-item\" (click)=\"selectEntity(relatedEntity, true)\">\n <span class=\"fa-solid fa-database\"></span>\n <span class=\"entity-name\">{{ relatedEntity.Name || relatedEntity.SchemaName }}</span>\n <span class=\"zoom-indicator fa-solid fa-search-plus\" title=\"Click to zoom to entity\"></span>\n </div>\n }\n </div>\n }\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"entity-details.component.js","sourceRoot":"","sources":["../../../../src/lib/components/entity-details/entity-details.component.ts","../../../../src/lib/components/entity-details/entity-details.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ViewChild, ElementRef } from '@angular/core';\nimport { EntityInfo, EntityFieldInfo, EntityFieldValueInfo } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n/**\n * Event emitted when requesting to open an entity record.\n */\nexport interface EntityDetailsOpenRecordEvent {\n EntityName: string;\n RecordID: string;\n}\n\n/**\n * Entity details panel component that displays detailed information about a selected entity.\n * Shows entity metadata, fields with filtering capabilities, and related entities.\n *\n * This component is designed to be used alongside the ERD diagram to provide\n * a detailed view of the currently selected entity.\n */\n@Component({\n standalone: false,\n selector: 'mj-entity-details',\n templateUrl: './entity-details.component.html',\n styleUrls: ['./entity-details.component.css']\n})\nexport class EntityDetailsComponent extends BaseAngularComponent implements OnChanges {\n @ViewChild('fieldsListContainer', { static: false }) fieldsListContainer!: ElementRef;\n @ViewChild('relationshipsListContainer', { static: false }) relationshipsListContainer!: ElementRef;\n\n /** The currently selected entity to display details for */\n @Input() selectedEntity: EntityInfo | null = null;\n\n /** All entity fields for looking up field information */\n @Input() allEntityFields: EntityFieldInfo[] = [];\n\n /** Whether the fields section is expanded */\n @Input() fieldsSectionExpanded = true;\n\n /** Whether the relationships section is expanded */\n @Input() relationshipsSectionExpanded = true;\n\n /** Emitted when user clicks to open the entity record */\n @Output() openEntity = new EventEmitter<EntityInfo>();\n\n /** Emitted when user clicks the close button */\n @Output() closePanel = new EventEmitter<void>();\n\n /** Emitted when fields section is toggled */\n @Output() fieldsSectionToggle = new EventEmitter<void>();\n\n /** Emitted when relationships section is toggled */\n @Output() relationshipsSectionToggle = new EventEmitter<void>();\n\n /** Emitted when a related entity is selected (clicked in relationships list) */\n @Output() entitySelected = new EventEmitter<EntityInfo>();\n\n /** Emitted when requesting to open an entity record */\n @Output() openRecord = new EventEmitter<EntityDetailsOpenRecordEvent>();\n\n public fieldFilter: 'all' | 'keys' | 'foreign_keys' | 'regular' = 'all';\n public expandedFieldDescriptions = new Set<string>();\n public expandedFieldValues = new Set<string>();\n public expandedFieldDetails = new Set<string>();\n private previousSelectedEntityId: string | null = null;\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['selectedEntity'] && !changes['selectedEntity'].firstChange) {\n const currentEntityId = this.selectedEntity?.ID || null;\n\n // Check if entity actually changed\n if (currentEntityId !== this.previousSelectedEntityId) {\n // Reset scroll positions when entity changes\n this.resetScrollPositions();\n\n this.previousSelectedEntityId = currentEntityId;\n }\n }\n }\n\n private resetScrollPositions(): void {\n // Use setTimeout to ensure the DOM is updated\n setTimeout(() => {\n if (this.fieldsListContainer?.nativeElement) {\n this.fieldsListContainer.nativeElement.scrollTop = 0;\n }\n if (this.relationshipsListContainer?.nativeElement) {\n this.relationshipsListContainer.nativeElement.scrollTop = 0;\n }\n }, 0);\n }\n\n public onOpenEntity(): void {\n if (this.selectedEntity) {\n this.openRecord.emit({\n EntityName: 'MJ: Entities',\n RecordID: this.selectedEntity.ID\n });\n }\n }\n\n public onClosePanel(): void {\n this.closePanel.emit();\n }\n\n public toggleFieldsSection(): void {\n this.fieldsSectionToggle.emit();\n }\n\n public toggleRelationshipsSection(): void {\n this.relationshipsSectionToggle.emit();\n }\n\n public setFieldFilter(filter: 'all' | 'keys' | 'foreign_keys' | 'regular'): void {\n this.fieldFilter = filter;\n }\n\n public getEntityFields(entityId: string): EntityFieldInfo[] {\n if (!entityId) return [];\n\n let fields = this.allEntityFields.filter(f => UUIDsEqual(f.EntityID, entityId));\n\n switch (this.fieldFilter) {\n case 'keys':\n return fields.filter(f => f.IsPrimaryKey || f.Name.toLowerCase().includes('id'));\n case 'foreign_keys':\n return fields.filter(f => f.RelatedEntityID && !f.IsPrimaryKey);\n case 'regular':\n return fields.filter(f => !f.IsPrimaryKey && !f.RelatedEntityID);\n default:\n return fields;\n }\n }\n\n public getRelatedEntities(entityId: string): EntityInfo[] {\n if (!entityId) return [];\n\n const relatedEntityIds = new Set<string>();\n\n // Get entities that this entity references (foreign keys)\n this.allEntityFields\n .filter(f => UUIDsEqual(f.EntityID, entityId) && f.RelatedEntityID)\n .forEach(f => relatedEntityIds.add(f.RelatedEntityID!));\n\n // Get entities that reference this entity\n this.allEntityFields\n .filter(f => UUIDsEqual(f.RelatedEntityID, entityId))\n .forEach(f => relatedEntityIds.add(f.EntityID));\n\n // Remove the current entity from the set (don't return self-references)\n relatedEntityIds.delete(entityId);\n\n // Convert to actual EntityInfo objects\n const md = this.ProviderToUse;\n const allEntities = md.Entities;\n const retVals: EntityInfo[] = [];\n relatedEntityIds.forEach(id => {\n const entity = allEntities.find(e => UUIDsEqual(e.ID, id));\n if (entity) {\n retVals.push(entity);\n }\n });\n return retVals;\n }\n\n public onFieldClick(field: EntityFieldInfo): void {\n this.toggleFieldDetails(field.ID);\n }\n\n public toggleFieldDescription(fieldId: string): void {\n if (this.expandedFieldDescriptions.has(fieldId)) {\n this.expandedFieldDescriptions.delete(fieldId);\n } else {\n this.expandedFieldDescriptions.add(fieldId);\n }\n }\n\n public toggleFieldValues(fieldId: string): void {\n if (this.expandedFieldValues.has(fieldId)) {\n this.expandedFieldValues.delete(fieldId);\n } else {\n this.expandedFieldValues.add(fieldId);\n }\n }\n\n public toggleFieldDetails(fieldId: string): void {\n if (this.expandedFieldDetails.has(fieldId)) {\n this.expandedFieldDetails.delete(fieldId);\n } else {\n this.expandedFieldDetails.add(fieldId);\n }\n }\n\n public isFieldDescriptionExpanded(fieldId: string): boolean {\n return this.expandedFieldDescriptions.has(fieldId);\n }\n\n public isFieldValuesExpanded(fieldId: string): boolean {\n return this.expandedFieldValues.has(fieldId);\n }\n\n public isFieldDetailsExpanded(fieldId: string): boolean {\n return this.expandedFieldDetails.has(fieldId);\n }\n\n public hasFieldPossibleValues(field: EntityFieldInfo): boolean {\n return field.EntityFieldValues && field.EntityFieldValues.length > 0;\n }\n\n public getFieldPossibleValues(field: EntityFieldInfo): string[] {\n if (!field.EntityFieldValues) return [];\n return field.EntityFieldValues.map(v => v.Value).slice(0, 10);\n }\n\n public getSortedEntityFieldValues(field: EntityFieldInfo): EntityFieldValueInfo[] {\n if (!field.EntityFieldValues) return [];\n return field.EntityFieldValues.sort((a, b) => {\n if (a.Sequence !== undefined && b.Sequence !== undefined) {\n return a.Sequence - b.Sequence;\n }\n return a.Value.localeCompare(b.Value);\n });\n }\n\n public onRelatedEntityClick(event: Event, field: EntityFieldInfo): void {\n event.stopPropagation();\n if (field.RelatedEntityID) {\n // Find the related entity and select it in the ERD\n const md = this.ProviderToUse;\n const relatedEntity = md.Entities.find(e => UUIDsEqual(e.ID, field.RelatedEntityID));\n if (relatedEntity) {\n this.entitySelected.emit(relatedEntity);\n }\n }\n }\n\n public selectEntity(entity: EntityInfo, _zoomTo: boolean = false): void {\n this.entitySelected.emit(entity);\n }\n}\n","<div class=\"details-panel\">\n <div class=\"panel-header\">\n <h3>{{ selectedEntity?.Name || selectedEntity?.SchemaName }}</h3>\n <div class=\"panel-actions\">\n <button class=\"open-btn\" (click)=\"onOpenEntity()\" title=\"Open Entity Record\">\n <span class=\"fa-solid fa-external-link-alt\"></span>\n Open\n </button>\n <button class=\"close-btn\" (click)=\"onClosePanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n </div>\n\n <div class=\"entity-info\">\n <div class=\"info-row\">\n <label>Schema:</label>\n <span>{{ selectedEntity?.SchemaName }}</span>\n </div>\n <div class=\"info-row\">\n <label>Table:</label>\n <span>{{ selectedEntity?.BaseTable }}</span>\n </div>\n @if (selectedEntity?.Description) {\n <div class=\"info-row\">\n <label>Description:</label>\n <span>{{ selectedEntity?.Description }}</span>\n </div>\n }\n </div>\n\n <div class=\"fields-section\" [class.section-expanded]=\"fieldsSectionExpanded\" [class.section-collapsed]=\"!fieldsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleFieldsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"fieldsSectionExpanded\"\n title=\"Toggle fields section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Fields ({{ selectedEntity ? getEntityFields(selectedEntity.ID).length : 0 }})</h4>\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"field-filters\">\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'all'\"\n (click)=\"setFieldFilter('all')\"\n title=\"Show all fields\">\n All\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'keys'\"\n (click)=\"setFieldFilter('keys')\"\n title=\"Show primary keys and ID fields\">\n Keys\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'foreign_keys'\"\n (click)=\"setFieldFilter('foreign_keys')\"\n title=\"Show foreign key fields only\">\n FKs\n </button>\n <button\n class=\"filter-btn\"\n [class.active]=\"fieldFilter === 'regular'\"\n (click)=\"setFieldFilter('regular')\"\n title=\"Show regular data fields\">\n Regular\n </button>\n </div>\n }\n </div>\n @if (fieldsSectionExpanded) {\n <div class=\"fields-list\" #fieldsListContainer>\n @for (field of getEntityFields(selectedEntity?.ID || ''); track field.ID) {\n <div class=\"field-item\"\n [class]=\"{\n 'primary-key-field': field.IsPrimaryKey,\n 'foreign-key-field': field.RelatedEntityID && !field.IsPrimaryKey,\n 'regular-field': !field.IsPrimaryKey && !field.RelatedEntityID,\n 'field-expanded': isFieldDetailsExpanded(field.ID)\n }\"\n (click)=\"onFieldClick(field)\"\n [title]=\"'Click to see more details about ' + field.Name\">\n <div class=\"field-header\">\n <div class=\"field-name\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-icon fa-solid fa-key\" title=\"Primary Key\"></span>\n } @else if (field.RelatedEntityID) {\n <span class=\"field-icon fa-solid fa-link\" title=\"Foreign Key\"></span>\n }\n {{ field.Name }}\n </div>\n <div class=\"field-actions\">\n @if (hasFieldPossibleValues(field)) {\n <button\n class=\"field-values-btn\"\n (click)=\"toggleFieldValues(field.ID)\"\n [class.expanded]=\"isFieldValuesExpanded(field.ID)\"\n title=\"Toggle possible values\">\n <span class=\"fa-solid fa-list\"></span>\n </button>\n }\n @if (field.Description) {\n <button\n class=\"field-info-btn\"\n (click)=\"toggleFieldDescription(field.ID)\"\n [class.expanded]=\"isFieldDescriptionExpanded(field.ID)\"\n title=\"Toggle field description\">\n <span class=\"fa-solid fa-info-circle\"></span>\n </button>\n }\n <div class=\"field-badges\">\n @if (field.IsPrimaryKey) {\n <span class=\"field-badge primary-key\">PK</span>\n }\n @if (field.RelatedEntityID && !field.IsPrimaryKey) {\n <span class=\"field-badge foreign-key\">FK</span>\n }\n </div>\n </div>\n </div>\n <div class=\"field-details\">\n <div class=\"field-type\">{{ field.Type }}</div>\n @if (field.RelatedEntityID) {\n <div class=\"field-relation\">\n <span class=\"fa-solid fa-arrow-right\"></span>\n Related Entity\n </div>\n }\n </div>\n @if (field.Description && isFieldDescriptionExpanded(field.ID)) {\n <div class=\"field-description\">\n <div class=\"description-text\">{{ field.Description }}</div>\n </div>\n }\n @if (hasFieldPossibleValues(field) && isFieldValuesExpanded(field.ID)) {\n <div class=\"field-values\">\n <div class=\"values-header\">Possible Values:</div>\n <div class=\"values-list\">\n @for (value of getFieldPossibleValues(field); track value; let i = $index) {\n <span class=\"value-tag\">{{ value }}</span>\n }\n </div>\n </div>\n }\n @if (isFieldDetailsExpanded(field.ID)) {\n <div class=\"field-comprehensive-details\">\n @if (field.Description) {\n <div class=\"comprehensive-description-top\">\n <div class=\"description-content\">{{ field.Description }}</div>\n </div>\n }\n @if (field.EntityFieldValues && field.EntityFieldValues.length > 0) {\n <div class=\"field-values-comprehensive\">\n <div class=\"values-header\">\n <span class=\"fa-solid fa-list\"></span>\n Possible Values ({{ field.EntityFieldValues.length }})\n </div>\n <div class=\"values-grid\">\n @for (fieldValue of getSortedEntityFieldValues(field); track fieldValue.ID) {\n <div class=\"value-item\">\n <div class=\"value-main\">\n <span class=\"value-text\">{{ fieldValue.Value }}</span>\n @if (fieldValue.Code && fieldValue.Code !== fieldValue.Value) {\n <span class=\"value-code\">[{{ fieldValue.Code }}]</span>\n }\n </div>\n @if (fieldValue.Description && fieldValue.Description !== fieldValue.Value) {\n <div class=\"value-description\">{{ fieldValue.Description }}</div>\n }\n </div>\n }\n </div>\n </div>\n }\n <div class=\"details-grid\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Data Type:</span>\n <span class=\"detail-value\">{{ field.Type }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Nullable:</span>\n <span class=\"detail-value\" [class]=\"field.AllowsNull ? 'nullable-yes' : 'nullable-no'\">\n {{ field.AllowsNull ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.Length && field.Length > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Max Length:</span>\n <span class=\"detail-value\">{{ field.Length }}</span>\n </div>\n }\n @if (field.Precision && field.Precision > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Precision:</span>\n <span class=\"detail-value\">{{ field.Precision }}</span>\n </div>\n }\n @if (field.Scale && field.Scale > 0) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Scale:</span>\n <span class=\"detail-value\">{{ field.Scale }}</span>\n </div>\n }\n <div class=\"detail-row\">\n <span class=\"detail-label\">Virtual Field:</span>\n <span class=\"detail-value\" [class]=\"field.IsVirtual ? 'virtual-yes' : 'virtual-no'\">\n {{ field.IsVirtual ? 'Yes' : 'No' }}\n </span>\n </div>\n @if (field.DefaultValue) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Default Value:</span>\n <span class=\"detail-value default-value\">{{ field.DefaultValue }}</span>\n </div>\n }\n @if (field.RelatedEntityID) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Related Entity:</span>\n <span class=\"detail-value related-entity\"\n (click)=\"onRelatedEntityClick($event, field)\"\n title=\"Click to select {{ field.RelatedEntity }} in ERD\">\n {{ field.RelatedEntity }}\n <span class=\"fa-solid fa-arrow-right\"></span>\n </span>\n </div>\n }\n @if (field.AutoIncrement) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Auto Increment:</span>\n <span class=\"detail-value auto-increment\">Yes</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"relationships-section\" [class.section-expanded]=\"relationshipsSectionExpanded\" [class.section-collapsed]=\"!relationshipsSectionExpanded\">\n <div class=\"section-header extra-padding\">\n <div class=\"section-title-group\" (click)=\"toggleRelationshipsSection()\">\n <button\n class=\"expand-btn\"\n [class.expanded]=\"relationshipsSectionExpanded\"\n title=\"Toggle relationships section\">\n <span class=\"fa-solid fa-chevron-right\"></span>\n </button>\n <h4>Related Entities ({{ selectedEntity ? getRelatedEntities(selectedEntity.ID).length : 0 }})</h4>\n </div>\n </div>\n @if (relationshipsSectionExpanded) {\n <div class=\"related-entities-list\" #relationshipsListContainer>\n @for (relatedEntity of getRelatedEntities(selectedEntity?.ID || ''); track relatedEntity.ID) {\n <div class=\"related-entity-item\" (click)=\"selectEntity(relatedEntity, true)\">\n <span class=\"fa-solid fa-database\"></span>\n <span class=\"entity-name\">{{ relatedEntity.Name || relatedEntity.SchemaName }}</span>\n <span class=\"zoom-indicator fa-solid fa-search-plus\" title=\"Click to zoom to entity\"></span>\n </div>\n }\n </div>\n }\n </div>\n</div>\n"]}
@@ -10,6 +10,10 @@ export interface EntityFilter {
10
10
  entityStatus: string | null;
11
11
  baseTable: string;
12
12
  }
13
+ interface FilterOption {
14
+ text: string;
15
+ value: string | null;
16
+ }
13
17
  /**
14
18
  * Entity filter panel component that provides filtering controls for entities.
15
19
  * Supports filtering by schema, entity name, base table, and status.
@@ -32,17 +36,19 @@ export declare class EntityFilterPanelComponent implements OnInit, OnChanges {
32
36
  resetFilters: EventEmitter<void>;
33
37
  /** Emitted when close button is clicked */
34
38
  closePanel: EventEmitter<void>;
35
- distinctSchemas: Array<{
36
- text: string;
37
- value: string;
38
- }>;
39
+ schemaOptions: FilterOption[];
40
+ readonly statusOptions: readonly FilterOption[];
39
41
  ngOnInit(): void;
40
42
  ngOnChanges(changes: SimpleChanges): void;
43
+ onSchemaChange(value: unknown): void;
44
+ onStatusChange(value: unknown): void;
41
45
  onFilterChange(): void;
42
46
  resetAllFilters(): void;
43
47
  toggleFilterPanel(): void;
48
+ private emitFilterChange;
44
49
  private updateDistinctSchemas;
45
50
  static ɵfac: i0.ɵɵFactoryDeclaration<EntityFilterPanelComponent, never>;
46
51
  static ɵcmp: i0.ɵɵComponentDeclaration<EntityFilterPanelComponent, "mj-entity-filter-panel", never, { "entities": { "alias": "entities"; "required": false; }; "filteredEntities": { "alias": "filteredEntities"; "required": false; }; "filters": { "alias": "filters"; "required": false; }; }, { "filtersChange": "filtersChange"; "filterChange": "filterChange"; "resetFilters": "resetFilters"; "closePanel": "closePanel"; }, never, never, false, never>;
47
52
  }
53
+ export {};
48
54
  //# sourceMappingURL=entity-filter-panel.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity-filter-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/entity-filter-panel/entity-filter-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;;AAElD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,qBAMa,0BAA2B,YAAW,MAAM,EAAE,SAAS;IAClE,2CAA2C;IAClC,QAAQ,EAAE,UAAU,EAAE,CAAM;IAErC,sDAAsD;IAC7C,gBAAgB,EAAE,UAAU,EAAE,CAAM;IAE7C,4BAA4B;IACnB,OAAO,EAAE,YAAY,CAK5B;IAEF,4CAA4C;IAClC,aAAa,6BAAoC;IAE3D,sDAAsD;IAC5C,YAAY,qBAA4B;IAElD,2CAA2C;IACjC,YAAY,qBAA4B;IAElD,2CAA2C;IACjC,UAAU,qBAA4B;IAEzC,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAEpE,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMlC,cAAc,IAAI,IAAI;IAKtB,eAAe,IAAI,IAAI;IAIvB,iBAAiB,IAAI,IAAI;IAIhC,OAAO,CAAC,qBAAqB;yCApDlB,0BAA0B;2CAA1B,0BAA0B;CAgEtC"}
1
+ {"version":3,"file":"entity-filter-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/entity-filter-panel/entity-filter-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;;AAElD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAUD;;;;;;GAMG;AACH,qBAMa,0BAA2B,YAAW,MAAM,EAAE,SAAS;IAClE,2CAA2C;IAClC,QAAQ,EAAE,UAAU,EAAE,CAAM;IAErC,sDAAsD;IAC7C,gBAAgB,EAAE,UAAU,EAAE,CAAM;IAE7C,4BAA4B;IACnB,OAAO,EAAE,YAAY,CAK5B;IAEF,4CAA4C;IAClC,aAAa,6BAAoC;IAE3D,sDAAsD;IAC5C,YAAY,qBAA4B;IAElD,2CAA2C;IACjC,YAAY,qBAA4B;IAElD,2CAA2C;IACjC,UAAU,qBAA4B;IAEzC,aAAa,EAAE,YAAY,EAAE,CAAM;IAC1C,SAAgB,aAAa,0BAAkB;IAE/C,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMlC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKpC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKpC,cAAc,IAAI,IAAI;IAItB,eAAe,IAAI,IAAI;IAIvB,iBAAiB,IAAI,IAAI;IAIhC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,qBAAqB;yCAnElB,0BAA0B;2CAA1B,0BAA0B;CAgFtC"}