@memberjunction/ng-artifacts 5.36.0 → 5.38.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.
- package/README.md +31 -0
- package/dist/__tests__/image-artifact-viewer.test.d.ts +2 -0
- package/dist/__tests__/image-artifact-viewer.test.d.ts.map +1 -0
- package/dist/__tests__/image-artifact-viewer.test.js +62 -0
- package/dist/__tests__/image-artifact-viewer.test.js.map +1 -0
- package/dist/lib/__tests__/interactive-form-apply.service.test.d.ts +2 -0
- package/dist/lib/__tests__/interactive-form-apply.service.test.d.ts.map +1 -0
- package/dist/lib/__tests__/interactive-form-apply.service.test.js +206 -0
- package/dist/lib/__tests__/interactive-form-apply.service.test.js.map +1 -0
- package/dist/lib/artifacts.module.d.ts +14 -12
- package/dist/lib/artifacts.module.d.ts.map +1 -1
- package/dist/lib/artifacts.module.js +14 -2
- package/dist/lib/artifacts.module.js.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +11 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.js +18 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +10 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +11 -3
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +60 -2
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +373 -24
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +0 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js +2 -2
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +129 -0
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/plugins/image-artifact-viewer.component.js +413 -0
- package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -0
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +2 -2
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.js +0 -2
- package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +2 -2
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/services/interactive-form-apply.service.d.ts +46 -0
- package/dist/lib/services/interactive-form-apply.service.d.ts.map +1 -0
- package/dist/lib/services/interactive-form-apply.service.js +219 -0
- package/dist/lib/services/interactive-form-apply.service.js.map +1 -0
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +18 -16
package/README.md
CHANGED
|
@@ -178,6 +178,37 @@ getIcon() {
|
|
|
178
178
|
- `@angular/core` ^21.x
|
|
179
179
|
- `@angular/platform-browser` ^21.x
|
|
180
180
|
|
|
181
|
+
## Form-aware artifact viewer (interactive forms)
|
|
182
|
+
|
|
183
|
+
When an artifact's spec declares `componentRole: 'form'`, the
|
|
184
|
+
`ComponentArtifactViewerComponent` switches to its form-aware branch:
|
|
185
|
+
|
|
186
|
+
- Resolves the entity from `spec.entityName` (or `spec.dataRequirements.entities[0].name`)
|
|
187
|
+
- Loads `TOP 1` record (ordered by `NameField` then `__mj_CreatedAt`) and
|
|
188
|
+
mounts via `<mj-interactive-form>` bound to that real record
|
|
189
|
+
- Falls back to a fresh `NewRecord()` when the entity has no rows
|
|
190
|
+
- Exposes a search-as-you-type record picker so users can swap the bound record
|
|
191
|
+
- Bubbles a top-level **`applyFormRequested`** `@Output` carrying
|
|
192
|
+
`{ spec, entityName }` when the user clicks "Apply to my form"
|
|
193
|
+
|
|
194
|
+
The `InteractiveFormApplyService` (exported from this package) consumes
|
|
195
|
+
that event end-to-end: confirms with the user via `MJDialogService`,
|
|
196
|
+
calls `Get Active Form For Entity` to detect existing state, then
|
|
197
|
+
routes to `Create Interactive Form` (net-new) or
|
|
198
|
+
`Modify Interactive Form` (refinement → new Pending version).
|
|
199
|
+
|
|
200
|
+
Consumers wire one line in their template:
|
|
201
|
+
```html
|
|
202
|
+
<mj-artifact-viewer-panel
|
|
203
|
+
...
|
|
204
|
+
(applyFormRequested)="onApplyFormRequested($event)">
|
|
205
|
+
</mj-artifact-viewer-panel>
|
|
206
|
+
```
|
|
207
|
+
…and inject `InteractiveFormApplyService` in the handler.
|
|
208
|
+
|
|
209
|
+
Wired in `ConversationChatAreaComponent` (live chat) and `ArtifactResource`
|
|
210
|
+
(standalone artifact viewing in Explorer).
|
|
211
|
+
|
|
181
212
|
## Build
|
|
182
213
|
|
|
183
214
|
```bash
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-artifact-viewer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/image-artifact-viewer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { IMAGE_MIME_EXTENSION_MAP, buildImageDownloadFileName, } from '../lib/components/plugins/image-artifact-viewer.component';
|
|
3
|
+
/**
|
|
4
|
+
* Unit tests for the pure helpers exported from the image-artifact viewer
|
|
5
|
+
* plugin. The plugin's Angular component itself can't be rendered under the
|
|
6
|
+
* package's `node`-environment vitest config (no DOM, no TestBed), so the
|
|
7
|
+
* tests focus on the deterministic, side-effect-free logic that the component
|
|
8
|
+
* delegates to — exactly the boundary that has historically caused user-visible
|
|
9
|
+
* bugs (filename sanitization, MIME → extension mapping).
|
|
10
|
+
*/
|
|
11
|
+
describe('IMAGE_MIME_EXTENSION_MAP', () => {
|
|
12
|
+
it('covers the MIMEs that the seed Image artifact type advertises', () => {
|
|
13
|
+
// The metadata seed declares ContentType "image/*". These are the
|
|
14
|
+
// common raster MIMEs that Generate Image and uploaded files produce.
|
|
15
|
+
const required = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
|
|
16
|
+
for (const mime of required) {
|
|
17
|
+
expect(IMAGE_MIME_EXTENSION_MAP[mime]).toBeTruthy();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
it('returns the canonical short extension for JPEG (jpg, not jpeg)', () => {
|
|
21
|
+
expect(IMAGE_MIME_EXTENSION_MAP['image/jpeg']).toBe('jpg');
|
|
22
|
+
});
|
|
23
|
+
it('is frozen (read-only) so callers cannot mutate the shared map', () => {
|
|
24
|
+
// Object.freeze guarantees runtime immutability — if a future refactor
|
|
25
|
+
// removes the freeze this test will catch it.
|
|
26
|
+
expect(Object.isFrozen(IMAGE_MIME_EXTENSION_MAP)).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('buildImageDownloadFileName', () => {
|
|
30
|
+
it('combines a clean name and the right extension', () => {
|
|
31
|
+
expect(buildImageDownloadFileName('mountain', 'image/png')).toBe('mountain.png');
|
|
32
|
+
});
|
|
33
|
+
it('uses jpg for jpeg even when input is uppercase', () => {
|
|
34
|
+
expect(buildImageDownloadFileName('photo', 'IMAGE/JPEG')).toBe('photo.jpg');
|
|
35
|
+
});
|
|
36
|
+
it('strips characters that are unsafe on common filesystems', () => {
|
|
37
|
+
// Spaces, slashes, colons, and emoji should all be normalized to underscores.
|
|
38
|
+
expect(buildImageDownloadFileName('Generated image 1', 'image/jpeg')).toBe('Generated_image_1.jpg');
|
|
39
|
+
expect(buildImageDownloadFileName('a/b:c\\d', 'image/png')).toBe('a_b_c_d.png');
|
|
40
|
+
});
|
|
41
|
+
it('preserves dots, dashes, and underscores (filesystem-safe)', () => {
|
|
42
|
+
expect(buildImageDownloadFileName('snapshot_v2-final.draft', 'image/png')).toBe('snapshot_v2-final.draft.png');
|
|
43
|
+
});
|
|
44
|
+
it('falls back to "image" when no name is supplied', () => {
|
|
45
|
+
expect(buildImageDownloadFileName(null, 'image/png')).toBe('image.png');
|
|
46
|
+
expect(buildImageDownloadFileName(undefined, 'image/webp')).toBe('image.webp');
|
|
47
|
+
expect(buildImageDownloadFileName('', 'image/gif')).toBe('image.gif');
|
|
48
|
+
});
|
|
49
|
+
it('falls back to "img" extension when the MIME type is missing or unknown', () => {
|
|
50
|
+
expect(buildImageDownloadFileName('thing', null)).toBe('thing.img');
|
|
51
|
+
expect(buildImageDownloadFileName('thing', undefined)).toBe('thing.img');
|
|
52
|
+
expect(buildImageDownloadFileName('thing', '')).toBe('thing.img');
|
|
53
|
+
expect(buildImageDownloadFileName('thing', 'application/json')).toBe('thing.img');
|
|
54
|
+
});
|
|
55
|
+
it('does not double-append the extension when the name already has it', () => {
|
|
56
|
+
// The agent sometimes hands us labels like "Generated image 1.png" — we
|
|
57
|
+
// shouldn't end up with "Generated_image_1.png.png" in the user's downloads.
|
|
58
|
+
expect(buildImageDownloadFileName('photo.png', 'image/png')).toBe('photo.png');
|
|
59
|
+
expect(buildImageDownloadFileName('shot.JPG', 'image/jpeg')).toBe('shot.JPG');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=image-artifact-viewer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-artifact-viewer.test.js","sourceRoot":"","sources":["../../src/__tests__/image-artifact-viewer.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport {\n IMAGE_MIME_EXTENSION_MAP,\n buildImageDownloadFileName,\n} from '../lib/components/plugins/image-artifact-viewer.component';\n\n/**\n * Unit tests for the pure helpers exported from the image-artifact viewer\n * plugin. The plugin's Angular component itself can't be rendered under the\n * package's `node`-environment vitest config (no DOM, no TestBed), so the\n * tests focus on the deterministic, side-effect-free logic that the component\n * delegates to — exactly the boundary that has historically caused user-visible\n * bugs (filename sanitization, MIME → extension mapping).\n */\n\ndescribe('IMAGE_MIME_EXTENSION_MAP', () => {\n it('covers the MIMEs that the seed Image artifact type advertises', () => {\n // The metadata seed declares ContentType \"image/*\". These are the\n // common raster MIMEs that Generate Image and uploaded files produce.\n const required = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];\n for (const mime of required) {\n expect(IMAGE_MIME_EXTENSION_MAP[mime]).toBeTruthy();\n }\n });\n\n it('returns the canonical short extension for JPEG (jpg, not jpeg)', () => {\n expect(IMAGE_MIME_EXTENSION_MAP['image/jpeg']).toBe('jpg');\n });\n\n it('is frozen (read-only) so callers cannot mutate the shared map', () => {\n // Object.freeze guarantees runtime immutability — if a future refactor\n // removes the freeze this test will catch it.\n expect(Object.isFrozen(IMAGE_MIME_EXTENSION_MAP)).toBe(true);\n });\n});\n\ndescribe('buildImageDownloadFileName', () => {\n it('combines a clean name and the right extension', () => {\n expect(buildImageDownloadFileName('mountain', 'image/png')).toBe('mountain.png');\n });\n\n it('uses jpg for jpeg even when input is uppercase', () => {\n expect(buildImageDownloadFileName('photo', 'IMAGE/JPEG')).toBe('photo.jpg');\n });\n\n it('strips characters that are unsafe on common filesystems', () => {\n // Spaces, slashes, colons, and emoji should all be normalized to underscores.\n expect(buildImageDownloadFileName('Generated image 1', 'image/jpeg')).toBe('Generated_image_1.jpg');\n expect(buildImageDownloadFileName('a/b:c\\\\d', 'image/png')).toBe('a_b_c_d.png');\n });\n\n it('preserves dots, dashes, and underscores (filesystem-safe)', () => {\n expect(buildImageDownloadFileName('snapshot_v2-final.draft', 'image/png')).toBe(\n 'snapshot_v2-final.draft.png',\n );\n });\n\n it('falls back to \"image\" when no name is supplied', () => {\n expect(buildImageDownloadFileName(null, 'image/png')).toBe('image.png');\n expect(buildImageDownloadFileName(undefined, 'image/webp')).toBe('image.webp');\n expect(buildImageDownloadFileName('', 'image/gif')).toBe('image.gif');\n });\n\n it('falls back to \"img\" extension when the MIME type is missing or unknown', () => {\n expect(buildImageDownloadFileName('thing', null)).toBe('thing.img');\n expect(buildImageDownloadFileName('thing', undefined)).toBe('thing.img');\n expect(buildImageDownloadFileName('thing', '')).toBe('thing.img');\n expect(buildImageDownloadFileName('thing', 'application/json')).toBe('thing.img');\n });\n\n it('does not double-append the extension when the name already has it', () => {\n // The agent sometimes hands us labels like \"Generated image 1.png\" — we\n // shouldn't end up with \"Generated_image_1.png.png\" in the user's downloads.\n expect(buildImageDownloadFileName('photo.png', 'image/png')).toBe('photo.png');\n expect(buildImageDownloadFileName('shot.JPG', 'image/jpeg')).toBe('shot.JPG');\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-form-apply.service.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/interactive-form-apply.service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end-ish coverage for the Apply-to-my-form flow.
|
|
3
|
+
*
|
|
4
|
+
* The service is the join point that closes the chat-artifact → action loop:
|
|
5
|
+
* form-aware artifact viewer → applyFormRequested →
|
|
6
|
+
* conversation-chat-area / artifact-resource → ConfirmAndApply →
|
|
7
|
+
* Get Active Form For Entity (action) → Create or Modify (action)
|
|
8
|
+
*
|
|
9
|
+
* These tests mock the dialog, notifications, and the GraphQL action
|
|
10
|
+
* client so we can drive both branches (no-existing → Create; existing →
|
|
11
|
+
* Modify) and the cancellation path, plus the failure surfaces. Without
|
|
12
|
+
* this suite the original "Apply button is wired to nothing" bug would
|
|
13
|
+
* regress silently — the unit tests on the actions wouldn't notice.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
16
|
+
// ─── Hoisted state buckets the mocks read/write ──────────────────────────
|
|
17
|
+
const hoisted = vi.hoisted(() => ({
|
|
18
|
+
dialogResult: 'apply',
|
|
19
|
+
actionResponses: new Map(),
|
|
20
|
+
actionCalls: [],
|
|
21
|
+
runViewResponses: [],
|
|
22
|
+
notifications: [],
|
|
23
|
+
}));
|
|
24
|
+
// ─── Module mocks ────────────────────────────────────────────────────────
|
|
25
|
+
vi.mock('@angular/core', () => ({
|
|
26
|
+
Injectable: () => (target) => target,
|
|
27
|
+
inject: (token) => {
|
|
28
|
+
// Return the mock singletons by class identity.
|
|
29
|
+
const name = token.name ?? '';
|
|
30
|
+
if (name === 'MJDialogService')
|
|
31
|
+
return mockDialog;
|
|
32
|
+
if (name === 'MJNotificationService')
|
|
33
|
+
return mockNotifications;
|
|
34
|
+
return {};
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
const mockDialog = {
|
|
38
|
+
Open: () => ({
|
|
39
|
+
Result: {
|
|
40
|
+
subscribe: (cb) => {
|
|
41
|
+
cb({ result: hoisted.dialogResult });
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
const mockNotifications = {
|
|
47
|
+
CreateSimpleNotification: (message, type) => {
|
|
48
|
+
hoisted.notifications.push({ message, type });
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
vi.mock('@memberjunction/ng-ui-components', () => ({ MJDialogService: class MJDialogService {
|
|
52
|
+
} }));
|
|
53
|
+
vi.mock('@memberjunction/ng-notifications', () => ({ MJNotificationService: class MJNotificationService {
|
|
54
|
+
} }));
|
|
55
|
+
vi.mock('@memberjunction/graphql-dataprovider', () => ({
|
|
56
|
+
GraphQLActionClient: class {
|
|
57
|
+
async RunAction(actionId, params) {
|
|
58
|
+
hoisted.actionCalls.push({ id: actionId, params });
|
|
59
|
+
return hoisted.actionResponses.get(actionId) ?? { Success: false, Message: 'mock: no response set' };
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
GraphQLDataProvider: class {
|
|
63
|
+
},
|
|
64
|
+
}));
|
|
65
|
+
vi.mock('@memberjunction/core', async () => {
|
|
66
|
+
const actual = await vi.importActual('@memberjunction/core');
|
|
67
|
+
return {
|
|
68
|
+
...actual,
|
|
69
|
+
Metadata: { Provider: null },
|
|
70
|
+
LogError: vi.fn(),
|
|
71
|
+
RunView: class {
|
|
72
|
+
async RunView() {
|
|
73
|
+
return hoisted.runViewResponses.shift() ?? { Success: true, Results: [] };
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
// ─── Test setup ──────────────────────────────────────────────────────────
|
|
79
|
+
import { InteractiveFormApplyService } from '../services/interactive-form-apply.service';
|
|
80
|
+
function mockProvider(overrides = {}) {
|
|
81
|
+
return {
|
|
82
|
+
EntityByName: () => ({ ID: 'ENT-1', Name: 'MJ: Apps' }),
|
|
83
|
+
CurrentUser: { ID: 'U1', Name: 'Test' },
|
|
84
|
+
ExecuteGQL: () => Promise.resolve({}), // marks it as a GraphQL provider
|
|
85
|
+
...overrides,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function spec(over = {}) {
|
|
89
|
+
return { name: 'Form', componentRole: 'form', location: 'embedded', code: '() => null', ...over };
|
|
90
|
+
}
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
hoisted.dialogResult = 'apply';
|
|
93
|
+
hoisted.actionResponses.clear();
|
|
94
|
+
hoisted.actionCalls.length = 0;
|
|
95
|
+
hoisted.runViewResponses.length = 0;
|
|
96
|
+
hoisted.notifications.length = 0;
|
|
97
|
+
});
|
|
98
|
+
describe('InteractiveFormApplyService', () => {
|
|
99
|
+
it('returns failure when no metadata provider is available', async () => {
|
|
100
|
+
const svc = new InteractiveFormApplyService();
|
|
101
|
+
// No provider — neither passed nor on Metadata.Provider.
|
|
102
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps');
|
|
103
|
+
expect(result.Success).toBe(false);
|
|
104
|
+
expect(result.Message).toMatch(/No metadata provider/);
|
|
105
|
+
});
|
|
106
|
+
it('returns failure when the declared entity is not registered', async () => {
|
|
107
|
+
const svc = new InteractiveFormApplyService();
|
|
108
|
+
const provider = mockProvider({ EntityByName: () => undefined });
|
|
109
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: NotAnEntity', provider);
|
|
110
|
+
expect(result.Success).toBe(false);
|
|
111
|
+
expect(result.Message).toMatch(/not registered/);
|
|
112
|
+
});
|
|
113
|
+
it('cancellation by user yields a friendly failure result, no action invoked', async () => {
|
|
114
|
+
hoisted.dialogResult = 'cancel';
|
|
115
|
+
// Seed action-id lookup so the path past dialog is reachable in case the
|
|
116
|
+
// implementation order changes; with dialog returning 'cancel' the
|
|
117
|
+
// Create action should never be called.
|
|
118
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });
|
|
119
|
+
hoisted.actionResponses.set('ACT-GET-ACTIVE', {
|
|
120
|
+
Success: true,
|
|
121
|
+
Message: JSON.stringify({ Active: null, Variants: [] }),
|
|
122
|
+
});
|
|
123
|
+
const svc = new InteractiveFormApplyService();
|
|
124
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());
|
|
125
|
+
expect(result.Success).toBe(false);
|
|
126
|
+
expect(result.Message).toMatch(/Cancelled/);
|
|
127
|
+
// Only Get Active Form should have been called (to populate dialog text);
|
|
128
|
+
// Create / Modify should NOT have been called.
|
|
129
|
+
const calls = hoisted.actionCalls.map(c => c.id);
|
|
130
|
+
expect(calls.filter(id => id !== 'ACT-GET-ACTIVE')).toEqual([]);
|
|
131
|
+
});
|
|
132
|
+
it('no existing override → calls Create Interactive Form', async () => {
|
|
133
|
+
// RunView lookups: each call resolves the next action ID.
|
|
134
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });
|
|
135
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-CREATE' }] });
|
|
136
|
+
hoisted.actionResponses.set('ACT-GET-ACTIVE', {
|
|
137
|
+
Success: true,
|
|
138
|
+
Message: JSON.stringify({ Active: null, Variants: [] }),
|
|
139
|
+
});
|
|
140
|
+
hoisted.actionResponses.set('ACT-CREATE', {
|
|
141
|
+
Success: true,
|
|
142
|
+
Message: JSON.stringify({ ComponentID: 'NEW-COMP', OverrideID: 'NEW-OVER', Version: '1.0.0' }),
|
|
143
|
+
});
|
|
144
|
+
const svc = new InteractiveFormApplyService();
|
|
145
|
+
const result = await svc.ConfirmAndApply(spec({ name: 'CompactForm' }), 'MJ: Apps', mockProvider());
|
|
146
|
+
expect(result.Success).toBe(true);
|
|
147
|
+
expect(result.Mode).toBe('create');
|
|
148
|
+
expect(result.OverrideID).toBe('NEW-OVER');
|
|
149
|
+
expect(result.Version).toBe('1.0.0');
|
|
150
|
+
const calls = hoisted.actionCalls.map(c => c.id);
|
|
151
|
+
expect(calls).toEqual(['ACT-GET-ACTIVE', 'ACT-CREATE']);
|
|
152
|
+
// Success notification surfaced.
|
|
153
|
+
expect(hoisted.notifications.some(n => n.type === 'success')).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
it('existing Active override → calls Modify Interactive Form (Pending sibling produced)', async () => {
|
|
156
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });
|
|
157
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-MODIFY' }] });
|
|
158
|
+
hoisted.actionResponses.set('ACT-GET-ACTIVE', {
|
|
159
|
+
Success: true,
|
|
160
|
+
Message: JSON.stringify({
|
|
161
|
+
Active: { OverrideID: 'OVER-EXISTING', ComponentID: 'COMP-EXISTING', ComponentVersion: '1.0.0' },
|
|
162
|
+
Variants: [],
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
hoisted.actionResponses.set('ACT-MODIFY', {
|
|
166
|
+
Success: true,
|
|
167
|
+
Message: JSON.stringify({ Mode: 'new-version', ComponentID: 'NEW-COMP', OverrideID: 'NEW-OVER', Version: '1.1.0' }),
|
|
168
|
+
});
|
|
169
|
+
const svc = new InteractiveFormApplyService();
|
|
170
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());
|
|
171
|
+
expect(result.Success).toBe(true);
|
|
172
|
+
expect(result.Mode).toBe('modify-new-version');
|
|
173
|
+
expect(result.Version).toBe('1.1.0');
|
|
174
|
+
const calls = hoisted.actionCalls.map(c => c.id);
|
|
175
|
+
expect(calls).toEqual(['ACT-GET-ACTIVE', 'ACT-MODIFY']);
|
|
176
|
+
});
|
|
177
|
+
it('Get Active failure short-circuits with an error', async () => {
|
|
178
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });
|
|
179
|
+
hoisted.actionResponses.set('ACT-GET-ACTIVE', {
|
|
180
|
+
Success: false,
|
|
181
|
+
Message: 'DB unavailable',
|
|
182
|
+
});
|
|
183
|
+
const svc = new InteractiveFormApplyService();
|
|
184
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());
|
|
185
|
+
expect(result.Success).toBe(false);
|
|
186
|
+
expect(result.Message).toMatch(/Could not check for existing override/);
|
|
187
|
+
});
|
|
188
|
+
it('failure on the Create action surfaces the error notification', async () => {
|
|
189
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });
|
|
190
|
+
hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-CREATE' }] });
|
|
191
|
+
hoisted.actionResponses.set('ACT-GET-ACTIVE', {
|
|
192
|
+
Success: true,
|
|
193
|
+
Message: JSON.stringify({ Active: null, Variants: [] }),
|
|
194
|
+
});
|
|
195
|
+
hoisted.actionResponses.set('ACT-CREATE', {
|
|
196
|
+
Success: false,
|
|
197
|
+
ResultCode: 'LINT_FAILED',
|
|
198
|
+
Message: 'Spec failed linting.',
|
|
199
|
+
});
|
|
200
|
+
const svc = new InteractiveFormApplyService();
|
|
201
|
+
const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());
|
|
202
|
+
expect(result.Success).toBe(false);
|
|
203
|
+
expect(hoisted.notifications.some(n => n.type === 'error')).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
//# sourceMappingURL=interactive-form-apply.service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-form-apply.service.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/interactive-form-apply.service.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * End-to-end-ish coverage for the Apply-to-my-form flow.\n *\n * The service is the join point that closes the chat-artifact → action loop:\n * form-aware artifact viewer → applyFormRequested →\n * conversation-chat-area / artifact-resource → ConfirmAndApply →\n * Get Active Form For Entity (action) → Create or Modify (action)\n *\n * These tests mock the dialog, notifications, and the GraphQL action\n * client so we can drive both branches (no-existing → Create; existing →\n * Modify) and the cancellation path, plus the failure surfaces. Without\n * this suite the original \"Apply button is wired to nothing\" bug would\n * regress silently — the unit tests on the actions wouldn't notice.\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\nimport type { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n// ─── Hoisted state buckets the mocks read/write ──────────────────────────\n\nconst hoisted = vi.hoisted(() => ({\n dialogResult: 'apply' as 'apply' | 'cancel',\n actionResponses: new Map<string, { Success: boolean; Message?: string; ResultCode?: string }>(),\n actionCalls: [] as Array<{ id: string; params: unknown }>,\n runViewResponses: [] as Array<{ Success: boolean; Results: Array<{ ID: string }>; ErrorMessage?: string }>,\n notifications: [] as Array<{ message: string; type: string }>,\n}));\n\n// ─── Module mocks ────────────────────────────────────────────────────────\n\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n inject: (token: { Instance?: unknown } | typeof Object) => {\n // Return the mock singletons by class identity.\n const name = (token as { name?: string }).name ?? '';\n if (name === 'MJDialogService') return mockDialog;\n if (name === 'MJNotificationService') return mockNotifications;\n return {};\n },\n}));\n\nconst mockDialog = {\n Open: () => ({\n Result: {\n subscribe: (cb: (r: { result: string }) => void) => {\n cb({ result: hoisted.dialogResult });\n },\n },\n }),\n};\n\nconst mockNotifications = {\n CreateSimpleNotification: (message: string, type: string) => {\n hoisted.notifications.push({ message, type });\n },\n};\n\nvi.mock('@memberjunction/ng-ui-components', () => ({ MJDialogService: class MJDialogService {} }));\nvi.mock('@memberjunction/ng-notifications', () => ({ MJNotificationService: class MJNotificationService {} }));\n\nvi.mock('@memberjunction/graphql-dataprovider', () => ({\n GraphQLActionClient: class {\n async RunAction(actionId: string, params: unknown) {\n hoisted.actionCalls.push({ id: actionId, params });\n return hoisted.actionResponses.get(actionId) ?? { Success: false, Message: 'mock: no response set' };\n }\n },\n GraphQLDataProvider: class {},\n}));\n\nvi.mock('@memberjunction/core', async () => {\n const actual = await vi.importActual<Record<string, unknown>>('@memberjunction/core');\n return {\n ...actual,\n Metadata: { Provider: null },\n LogError: vi.fn(),\n RunView: class {\n async RunView() {\n return hoisted.runViewResponses.shift() ?? { Success: true, Results: [] };\n }\n },\n };\n});\n\n// ─── Test setup ──────────────────────────────────────────────────────────\n\nimport { InteractiveFormApplyService } from '../services/interactive-form-apply.service';\n\nfunction mockProvider(overrides: Partial<{ EntityByName: () => unknown; CurrentUser: unknown }> = {}) {\n return {\n EntityByName: () => ({ ID: 'ENT-1', Name: 'MJ: Apps' }),\n CurrentUser: { ID: 'U1', Name: 'Test' },\n ExecuteGQL: () => Promise.resolve({}), // marks it as a GraphQL provider\n ...overrides,\n } as unknown as Parameters<InteractiveFormApplyService['ConfirmAndApply']>[2];\n}\n\nfunction spec(over: Partial<ComponentSpec> = {}): ComponentSpec {\n return { name: 'Form', componentRole: 'form', location: 'embedded', code: '() => null', ...over } as ComponentSpec;\n}\n\nbeforeEach(() => {\n hoisted.dialogResult = 'apply';\n hoisted.actionResponses.clear();\n hoisted.actionCalls.length = 0;\n hoisted.runViewResponses.length = 0;\n hoisted.notifications.length = 0;\n});\n\ndescribe('InteractiveFormApplyService', () => {\n\n it('returns failure when no metadata provider is available', async () => {\n const svc = new InteractiveFormApplyService();\n // No provider — neither passed nor on Metadata.Provider.\n const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps');\n expect(result.Success).toBe(false);\n expect(result.Message).toMatch(/No metadata provider/);\n });\n\n it('returns failure when the declared entity is not registered', async () => {\n const svc = new InteractiveFormApplyService();\n const provider = mockProvider({ EntityByName: () => undefined });\n const result = await svc.ConfirmAndApply(spec(), 'MJ: NotAnEntity', provider);\n expect(result.Success).toBe(false);\n expect(result.Message).toMatch(/not registered/);\n });\n\n it('cancellation by user yields a friendly failure result, no action invoked', async () => {\n hoisted.dialogResult = 'cancel';\n // Seed action-id lookup so the path past dialog is reachable in case the\n // implementation order changes; with dialog returning 'cancel' the\n // Create action should never be called.\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });\n hoisted.actionResponses.set('ACT-GET-ACTIVE', {\n Success: true,\n Message: JSON.stringify({ Active: null, Variants: [] }),\n });\n\n const svc = new InteractiveFormApplyService();\n const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());\n expect(result.Success).toBe(false);\n expect(result.Message).toMatch(/Cancelled/);\n // Only Get Active Form should have been called (to populate dialog text);\n // Create / Modify should NOT have been called.\n const calls = hoisted.actionCalls.map(c => c.id);\n expect(calls.filter(id => id !== 'ACT-GET-ACTIVE')).toEqual([]);\n });\n\n it('no existing override → calls Create Interactive Form', async () => {\n // RunView lookups: each call resolves the next action ID.\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-CREATE' }] });\n hoisted.actionResponses.set('ACT-GET-ACTIVE', {\n Success: true,\n Message: JSON.stringify({ Active: null, Variants: [] }),\n });\n hoisted.actionResponses.set('ACT-CREATE', {\n Success: true,\n Message: JSON.stringify({ ComponentID: 'NEW-COMP', OverrideID: 'NEW-OVER', Version: '1.0.0' }),\n });\n\n const svc = new InteractiveFormApplyService();\n const result = await svc.ConfirmAndApply(spec({ name: 'CompactForm' }), 'MJ: Apps', mockProvider());\n\n expect(result.Success).toBe(true);\n expect(result.Mode).toBe('create');\n expect(result.OverrideID).toBe('NEW-OVER');\n expect(result.Version).toBe('1.0.0');\n const calls = hoisted.actionCalls.map(c => c.id);\n expect(calls).toEqual(['ACT-GET-ACTIVE', 'ACT-CREATE']);\n // Success notification surfaced.\n expect(hoisted.notifications.some(n => n.type === 'success')).toBe(true);\n });\n\n it('existing Active override → calls Modify Interactive Form (Pending sibling produced)', async () => {\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-MODIFY' }] });\n hoisted.actionResponses.set('ACT-GET-ACTIVE', {\n Success: true,\n Message: JSON.stringify({\n Active: { OverrideID: 'OVER-EXISTING', ComponentID: 'COMP-EXISTING', ComponentVersion: '1.0.0' },\n Variants: [],\n }),\n });\n hoisted.actionResponses.set('ACT-MODIFY', {\n Success: true,\n Message: JSON.stringify({ Mode: 'new-version', ComponentID: 'NEW-COMP', OverrideID: 'NEW-OVER', Version: '1.1.0' }),\n });\n\n const svc = new InteractiveFormApplyService();\n const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());\n\n expect(result.Success).toBe(true);\n expect(result.Mode).toBe('modify-new-version');\n expect(result.Version).toBe('1.1.0');\n const calls = hoisted.actionCalls.map(c => c.id);\n expect(calls).toEqual(['ACT-GET-ACTIVE', 'ACT-MODIFY']);\n });\n\n it('Get Active failure short-circuits with an error', async () => {\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });\n hoisted.actionResponses.set('ACT-GET-ACTIVE', {\n Success: false,\n Message: 'DB unavailable',\n });\n\n const svc = new InteractiveFormApplyService();\n const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());\n expect(result.Success).toBe(false);\n expect(result.Message).toMatch(/Could not check for existing override/);\n });\n\n it('failure on the Create action surfaces the error notification', async () => {\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-GET-ACTIVE' }] });\n hoisted.runViewResponses.push({ Success: true, Results: [{ ID: 'ACT-CREATE' }] });\n hoisted.actionResponses.set('ACT-GET-ACTIVE', {\n Success: true,\n Message: JSON.stringify({ Active: null, Variants: [] }),\n });\n hoisted.actionResponses.set('ACT-CREATE', {\n Success: false,\n ResultCode: 'LINT_FAILED',\n Message: 'Spec failed linting.',\n });\n\n const svc = new InteractiveFormApplyService();\n const result = await svc.ConfirmAndApply(spec(), 'MJ: Apps', mockProvider());\n expect(result.Success).toBe(false);\n expect(hoisted.notifications.some(n => n.type === 'error')).toBe(true);\n });\n});\n"]}
|
|
@@ -17,17 +17,19 @@ import * as i14 from "./components/file-artifact-toolbar.component";
|
|
|
17
17
|
import * as i15 from "./components/plugins/pdf-artifact-viewer.component";
|
|
18
18
|
import * as i16 from "./components/plugins/xlsx-artifact-viewer.component";
|
|
19
19
|
import * as i17 from "./components/plugins/docx-artifact-viewer.component";
|
|
20
|
-
import * as i18 from "
|
|
21
|
-
import * as i19 from "@angular/
|
|
22
|
-
import * as i20 from "@
|
|
23
|
-
import * as i21 from "@memberjunction/ng-
|
|
24
|
-
import * as i22 from "@memberjunction/ng-
|
|
25
|
-
import * as i23 from "@memberjunction/ng-
|
|
26
|
-
import * as i24 from "@memberjunction/ng-
|
|
27
|
-
import * as i25 from "@memberjunction/ng-
|
|
28
|
-
import * as i26 from "@memberjunction/ng-
|
|
29
|
-
import * as i27 from "
|
|
30
|
-
import * as i28 from "
|
|
20
|
+
import * as i18 from "./components/plugins/image-artifact-viewer.component";
|
|
21
|
+
import * as i19 from "@angular/common";
|
|
22
|
+
import * as i20 from "@angular/forms";
|
|
23
|
+
import * as i21 from "@memberjunction/ng-markdown";
|
|
24
|
+
import * as i22 from "@memberjunction/ng-code-editor";
|
|
25
|
+
import * as i23 from "@memberjunction/ng-react";
|
|
26
|
+
import * as i24 from "@memberjunction/ng-notifications";
|
|
27
|
+
import * as i25 from "@memberjunction/ng-query-viewer";
|
|
28
|
+
import * as i26 from "@memberjunction/ng-shared-generic";
|
|
29
|
+
import * as i27 from "@memberjunction/ng-trees";
|
|
30
|
+
import * as i28 from "@memberjunction/ng-base-forms";
|
|
31
|
+
import * as i29 from "./components/plugins/component-feedback-panel/component-feedback-panel.component";
|
|
32
|
+
import * as i30 from "ag-grid-angular";
|
|
31
33
|
/**
|
|
32
34
|
* Module for artifact viewer plugin system.
|
|
33
35
|
* Provides components for viewing different types of artifacts (JSON, Code, Markdown, HTML, SVG, Components).
|
|
@@ -39,7 +41,7 @@ export declare class ArtifactsModule {
|
|
|
39
41
|
private adapter;
|
|
40
42
|
constructor(adapter: AngularAdapterService);
|
|
41
43
|
static ɵfac: i0.ɵɵFactoryDeclaration<ArtifactsModule, never>;
|
|
42
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<ArtifactsModule, [typeof i1.ArtifactTypePluginViewerComponent, typeof i2.ArtifactViewerPanelComponent, typeof i3.ArtifactVersionHistoryComponent, typeof i4.ArtifactMessageCardComponent, typeof i5.JsonArtifactViewerComponent, typeof i6.CodeArtifactViewerComponent, typeof i7.MarkdownArtifactViewerComponent, typeof i8.HtmlArtifactViewerComponent, typeof i9.SvgArtifactViewerComponent, typeof i10.ComponentArtifactViewerComponent, typeof i11.DataArtifactViewerComponent, typeof i12.SaveQueryPanelComponent, typeof i13.DataRequirementsViewerComponent, typeof i14.FileArtifactToolbarComponent, typeof i15.PdfArtifactViewerComponent, typeof i16.XlsxArtifactViewerComponent, typeof i17.DocxArtifactViewerComponent], [typeof
|
|
44
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<ArtifactsModule, [typeof i1.ArtifactTypePluginViewerComponent, typeof i2.ArtifactViewerPanelComponent, typeof i3.ArtifactVersionHistoryComponent, typeof i4.ArtifactMessageCardComponent, typeof i5.JsonArtifactViewerComponent, typeof i6.CodeArtifactViewerComponent, typeof i7.MarkdownArtifactViewerComponent, typeof i8.HtmlArtifactViewerComponent, typeof i9.SvgArtifactViewerComponent, typeof i10.ComponentArtifactViewerComponent, typeof i11.DataArtifactViewerComponent, typeof i12.SaveQueryPanelComponent, typeof i13.DataRequirementsViewerComponent, typeof i14.FileArtifactToolbarComponent, typeof i15.PdfArtifactViewerComponent, typeof i16.XlsxArtifactViewerComponent, typeof i17.DocxArtifactViewerComponent, typeof i18.ImageArtifactViewerComponent], [typeof i19.CommonModule, typeof i20.FormsModule, typeof i21.MarkdownModule, typeof i22.CodeEditorModule, typeof i23.MJReactModule, typeof i24.MJNotificationsModule, typeof i25.QueryViewerModule, typeof i26.SharedGenericModule, typeof i27.NgTreesModule, typeof i28.BaseFormsModule, typeof i29.ComponentFeedbackPanelComponent, typeof i30.AgGridModule], [typeof i1.ArtifactTypePluginViewerComponent, typeof i2.ArtifactViewerPanelComponent, typeof i3.ArtifactVersionHistoryComponent, typeof i4.ArtifactMessageCardComponent, typeof i5.JsonArtifactViewerComponent, typeof i6.CodeArtifactViewerComponent, typeof i7.MarkdownArtifactViewerComponent, typeof i8.HtmlArtifactViewerComponent, typeof i9.SvgArtifactViewerComponent, typeof i10.ComponentArtifactViewerComponent, typeof i11.DataArtifactViewerComponent, typeof i14.FileArtifactToolbarComponent, typeof i15.PdfArtifactViewerComponent, typeof i16.XlsxArtifactViewerComponent, typeof i17.DocxArtifactViewerComponent, typeof i18.ImageArtifactViewerComponent]>;
|
|
43
45
|
static ɵinj: i0.ɵɵInjectorDeclaration<ArtifactsModule>;
|
|
44
46
|
}
|
|
45
47
|
//# sourceMappingURL=artifacts.module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.module.d.ts","sourceRoot":"","sources":["../../src/lib/artifacts.module.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,qBAAqB,EAAE,MAAM,0BAA0B,CAAC
|
|
1
|
+
{"version":3,"file":"artifacts.module.d.ts","sourceRoot":"","sources":["../../src/lib/artifacts.module.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkChF;;;;;;GAMG;AACH,qBAyEa,eAAe;IACd,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,qBAAqB;yCADvC,eAAe;0CAAf,eAAe;0CAAf,eAAe;CAuB3B"}
|
|
@@ -10,6 +10,9 @@ import { MJNotificationsModule } from '@memberjunction/ng-notifications';
|
|
|
10
10
|
import { QueryViewerModule } from '@memberjunction/ng-query-viewer';
|
|
11
11
|
import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
|
|
12
12
|
import { NgTreesModule } from '@memberjunction/ng-trees';
|
|
13
|
+
// BaseFormsModule supplies `<mj-interactive-form>` for the form-aware
|
|
14
|
+
// component-artifact viewer branch (componentRole === 'form').
|
|
15
|
+
import { BaseFormsModule } from '@memberjunction/ng-base-forms';
|
|
13
16
|
// Import plugin components (note: base component is abstract and NOT declared)
|
|
14
17
|
import { JsonArtifactViewerComponent } from './components/plugins/json-artifact-viewer.component';
|
|
15
18
|
import { CodeArtifactViewerComponent } from './components/plugins/code-artifact-viewer.component';
|
|
@@ -26,6 +29,7 @@ import { FileArtifactToolbarComponent } from './components/file-artifact-toolbar
|
|
|
26
29
|
import { PdfArtifactViewerComponent } from './components/plugins/pdf-artifact-viewer.component';
|
|
27
30
|
import { XlsxArtifactViewerComponent } from './components/plugins/xlsx-artifact-viewer.component';
|
|
28
31
|
import { DocxArtifactViewerComponent } from './components/plugins/docx-artifact-viewer.component';
|
|
32
|
+
import { ImageArtifactViewerComponent } from './components/plugins/image-artifact-viewer.component';
|
|
29
33
|
// Import artifact type plugin viewer component
|
|
30
34
|
import { ArtifactTypePluginViewerComponent } from './components/artifact-type-plugin-viewer.component';
|
|
31
35
|
import { ArtifactVersionHistoryComponent } from './components/artifact-version-history.component';
|
|
@@ -57,6 +61,7 @@ export class ArtifactsModule {
|
|
|
57
61
|
PdfArtifactViewerComponent,
|
|
58
62
|
XlsxArtifactViewerComponent,
|
|
59
63
|
DocxArtifactViewerComponent,
|
|
64
|
+
ImageArtifactViewerComponent,
|
|
60
65
|
];
|
|
61
66
|
// PERF: Eagerly start downloading React, ReactDOM, and Babel from CDN in the background.
|
|
62
67
|
// By the time a user opens an interactive component artifact, the scripts will already
|
|
@@ -74,6 +79,7 @@ export class ArtifactsModule {
|
|
|
74
79
|
QueryViewerModule,
|
|
75
80
|
SharedGenericModule,
|
|
76
81
|
NgTreesModule,
|
|
82
|
+
BaseFormsModule,
|
|
77
83
|
ComponentFeedbackPanelComponent,
|
|
78
84
|
AgGridModule] });
|
|
79
85
|
}
|
|
@@ -103,6 +109,7 @@ export class ArtifactsModule {
|
|
|
103
109
|
PdfArtifactViewerComponent,
|
|
104
110
|
XlsxArtifactViewerComponent,
|
|
105
111
|
DocxArtifactViewerComponent,
|
|
112
|
+
ImageArtifactViewerComponent,
|
|
106
113
|
],
|
|
107
114
|
imports: [
|
|
108
115
|
CommonModule,
|
|
@@ -114,6 +121,7 @@ export class ArtifactsModule {
|
|
|
114
121
|
QueryViewerModule,
|
|
115
122
|
SharedGenericModule,
|
|
116
123
|
NgTreesModule,
|
|
124
|
+
BaseFormsModule,
|
|
117
125
|
ComponentFeedbackPanelComponent,
|
|
118
126
|
AgGridModule,
|
|
119
127
|
],
|
|
@@ -137,6 +145,7 @@ export class ArtifactsModule {
|
|
|
137
145
|
PdfArtifactViewerComponent,
|
|
138
146
|
XlsxArtifactViewerComponent,
|
|
139
147
|
DocxArtifactViewerComponent,
|
|
148
|
+
ImageArtifactViewerComponent,
|
|
140
149
|
],
|
|
141
150
|
providers: [
|
|
142
151
|
// Plugins are registered via @RegisterClass decorator on component classes, no providers needed
|
|
@@ -165,7 +174,8 @@ export class ArtifactsModule {
|
|
|
165
174
|
FileArtifactToolbarComponent,
|
|
166
175
|
PdfArtifactViewerComponent,
|
|
167
176
|
XlsxArtifactViewerComponent,
|
|
168
|
-
DocxArtifactViewerComponent
|
|
177
|
+
DocxArtifactViewerComponent,
|
|
178
|
+
ImageArtifactViewerComponent], imports: [CommonModule,
|
|
169
179
|
FormsModule,
|
|
170
180
|
MarkdownModule,
|
|
171
181
|
CodeEditorModule,
|
|
@@ -174,6 +184,7 @@ export class ArtifactsModule {
|
|
|
174
184
|
QueryViewerModule,
|
|
175
185
|
SharedGenericModule,
|
|
176
186
|
NgTreesModule,
|
|
187
|
+
BaseFormsModule,
|
|
177
188
|
ComponentFeedbackPanelComponent,
|
|
178
189
|
AgGridModule], exports: [
|
|
179
190
|
// Export artifact type plugin viewer
|
|
@@ -194,5 +205,6 @@ export class ArtifactsModule {
|
|
|
194
205
|
FileArtifactToolbarComponent,
|
|
195
206
|
PdfArtifactViewerComponent,
|
|
196
207
|
XlsxArtifactViewerComponent,
|
|
197
|
-
DocxArtifactViewerComponent
|
|
208
|
+
DocxArtifactViewerComponent,
|
|
209
|
+
ImageArtifactViewerComponent] }); })();
|
|
198
210
|
//# sourceMappingURL=artifacts.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.module.js","sourceRoot":"","sources":["../../src/lib/artifacts.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\nimport { AgGridModule } from 'ag-grid-angular';\n\n// Import MJ modules\nimport { CodeEditorModule } from '@memberjunction/ng-code-editor';\nimport { MJReactModule, AngularAdapterService } from '@memberjunction/ng-react';\nimport { MJNotificationsModule } from '@memberjunction/ng-notifications';\nimport { QueryViewerModule } from '@memberjunction/ng-query-viewer';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { NgTreesModule } from '@memberjunction/ng-trees';\n\n// Import plugin components (note: base component is abstract and NOT declared)\nimport { JsonArtifactViewerComponent } from './components/plugins/json-artifact-viewer.component';\nimport { CodeArtifactViewerComponent } from './components/plugins/code-artifact-viewer.component';\nimport { MarkdownArtifactViewerComponent } from './components/plugins/markdown-artifact-viewer.component';\nimport { HtmlArtifactViewerComponent } from './components/plugins/html-artifact-viewer.component';\nimport { SvgArtifactViewerComponent } from './components/plugins/svg-artifact-viewer.component';\nimport { ComponentArtifactViewerComponent } from './components/plugins/component-artifact-viewer.component';\nimport { DataArtifactViewerComponent } from './components/plugins/data-artifact-viewer.component';\nimport { SaveQueryPanelComponent } from './components/plugins/save-query-dialog.component';\nimport { DataRequirementsViewerComponent } from './components/plugins/data-requirements-viewer/data-requirements-viewer.component';\nimport { ComponentFeedbackPanelComponent } from './components/plugins/component-feedback-panel/component-feedback-panel.component';\n\n// File viewer plugins\nimport { FileArtifactToolbarComponent } from './components/file-artifact-toolbar.component';\nimport { PdfArtifactViewerComponent } from './components/plugins/pdf-artifact-viewer.component';\nimport { XlsxArtifactViewerComponent } from './components/plugins/xlsx-artifact-viewer.component';\nimport { DocxArtifactViewerComponent } from './components/plugins/docx-artifact-viewer.component';\n\n// Import artifact type plugin viewer component\nimport { ArtifactTypePluginViewerComponent } from './components/artifact-type-plugin-viewer.component';\nimport { ArtifactVersionHistoryComponent } from './components/artifact-version-history.component';\nimport { ArtifactViewerPanelComponent } from './components/artifact-viewer-panel.component';\nimport { ArtifactMessageCardComponent } from './components/artifact-message-card.component';\n\n/**\n * Module for artifact viewer plugin system.\n * Provides components for viewing different types of artifacts (JSON, Code, Markdown, HTML, SVG, Components).\n *\n * Plugins are automatically registered via @RegisterClass decorator and can be instantiated\n * using MJGlobal.Instance.ClassFactory.CreateInstance('PluginClassName').\n */\n@NgModule({\n declarations: [\n // Artifact type plugin viewer (loads appropriate plugin based on DriverClass)\n ArtifactTypePluginViewerComponent,\n\n // Artifact viewer UI components\n ArtifactViewerPanelComponent,\n ArtifactVersionHistoryComponent,\n ArtifactMessageCardComponent,\n\n // Plugin components\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n SaveQueryPanelComponent,\n\n // Custom tab components (used by plugins via dynamic component tabs)\n DataRequirementsViewerComponent,\n\n // File viewer toolbar and plugins\n FileArtifactToolbarComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ],\n imports: [\n CommonModule,\n FormsModule,\n MarkdownModule,\n CodeEditorModule,\n MJReactModule,\n MJNotificationsModule,\n QueryViewerModule,\n SharedGenericModule,\n NgTreesModule,\n ComponentFeedbackPanelComponent,\n AgGridModule,\n ],\n exports: [\n // Export artifact type plugin viewer\n ArtifactTypePluginViewerComponent,\n\n // Export artifact viewer UI components\n ArtifactViewerPanelComponent,\n ArtifactVersionHistoryComponent,\n ArtifactMessageCardComponent,\n\n // Export plugin components\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n\n // File viewer toolbar and plugins\n FileArtifactToolbarComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ],\n providers: [\n // Plugins are registered via @RegisterClass decorator on component classes, no providers needed\n ]\n})\nexport class ArtifactsModule {\n constructor(private adapter: AngularAdapterService) {\n // Ensure plugin components are registered on module load by referencing their classes\n // The @RegisterClass decorator on each component handles the actual registration with MJGlobal\n [\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ];\n\n // PERF: Eagerly start downloading React, ReactDOM, and Babel from CDN in the background.\n // By the time a user opens an interactive component artifact, the scripts will already\n // be cached. The adapter.preload() is non-blocking and deduplicates with initialize().\n this.adapter.preload();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifacts.module.js","sourceRoot":"","sources":["../../src/lib/artifacts.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\nimport { AgGridModule } from 'ag-grid-angular';\n\n// Import MJ modules\nimport { CodeEditorModule } from '@memberjunction/ng-code-editor';\nimport { MJReactModule, AngularAdapterService } from '@memberjunction/ng-react';\nimport { MJNotificationsModule } from '@memberjunction/ng-notifications';\nimport { QueryViewerModule } from '@memberjunction/ng-query-viewer';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { NgTreesModule } from '@memberjunction/ng-trees';\n// BaseFormsModule supplies `<mj-interactive-form>` for the form-aware\n// component-artifact viewer branch (componentRole === 'form').\nimport { BaseFormsModule } from '@memberjunction/ng-base-forms';\n\n// Import plugin components (note: base component is abstract and NOT declared)\nimport { JsonArtifactViewerComponent } from './components/plugins/json-artifact-viewer.component';\nimport { CodeArtifactViewerComponent } from './components/plugins/code-artifact-viewer.component';\nimport { MarkdownArtifactViewerComponent } from './components/plugins/markdown-artifact-viewer.component';\nimport { HtmlArtifactViewerComponent } from './components/plugins/html-artifact-viewer.component';\nimport { SvgArtifactViewerComponent } from './components/plugins/svg-artifact-viewer.component';\nimport { ComponentArtifactViewerComponent } from './components/plugins/component-artifact-viewer.component';\nimport { DataArtifactViewerComponent } from './components/plugins/data-artifact-viewer.component';\nimport { SaveQueryPanelComponent } from './components/plugins/save-query-dialog.component';\nimport { DataRequirementsViewerComponent } from './components/plugins/data-requirements-viewer/data-requirements-viewer.component';\nimport { ComponentFeedbackPanelComponent } from './components/plugins/component-feedback-panel/component-feedback-panel.component';\n\n// File viewer plugins\nimport { FileArtifactToolbarComponent } from './components/file-artifact-toolbar.component';\nimport { PdfArtifactViewerComponent } from './components/plugins/pdf-artifact-viewer.component';\nimport { XlsxArtifactViewerComponent } from './components/plugins/xlsx-artifact-viewer.component';\nimport { DocxArtifactViewerComponent } from './components/plugins/docx-artifact-viewer.component';\nimport { ImageArtifactViewerComponent } from './components/plugins/image-artifact-viewer.component';\n\n// Import artifact type plugin viewer component\nimport { ArtifactTypePluginViewerComponent } from './components/artifact-type-plugin-viewer.component';\nimport { ArtifactVersionHistoryComponent } from './components/artifact-version-history.component';\nimport { ArtifactViewerPanelComponent } from './components/artifact-viewer-panel.component';\nimport { ArtifactMessageCardComponent } from './components/artifact-message-card.component';\n\n/**\n * Module for artifact viewer plugin system.\n * Provides components for viewing different types of artifacts (JSON, Code, Markdown, HTML, SVG, Components).\n *\n * Plugins are automatically registered via @RegisterClass decorator and can be instantiated\n * using MJGlobal.Instance.ClassFactory.CreateInstance('PluginClassName').\n */\n@NgModule({\n declarations: [\n // Artifact type plugin viewer (loads appropriate plugin based on DriverClass)\n ArtifactTypePluginViewerComponent,\n\n // Artifact viewer UI components\n ArtifactViewerPanelComponent,\n ArtifactVersionHistoryComponent,\n ArtifactMessageCardComponent,\n\n // Plugin components\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n SaveQueryPanelComponent,\n\n // Custom tab components (used by plugins via dynamic component tabs)\n DataRequirementsViewerComponent,\n\n // File viewer toolbar and plugins\n FileArtifactToolbarComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ImageArtifactViewerComponent,\n ],\n imports: [\n CommonModule,\n FormsModule,\n MarkdownModule,\n CodeEditorModule,\n MJReactModule,\n MJNotificationsModule,\n QueryViewerModule,\n SharedGenericModule,\n NgTreesModule,\n BaseFormsModule,\n ComponentFeedbackPanelComponent,\n AgGridModule,\n ],\n exports: [\n // Export artifact type plugin viewer\n ArtifactTypePluginViewerComponent,\n\n // Export artifact viewer UI components\n ArtifactViewerPanelComponent,\n ArtifactVersionHistoryComponent,\n ArtifactMessageCardComponent,\n\n // Export plugin components\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n\n // File viewer toolbar and plugins\n FileArtifactToolbarComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ImageArtifactViewerComponent,\n ],\n providers: [\n // Plugins are registered via @RegisterClass decorator on component classes, no providers needed\n ]\n})\nexport class ArtifactsModule {\n constructor(private adapter: AngularAdapterService) {\n // Ensure plugin components are registered on module load by referencing their classes\n // The @RegisterClass decorator on each component handles the actual registration with MJGlobal\n [\n JsonArtifactViewerComponent,\n CodeArtifactViewerComponent,\n MarkdownArtifactViewerComponent,\n HtmlArtifactViewerComponent,\n SvgArtifactViewerComponent,\n ComponentArtifactViewerComponent,\n DataArtifactViewerComponent,\n PdfArtifactViewerComponent,\n XlsxArtifactViewerComponent,\n DocxArtifactViewerComponent,\n ImageArtifactViewerComponent,\n ];\n\n // PERF: Eagerly start downloading React, ReactDOM, and Babel from CDN in the background.\n // By the time a user opens an interactive component artifact, the scripts will already\n // be cached. The adapter.preload() is non-blocking and deduplicates with initialize().\n this.adapter.preload();\n }\n}\n"]}
|
|
@@ -22,6 +22,16 @@ export declare class ArtifactTypePluginViewerComponent extends BaseAngularCompon
|
|
|
22
22
|
navigationRequest: EventEmitter<NavigationRequest>;
|
|
23
23
|
pluginLoaded: EventEmitter<void>;
|
|
24
24
|
tabsChanged: EventEmitter<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Bubbled up from the component-artifact-viewer's form-aware branch when
|
|
27
|
+
* the user clicks "Apply to my form". Carries the spec + entity so the
|
|
28
|
+
* consumer (chat message card, conversation host) can invoke the
|
|
29
|
+
* Create-or-Modify Interactive Form action behind a confirmation dialog.
|
|
30
|
+
*/
|
|
31
|
+
applyFormRequested: EventEmitter<{
|
|
32
|
+
spec: unknown;
|
|
33
|
+
entityName: string;
|
|
34
|
+
}>;
|
|
25
35
|
viewerContainer: ViewContainerRef;
|
|
26
36
|
isLoading: boolean;
|
|
27
37
|
error: string | null;
|
|
@@ -78,6 +88,6 @@ export declare class ArtifactTypePluginViewerComponent extends BaseAngularCompon
|
|
|
78
88
|
*/
|
|
79
89
|
private destroyCurrentViewer;
|
|
80
90
|
static ɵfac: i0.ɵɵFactoryDeclaration<ArtifactTypePluginViewerComponent, never>;
|
|
81
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ArtifactTypePluginViewerComponent, "mj-artifact-type-plugin-viewer", never, { "artifactVersion": { "alias": "artifactVersion"; "required": false; }; "artifactTypeName": { "alias": "artifactTypeName"; "required": false; }; "contentType": { "alias": "contentType"; "required": false; }; "height": { "alias": "height"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "cssClass": { "alias": "cssClass"; "required": false; }; }, { "openEntityRecord": "openEntityRecord"; "navigationRequest": "navigationRequest"; "pluginLoaded": "pluginLoaded"; "tabsChanged": "tabsChanged"; }, never, never, false, never>;
|
|
91
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ArtifactTypePluginViewerComponent, "mj-artifact-type-plugin-viewer", never, { "artifactVersion": { "alias": "artifactVersion"; "required": false; }; "artifactTypeName": { "alias": "artifactTypeName"; "required": false; }; "contentType": { "alias": "contentType"; "required": false; }; "height": { "alias": "height"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "cssClass": { "alias": "cssClass"; "required": false; }; }, { "openEntityRecord": "openEntityRecord"; "navigationRequest": "navigationRequest"; "pluginLoaded": "pluginLoaded"; "tabsChanged": "tabsChanged"; "applyFormRequested": "applyFormRequested"; }, never, never, false, never>;
|
|
82
92
|
}
|
|
83
93
|
//# sourceMappingURL=artifact-type-plugin-viewer.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-type-plugin-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/artifact-type-plugin-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACZ,MAAM,EACN,SAAS,EACT,aAAa,EAEb,gBAAgB,EAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,uBAAuB,EAAgD,MAAM,+BAA+B,CAAC;AACtH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAA+B,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGjF,OAAO,EAAE,iCAAiC,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;;AAExG;;;GAGG;AACH,qBA2Fa,iCAAkC,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC7F,eAAe,EAAG,uBAAuB,CAAC;IAC1C,gBAAgB,EAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAQ;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAEjB,gBAAgB;oBAAiC,MAAM;sBAAgB,YAAY;OAAK;IACxF,iBAAiB,kCAAyC;IAC1D,YAAY,qBAA4B;IACxC,WAAW,qBAA4B;
|
|
1
|
+
{"version":3,"file":"artifact-type-plugin-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/artifact-type-plugin-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACZ,MAAM,EACN,SAAS,EACT,aAAa,EAEb,gBAAgB,EAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,uBAAuB,EAAgD,MAAM,+BAA+B,CAAC;AACtH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAA+B,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGjF,OAAO,EAAE,iCAAiC,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;;AAExG;;;GAGG;AACH,qBA2Fa,iCAAkC,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC7F,eAAe,EAAG,uBAAuB,CAAC;IAC1C,gBAAgB,EAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAQ;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAEjB,gBAAgB;oBAAiC,MAAM;sBAAgB,YAAY;OAAK;IACxF,iBAAiB,kCAAyC;IAC1D,YAAY,qBAA4B;IACxC,WAAW,qBAA4B;IACjD;;;;;OAKG;IACO,kBAAkB;cAA4B,OAAO;oBAAc,MAAM;OAAM;IAGzF,eAAe,EAAG,gBAAgB,CAAC;IAE5B,SAAS,UAAQ;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC,OAAO,CAAC,YAAY,CAAkC;IAEtD;;OAEG;IACH,IAAW,cAAc,IAAI,iCAAiC,GAAG,IAAI,CAEpE;IAED;;;OAGG;IACH,IAAW,gBAAgB,IAAI,OAAO,CAErC;IAED;;;OAGG;IACI,kBAAkB,IAAI,IAAI;IAI3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxD,WAAW,IAAI,IAAI;IAInB;;OAEG;YACW,UAAU;IAoJxB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAMhB;;OAEG;YACW,eAAe;IAW7B;;;;;;OAMG;YACW,kBAAkB;IAyBhC;;OAEG;YACW,mBAAmB;IAiBjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;yCA7TjB,iCAAiC;2CAAjC,iCAAiC;CAoU7C"}
|