@memberjunction/ng-artifacts 6.1.4 → 6.2.0-edge.1
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/dist/lib/components/artifact-message-card.component.d.ts +60 -8
- package/dist/lib/components/artifact-message-card.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-message-card.component.js +135 -39
- package/dist/lib/components/artifact-message-card.component.js.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +58 -6
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.js +113 -35
- package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
- package/dist/lib/components/artifact-version-download.d.ts +5 -3
- package/dist/lib/components/artifact-version-download.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-download.js +11 -7
- package/dist/lib/components/artifact-version-download.js.map +1 -1
- package/dist/lib/components/artifact-version-history.component.d.ts +74 -8
- package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-history.component.js +152 -34
- package/dist/lib/components/artifact-version-history.component.js.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +328 -35
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +701 -213
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.d.ts +112 -10
- package/dist/lib/components/file-artifact-toolbar.component.d.ts.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.js +197 -23
- package/dist/lib/components/file-artifact-toolbar.component.js.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts +23 -5
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.js +69 -31
- package/dist/lib/components/plugins/code-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +136 -18
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +285 -97
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +2 -2
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +7 -7
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts +2 -0
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.js +6 -2
- package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts +17 -6
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +32 -22
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts +56 -4
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +142 -36
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts +14 -2
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js +32 -8
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/html-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +41 -5
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.js +102 -30
- package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +33 -5
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.js +89 -33
- package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts +12 -2
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js +28 -8
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +4 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +14 -6
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts +47 -5
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +129 -45
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts +5 -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 +12 -4
- package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts +28 -4
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +64 -16
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts +16 -2
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.js +35 -7
- package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
- package/dist/lib/interfaces/artifact-viewer-plugin.interface.js.map +1 -1
- package/dist/lib/services/artifact-file.service.d.ts +8 -0
- package/dist/lib/services/artifact-file.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-file.service.js +22 -6
- package/dist/lib/services/artifact-file.service.js.map +1 -1
- package/dist/lib/services/artifact-icon.service.d.ts +2 -0
- package/dist/lib/services/artifact-icon.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-icon.service.js +5 -1
- package/dist/lib/services/artifact-icon.service.js.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.d.ts +2 -0
- package/dist/lib/services/artifact-preview-resolver.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.js +5 -1
- package/dist/lib/services/artifact-preview-resolver.service.js.map +1 -1
- package/dist/lib/snapshot-helpers.d.ts +10 -0
- package/dist/lib/snapshot-helpers.d.ts.map +1 -1
- package/dist/lib/snapshot-helpers.js +25 -5
- package/dist/lib/snapshot-helpers.js.map +1 -1
- package/package.json +21 -21
|
@@ -11,7 +11,7 @@ import { BuildComponentCompleteCode } from '@memberjunction/interactive-componen
|
|
|
11
11
|
import { isFormRole, getDeclaredFormEntityName } from '@memberjunction/interactive-component-types/forms';
|
|
12
12
|
import { CompositeKey, DataSnapshot, LogError, RunView } from '@memberjunction/core';
|
|
13
13
|
import { DataRequirementsViewerComponent } from './data-requirements-viewer/data-requirements-viewer.component';
|
|
14
|
-
import {
|
|
14
|
+
import { EvaluateComponentPermissions } from './component-permission-evaluation';
|
|
15
15
|
import * as i0 from "@angular/core";
|
|
16
16
|
import * as i1 from "@memberjunction/ng-react";
|
|
17
17
|
import * as i2 from "@angular/common";
|
|
@@ -324,56 +324,212 @@ function ComponentArtifactViewerComponent_Conditional_6_Template(rf, ctx) { if (
|
|
|
324
324
|
let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
|
|
325
325
|
adapter;
|
|
326
326
|
cdr;
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
ReactComponent;
|
|
328
|
+
/** @deprecated Use {@link ReactComponent}. */
|
|
329
|
+
get reactComponent() {
|
|
330
|
+
return this.ReactComponent;
|
|
331
|
+
}
|
|
332
|
+
/** @deprecated Use {@link ReactComponent}. */
|
|
333
|
+
set reactComponent(value) {
|
|
334
|
+
this.ReactComponent = value;
|
|
335
|
+
}
|
|
336
|
+
InteractiveForm;
|
|
337
|
+
/** @deprecated Use {@link InteractiveForm}. */
|
|
338
|
+
get interactiveForm() {
|
|
339
|
+
return this.InteractiveForm;
|
|
340
|
+
}
|
|
341
|
+
/** @deprecated Use {@link InteractiveForm}. */
|
|
342
|
+
set interactiveForm(value) {
|
|
343
|
+
this.InteractiveForm = value;
|
|
344
|
+
}
|
|
329
345
|
tabsChanged = new EventEmitter();
|
|
330
|
-
|
|
346
|
+
OpenEntityRecord = new EventEmitter();
|
|
347
|
+
/**
|
|
348
|
+
* @deprecated Use {@link OpenEntityRecord}.
|
|
349
|
+
*
|
|
350
|
+
* The same emitter under the old binding name, so a template still binding
|
|
351
|
+
* (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
|
|
352
|
+
* initialise in order, and the other way round this captures undefined.
|
|
353
|
+
*/
|
|
354
|
+
openEntityRecord = this.OpenEntityRecord;
|
|
331
355
|
/**
|
|
332
356
|
* Emitted when the user clicks "Apply to my form" on a form-role artifact.
|
|
333
357
|
* Carries the spec (ready to hand to the agent's Create/Modify action) and
|
|
334
358
|
* the entity name. The host is responsible for confirming + invoking the
|
|
335
359
|
* actual server action.
|
|
336
360
|
*/
|
|
337
|
-
|
|
361
|
+
ApplyFormRequested = new EventEmitter();
|
|
362
|
+
/**
|
|
363
|
+
* @deprecated Use {@link ApplyFormRequested}.
|
|
364
|
+
*
|
|
365
|
+
* The same emitter under the old binding name, so a template still binding
|
|
366
|
+
* (applyFormRequested) keeps working. Must stay AFTER ApplyFormRequested: class fields
|
|
367
|
+
* initialise in order, and the other way round this captures undefined.
|
|
368
|
+
*/
|
|
369
|
+
applyFormRequested = this.ApplyFormRequested;
|
|
338
370
|
// ── Form-aware state (only populated when componentRole === 'form') ──
|
|
339
371
|
/** True when this artifact's spec declares `componentRole: 'form'`. */
|
|
340
|
-
|
|
372
|
+
IsFormArtifact = false;
|
|
373
|
+
/** @deprecated Use {@link IsFormArtifact}. */
|
|
374
|
+
get isFormArtifact() {
|
|
375
|
+
return this.IsFormArtifact;
|
|
376
|
+
}
|
|
377
|
+
/** @deprecated Use {@link IsFormArtifact}. */
|
|
378
|
+
set isFormArtifact(value) {
|
|
379
|
+
this.IsFormArtifact = value;
|
|
380
|
+
}
|
|
341
381
|
/** Entity the form targets — resolved from spec.entityName / dataRequirements. */
|
|
342
|
-
|
|
382
|
+
FormEntityInfo = null;
|
|
383
|
+
/** @deprecated Use {@link FormEntityInfo}. */
|
|
384
|
+
get formEntityInfo() {
|
|
385
|
+
return this.FormEntityInfo;
|
|
386
|
+
}
|
|
387
|
+
/** @deprecated Use {@link FormEntityInfo}. */
|
|
388
|
+
set formEntityInfo(value) {
|
|
389
|
+
this.FormEntityInfo = value;
|
|
390
|
+
}
|
|
343
391
|
/** The real or fixture record currently bound to the form preview. */
|
|
344
|
-
|
|
392
|
+
FormRecord = null;
|
|
393
|
+
/** @deprecated Use {@link FormRecord}. */
|
|
394
|
+
get formRecord() {
|
|
395
|
+
return this.FormRecord;
|
|
396
|
+
}
|
|
397
|
+
/** @deprecated Use {@link FormRecord}. */
|
|
398
|
+
set formRecord(value) {
|
|
399
|
+
this.FormRecord = value;
|
|
400
|
+
}
|
|
345
401
|
/** True iff `formRecord` is a real DB row (vs a fixture NewRecord()). */
|
|
346
|
-
|
|
402
|
+
FormRecordIsReal = false;
|
|
403
|
+
/** @deprecated Use {@link FormRecordIsReal}. */
|
|
404
|
+
get formRecordIsReal() {
|
|
405
|
+
return this.FormRecordIsReal;
|
|
406
|
+
}
|
|
407
|
+
/** @deprecated Use {@link FormRecordIsReal}. */
|
|
408
|
+
set formRecordIsReal(value) {
|
|
409
|
+
this.FormRecordIsReal = value;
|
|
410
|
+
}
|
|
347
411
|
/** Label for the chip (e.g. the record's Name field). */
|
|
348
|
-
|
|
412
|
+
FormRecordLabel = '';
|
|
413
|
+
/** @deprecated Use {@link FormRecordLabel}. */
|
|
414
|
+
get formRecordLabel() {
|
|
415
|
+
return this.FormRecordLabel;
|
|
416
|
+
}
|
|
417
|
+
/** @deprecated Use {@link FormRecordLabel}. */
|
|
418
|
+
set formRecordLabel(value) {
|
|
419
|
+
this.FormRecordLabel = value;
|
|
420
|
+
}
|
|
349
421
|
/** Picker UI state. */
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
422
|
+
ShowRecordPicker = false;
|
|
423
|
+
/** @deprecated Use {@link ShowRecordPicker}. */
|
|
424
|
+
get showRecordPicker() {
|
|
425
|
+
return this.ShowRecordPicker;
|
|
426
|
+
}
|
|
427
|
+
/** @deprecated Use {@link ShowRecordPicker}. */
|
|
428
|
+
set showRecordPicker(value) {
|
|
429
|
+
this.ShowRecordPicker = value;
|
|
430
|
+
}
|
|
431
|
+
RecordSearchTerm = '';
|
|
432
|
+
/** @deprecated Use {@link RecordSearchTerm}. */
|
|
433
|
+
get recordSearchTerm() {
|
|
434
|
+
return this.RecordSearchTerm;
|
|
435
|
+
}
|
|
436
|
+
/** @deprecated Use {@link RecordSearchTerm}. */
|
|
437
|
+
set recordSearchTerm(value) {
|
|
438
|
+
this.RecordSearchTerm = value;
|
|
439
|
+
}
|
|
440
|
+
RecordSearchResults = [];
|
|
441
|
+
/** @deprecated Use {@link RecordSearchResults}. */
|
|
442
|
+
get recordSearchResults() {
|
|
443
|
+
return this.RecordSearchResults;
|
|
444
|
+
}
|
|
445
|
+
/** @deprecated Use {@link RecordSearchResults}. */
|
|
446
|
+
set recordSearchResults(value) {
|
|
447
|
+
this.RecordSearchResults = value;
|
|
448
|
+
}
|
|
449
|
+
FormInitError = null;
|
|
450
|
+
/** @deprecated Use {@link FormInitError}. */
|
|
451
|
+
get formInitError() {
|
|
452
|
+
return this.FormInitError;
|
|
453
|
+
}
|
|
454
|
+
/** @deprecated Use {@link FormInitError}. */
|
|
455
|
+
set formInitError(value) {
|
|
456
|
+
this.FormInitError = value;
|
|
457
|
+
}
|
|
354
458
|
// Component data
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
459
|
+
Component = null;
|
|
460
|
+
/** @deprecated Use {@link Component}. */
|
|
461
|
+
get component() {
|
|
462
|
+
return this.Component;
|
|
463
|
+
}
|
|
464
|
+
/** @deprecated Use {@link Component}. */
|
|
465
|
+
set component(value) {
|
|
466
|
+
this.Component = value;
|
|
467
|
+
}
|
|
468
|
+
ComponentCode = "";
|
|
469
|
+
/** @deprecated Use {@link ComponentCode}. */
|
|
470
|
+
get componentCode() {
|
|
471
|
+
return this.ComponentCode;
|
|
472
|
+
}
|
|
473
|
+
/** @deprecated Use {@link ComponentCode}. */
|
|
474
|
+
set componentCode(value) {
|
|
475
|
+
this.ComponentCode = value;
|
|
476
|
+
}
|
|
477
|
+
ComponentName = '';
|
|
478
|
+
/** @deprecated Use {@link ComponentName}. */
|
|
479
|
+
get componentName() {
|
|
480
|
+
return this.ComponentName;
|
|
481
|
+
}
|
|
482
|
+
/** @deprecated Use {@link ComponentName}. */
|
|
483
|
+
set componentName(value) {
|
|
484
|
+
this.ComponentName = value;
|
|
485
|
+
}
|
|
358
486
|
/**
|
|
359
487
|
* Cached resolved spec from the registry, preserved even after the React component
|
|
360
488
|
* is destroyed (e.g., when a render error removes <mj-react-component> from the DOM).
|
|
361
489
|
*/
|
|
362
490
|
_cachedResolvedSpec = null;
|
|
363
|
-
get
|
|
491
|
+
get ResolvedComponentSpec() {
|
|
364
492
|
// Prefer the live React component's resolved spec (most up-to-date),
|
|
365
493
|
// then fall back to our cached copy (survives DOM destruction),
|
|
366
494
|
// then fall back to the stripped local spec as last resort.
|
|
367
|
-
return this.
|
|
495
|
+
return this.ReactComponent?.resolvedComponentSpec || this._cachedResolvedSpec || this.Component;
|
|
496
|
+
}
|
|
497
|
+
/** @deprecated Use {@link ResolvedComponentSpec}. */
|
|
498
|
+
get resolvedComponentSpec() {
|
|
499
|
+
return this.ResolvedComponentSpec;
|
|
368
500
|
}
|
|
369
501
|
// Feedback panel
|
|
370
502
|
ShowFeedbackPanel = false;
|
|
371
503
|
// Error state
|
|
372
|
-
|
|
504
|
+
HasError = false;
|
|
505
|
+
/** @deprecated Use {@link HasError}. */
|
|
506
|
+
get hasError() {
|
|
507
|
+
return this.HasError;
|
|
508
|
+
}
|
|
509
|
+
/** @deprecated Use {@link HasError}. */
|
|
510
|
+
set hasError(value) {
|
|
511
|
+
this.HasError = value;
|
|
512
|
+
}
|
|
373
513
|
errorMessage = '';
|
|
374
|
-
|
|
514
|
+
ErrorDetails = '';
|
|
515
|
+
/** @deprecated Use {@link ErrorDetails}. */
|
|
516
|
+
get errorDetails() {
|
|
517
|
+
return this.ErrorDetails;
|
|
518
|
+
}
|
|
519
|
+
/** @deprecated Use {@link ErrorDetails}. */
|
|
520
|
+
set errorDetails(value) {
|
|
521
|
+
this.ErrorDetails = value;
|
|
522
|
+
}
|
|
375
523
|
// Permission state
|
|
376
|
-
|
|
524
|
+
PermissionResult = null;
|
|
525
|
+
/** @deprecated Use {@link PermissionResult}. */
|
|
526
|
+
get permissionResult() {
|
|
527
|
+
return this.PermissionResult;
|
|
528
|
+
}
|
|
529
|
+
/** @deprecated Use {@link PermissionResult}. */
|
|
530
|
+
set permissionResult(value) {
|
|
531
|
+
this.PermissionResult = value;
|
|
532
|
+
}
|
|
377
533
|
/**
|
|
378
534
|
* Whether this plugin has content to display in the Display tab.
|
|
379
535
|
* Returns true only if the component has code that can be rendered.
|
|
@@ -385,7 +541,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
385
541
|
*/
|
|
386
542
|
get hasDisplayContent() {
|
|
387
543
|
// Use this.component directly - it's available synchronously after loadComponentSpec()
|
|
388
|
-
return !!this.
|
|
544
|
+
return !!this.Component?.namespace || !!this.Component?.code;
|
|
389
545
|
}
|
|
390
546
|
constructor(adapter, cdr) {
|
|
391
547
|
super();
|
|
@@ -416,9 +572,9 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
416
572
|
try {
|
|
417
573
|
// Clear cached resolved spec from previous version so stale data doesn't persist
|
|
418
574
|
this._cachedResolvedSpec = null;
|
|
419
|
-
this.
|
|
575
|
+
this.PermissionResult = null;
|
|
420
576
|
if (this.artifactVersion?.Content) {
|
|
421
|
-
this.
|
|
577
|
+
this.Component = SafeJSONParse(this.artifactVersion.Content);
|
|
422
578
|
this.extractComponentParts();
|
|
423
579
|
this.evaluatePermissions();
|
|
424
580
|
// Form-aware detection. Done here (not in ngAfterViewInit) so the
|
|
@@ -433,9 +589,9 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
433
589
|
}
|
|
434
590
|
catch (error) {
|
|
435
591
|
console.error('Failed to load component spec:', error);
|
|
436
|
-
this.
|
|
592
|
+
this.HasError = true;
|
|
437
593
|
this.errorMessage = 'Failed to load component';
|
|
438
|
-
this.
|
|
594
|
+
this.ErrorDetails = error instanceof Error ? error.message : String(error);
|
|
439
595
|
}
|
|
440
596
|
}
|
|
441
597
|
/**
|
|
@@ -445,18 +601,22 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
445
601
|
* Runs synchronously against already-loaded client-side metadata.
|
|
446
602
|
*/
|
|
447
603
|
evaluatePermissions() {
|
|
448
|
-
const spec = this.
|
|
604
|
+
const spec = this.ResolvedComponentSpec;
|
|
449
605
|
if (!spec)
|
|
450
606
|
return;
|
|
451
607
|
const provider = this.ProviderToUse;
|
|
452
608
|
const currentUser = provider.CurrentUser;
|
|
453
609
|
if (!currentUser)
|
|
454
610
|
return; // No user context — skip check
|
|
455
|
-
this.
|
|
611
|
+
this.PermissionResult = EvaluateComponentPermissions(spec, currentUser, provider);
|
|
456
612
|
}
|
|
457
613
|
/** Whether the component should be blocked from rendering due to missing permissions. */
|
|
614
|
+
get IsPermissionBlocked() {
|
|
615
|
+
return !!this.PermissionResult && !this.PermissionResult.canRun;
|
|
616
|
+
}
|
|
617
|
+
/** @deprecated Use {@link IsPermissionBlocked}. */
|
|
458
618
|
get isPermissionBlocked() {
|
|
459
|
-
return
|
|
619
|
+
return this.IsPermissionBlocked;
|
|
460
620
|
}
|
|
461
621
|
/**
|
|
462
622
|
* Component initialization.
|
|
@@ -471,9 +631,9 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
471
631
|
}
|
|
472
632
|
catch (error) {
|
|
473
633
|
console.error('Failed to initialize Angular adapter:', error);
|
|
474
|
-
this.
|
|
634
|
+
this.HasError = true;
|
|
475
635
|
this.errorMessage = 'Failed to initialize component runtime';
|
|
476
|
-
this.
|
|
636
|
+
this.ErrorDetails = error instanceof Error ? error.message : String(error);
|
|
477
637
|
}
|
|
478
638
|
}
|
|
479
639
|
async ngAfterViewInit() {
|
|
@@ -484,7 +644,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
484
644
|
*/
|
|
485
645
|
GetAdditionalTabs() {
|
|
486
646
|
const tabs = [];
|
|
487
|
-
const resolvedComponent = this.
|
|
647
|
+
const resolvedComponent = this.ResolvedComponentSpec;
|
|
488
648
|
if (!resolvedComponent) {
|
|
489
649
|
return tabs;
|
|
490
650
|
}
|
|
@@ -544,11 +704,11 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
544
704
|
return ['JSON'];
|
|
545
705
|
}
|
|
546
706
|
extractComponentParts() {
|
|
547
|
-
if (this.
|
|
548
|
-
this.
|
|
707
|
+
if (this.ResolvedComponentSpec?.name) {
|
|
708
|
+
this.ComponentName = this.ResolvedComponentSpec.name;
|
|
549
709
|
}
|
|
550
|
-
if (this.
|
|
551
|
-
this.
|
|
710
|
+
if (this.ResolvedComponentSpec?.code) {
|
|
711
|
+
this.ComponentCode = BuildComponentCompleteCode(this.ResolvedComponentSpec);
|
|
552
712
|
}
|
|
553
713
|
}
|
|
554
714
|
/**
|
|
@@ -558,11 +718,11 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
558
718
|
* render and <mj-react-component> is removed by the @if/else block).
|
|
559
719
|
* Emits tabsChanged so the parent panel re-evaluates allTabs and renders the new tab labels.
|
|
560
720
|
*/
|
|
561
|
-
|
|
562
|
-
if (this.
|
|
563
|
-
this.
|
|
721
|
+
OnReactComponentInitialized() {
|
|
722
|
+
if (this.ReactComponent?.resolvedComponentSpec &&
|
|
723
|
+
this.ReactComponent.resolvedComponentSpec !== this.Component) {
|
|
564
724
|
// Cache the resolved spec so it's available even after the React component is destroyed
|
|
565
|
-
this._cachedResolvedSpec = this.
|
|
725
|
+
this._cachedResolvedSpec = this.ReactComponent.resolvedComponentSpec;
|
|
566
726
|
this.tabsChanged.emit();
|
|
567
727
|
// Re-evaluate permissions against the resolved spec — the stripped artifact
|
|
568
728
|
// spec has no dataRequirements, so the initial check in loadComponentSpec()
|
|
@@ -571,33 +731,45 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
571
731
|
this.evaluatePermissions();
|
|
572
732
|
}
|
|
573
733
|
}
|
|
574
|
-
|
|
734
|
+
/** @deprecated Use {@link OnReactComponentInitialized}. */
|
|
735
|
+
onReactComponentInitialized() {
|
|
736
|
+
return this.OnReactComponentInitialized();
|
|
737
|
+
}
|
|
738
|
+
OnComponentEvent(event) {
|
|
575
739
|
console.log('Component event:', event);
|
|
576
740
|
// Handle error events from React component
|
|
577
741
|
if (event && typeof event === 'object' && 'type' in event && event.type === 'error') {
|
|
578
742
|
const errorEvent = event;
|
|
579
|
-
this.
|
|
743
|
+
this.HasError = true;
|
|
580
744
|
this.errorMessage = 'Component Failed to Load';
|
|
581
|
-
this.
|
|
745
|
+
this.ErrorDetails = errorEvent.payload.error || 'Unknown error occurred while loading the component';
|
|
582
746
|
}
|
|
583
747
|
}
|
|
748
|
+
/** @deprecated Use {@link OnComponentEvent}. */
|
|
749
|
+
onComponentEvent(event) {
|
|
750
|
+
return this.OnComponentEvent(event);
|
|
751
|
+
}
|
|
584
752
|
/**
|
|
585
753
|
* Handle entity record open request from React component
|
|
586
754
|
* Propagates the event up to parent components
|
|
587
755
|
*/
|
|
588
|
-
|
|
756
|
+
OnOpenEntityRecord(event) {
|
|
589
757
|
// Transform to use 'compositeKey' name for consistency with Angular components
|
|
590
|
-
this.
|
|
758
|
+
this.OpenEntityRecord.emit({
|
|
591
759
|
entityName: event.entityName,
|
|
592
760
|
compositeKey: event.key
|
|
593
761
|
});
|
|
594
762
|
}
|
|
763
|
+
/** @deprecated Use {@link OnOpenEntityRecord}. */
|
|
764
|
+
onOpenEntityRecord(event) {
|
|
765
|
+
return this.OnOpenEntityRecord(event);
|
|
766
|
+
}
|
|
595
767
|
GetCurrentStateSnapshot() {
|
|
596
768
|
// First try the component's explicit or auto-captured data state.
|
|
597
769
|
// MJReactComponent.getCurrentDataState() already includes the fallback
|
|
598
770
|
// to intercepted RunView/RunQuery results when the React component
|
|
599
771
|
// doesn't register getCurrentDataState() via callbacks.RegisterMethod.
|
|
600
|
-
const dataState = this.
|
|
772
|
+
const dataState = this.ReactComponent?.getCurrentDataState?.();
|
|
601
773
|
if (dataState && typeof dataState === 'object') {
|
|
602
774
|
return dataState;
|
|
603
775
|
}
|
|
@@ -608,7 +780,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
608
780
|
// the component. The artifact itself is attached to the conversation as an
|
|
609
781
|
// Input junction, so the agent can reason from the spec + any static data
|
|
610
782
|
// baked into the component code.
|
|
611
|
-
const spec = this.
|
|
783
|
+
const spec = this.ResolvedComponentSpec;
|
|
612
784
|
if (!spec)
|
|
613
785
|
return null;
|
|
614
786
|
const snap = new DataSnapshot();
|
|
@@ -624,7 +796,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
624
796
|
* Component artifacts support feedback when a resolved spec is available.
|
|
625
797
|
*/
|
|
626
798
|
get SupportsFeedback() {
|
|
627
|
-
return !!this.
|
|
799
|
+
return !!this.ResolvedComponentSpec;
|
|
628
800
|
}
|
|
629
801
|
/**
|
|
630
802
|
* Toggle the feedback panel open. Called from the artifact viewer header button.
|
|
@@ -650,41 +822,41 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
650
822
|
* against type-appropriate empty values.
|
|
651
823
|
*/
|
|
652
824
|
async detectAndInitFormArtifact() {
|
|
653
|
-
this.
|
|
654
|
-
this.
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
this.
|
|
658
|
-
this.
|
|
659
|
-
const spec = this.
|
|
825
|
+
this.IsFormArtifact = false;
|
|
826
|
+
this.FormEntityInfo = null;
|
|
827
|
+
this.FormRecord = null;
|
|
828
|
+
this.FormRecordIsReal = false;
|
|
829
|
+
this.FormRecordLabel = '';
|
|
830
|
+
this.FormInitError = null;
|
|
831
|
+
const spec = this.Component;
|
|
660
832
|
if (!spec || !isFormRole(spec))
|
|
661
833
|
return;
|
|
662
|
-
this.
|
|
834
|
+
this.IsFormArtifact = true;
|
|
663
835
|
const entityName = getDeclaredFormEntityName(spec);
|
|
664
836
|
if (!entityName) {
|
|
665
|
-
this.
|
|
837
|
+
this.FormInitError = 'Form artifact has no declared entity. Showing without record context.';
|
|
666
838
|
return;
|
|
667
839
|
}
|
|
668
840
|
const provider = this.ProviderToUse;
|
|
669
841
|
const entity = provider?.EntityByName(entityName);
|
|
670
842
|
if (!entity) {
|
|
671
|
-
this.
|
|
843
|
+
this.FormInitError = `Entity "${entityName}" not registered with the active provider.`;
|
|
672
844
|
return;
|
|
673
845
|
}
|
|
674
|
-
this.
|
|
846
|
+
this.FormEntityInfo = entity;
|
|
675
847
|
// Load Top-1 record by default. If empty / fails, fall back to a fresh
|
|
676
848
|
// synthetic record. Either way the form mounts — failure to find a real
|
|
677
849
|
// record is informational, not fatal.
|
|
678
850
|
const record = await this.loadTopOneRecord(entity);
|
|
679
851
|
if (record) {
|
|
680
|
-
this.
|
|
681
|
-
this.
|
|
682
|
-
this.
|
|
852
|
+
this.FormRecord = record;
|
|
853
|
+
this.FormRecordIsReal = true;
|
|
854
|
+
this.FormRecordLabel = this.computeRecordLabel(record);
|
|
683
855
|
}
|
|
684
856
|
else {
|
|
685
|
-
this.
|
|
686
|
-
this.
|
|
687
|
-
this.
|
|
857
|
+
this.FormRecord = await this.buildFixtureRecord(entity);
|
|
858
|
+
this.FormRecordIsReal = false;
|
|
859
|
+
this.FormRecordLabel = 'Mock data';
|
|
688
860
|
}
|
|
689
861
|
// This runs after an await on a RunView that resolves outside Angular's zone,
|
|
690
862
|
// so nothing would refresh the view until the next user event — leaving the
|
|
@@ -747,15 +919,15 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
747
919
|
* Search-as-you-type for the picker. Queries by name field (or any
|
|
748
920
|
* indexed string field, best-effort). Limits to 8 hits for tightness.
|
|
749
921
|
*/
|
|
750
|
-
async
|
|
751
|
-
this.
|
|
752
|
-
if (!this.
|
|
753
|
-
this.
|
|
922
|
+
async OnPickerSearchInput(term) {
|
|
923
|
+
this.RecordSearchTerm = term;
|
|
924
|
+
if (!this.FormEntityInfo || term.trim().length === 0) {
|
|
925
|
+
this.RecordSearchResults = [];
|
|
754
926
|
return;
|
|
755
927
|
}
|
|
756
|
-
const nameField = this.
|
|
928
|
+
const nameField = this.FormEntityInfo.NameField?.Name;
|
|
757
929
|
if (!nameField) {
|
|
758
|
-
this.
|
|
930
|
+
this.RecordSearchResults = [];
|
|
759
931
|
return;
|
|
760
932
|
}
|
|
761
933
|
try {
|
|
@@ -764,13 +936,13 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
764
936
|
// term so we don't break SQL — RunView passes ExtraFilter as-is.
|
|
765
937
|
const safe = term.replace(/'/g, "''");
|
|
766
938
|
const result = await rv.RunView({
|
|
767
|
-
EntityName: this.
|
|
939
|
+
EntityName: this.FormEntityInfo.Name,
|
|
768
940
|
ExtraFilter: `${nameField} LIKE '%${safe}%'`,
|
|
769
941
|
MaxRows: 8,
|
|
770
942
|
ResultType: 'entity_object',
|
|
771
943
|
}, this.ProviderToUse.CurrentUser);
|
|
772
944
|
if (result.Success) {
|
|
773
|
-
this.
|
|
945
|
+
this.RecordSearchResults = (result.Results ?? []).map(r => ({
|
|
774
946
|
ID: r.PrimaryKey?.ToConcatenatedString() ?? '',
|
|
775
947
|
Label: this.computeRecordLabel(r),
|
|
776
948
|
}));
|
|
@@ -778,31 +950,39 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
778
950
|
}
|
|
779
951
|
catch (err) {
|
|
780
952
|
LogError(`ComponentArtifactViewer: picker search failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
781
|
-
this.
|
|
953
|
+
this.RecordSearchResults = [];
|
|
782
954
|
}
|
|
783
955
|
}
|
|
956
|
+
/** @deprecated Use {@link OnPickerSearchInput}. */
|
|
957
|
+
async onPickerSearchInput(term) {
|
|
958
|
+
return this.OnPickerSearchInput(term);
|
|
959
|
+
}
|
|
784
960
|
/** User picked a different record from the search results. Re-bind the form. */
|
|
785
|
-
async
|
|
786
|
-
if (!this.
|
|
961
|
+
async OnPickerSelect(item) {
|
|
962
|
+
if (!this.FormEntityInfo)
|
|
787
963
|
return;
|
|
788
964
|
try {
|
|
789
|
-
const rec = await this.ProviderToUse.GetEntityObject(this.
|
|
965
|
+
const rec = await this.ProviderToUse.GetEntityObject(this.FormEntityInfo.Name, this.ProviderToUse.CurrentUser);
|
|
790
966
|
const pk = new CompositeKey();
|
|
791
|
-
pk.LoadFromURLSegment(this.
|
|
967
|
+
pk.LoadFromURLSegment(this.FormEntityInfo, item.ID);
|
|
792
968
|
const loaded = await rec.InnerLoad(pk);
|
|
793
969
|
if (loaded) {
|
|
794
|
-
this.
|
|
795
|
-
this.
|
|
796
|
-
this.
|
|
797
|
-
this.
|
|
798
|
-
this.
|
|
799
|
-
this.
|
|
970
|
+
this.FormRecord = rec;
|
|
971
|
+
this.FormRecordIsReal = true;
|
|
972
|
+
this.FormRecordLabel = item.Label;
|
|
973
|
+
this.ShowRecordPicker = false;
|
|
974
|
+
this.RecordSearchTerm = '';
|
|
975
|
+
this.RecordSearchResults = [];
|
|
800
976
|
}
|
|
801
977
|
}
|
|
802
978
|
catch (err) {
|
|
803
979
|
LogError(`ComponentArtifactViewer: failed to load picked record ${item.ID}: ${err instanceof Error ? err.message : String(err)}`);
|
|
804
980
|
}
|
|
805
981
|
}
|
|
982
|
+
/** @deprecated Use {@link OnPickerSelect}. */
|
|
983
|
+
async onPickerSelect(item) {
|
|
984
|
+
return this.OnPickerSelect(item);
|
|
985
|
+
}
|
|
806
986
|
/**
|
|
807
987
|
* Bubble Apply intent up to the host (Form Builder dashboard / Sage chat).
|
|
808
988
|
*
|
|
@@ -814,28 +994,32 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
814
994
|
* Source #2 covers the common form-artifact case where the React component lives inside
|
|
815
995
|
* <mj-interactive-form> and resolvedComponentSpec falls back to the stripped local spec.
|
|
816
996
|
*/
|
|
817
|
-
async
|
|
818
|
-
if (!this.
|
|
997
|
+
async OnApplyClicked() {
|
|
998
|
+
if (!this.FormEntityInfo)
|
|
819
999
|
return;
|
|
820
1000
|
const spec = await this.resolveSpecWithCode();
|
|
821
1001
|
if (!spec)
|
|
822
1002
|
return;
|
|
823
|
-
this.
|
|
1003
|
+
this.ApplyFormRequested.emit({
|
|
824
1004
|
spec,
|
|
825
|
-
entityName: this.
|
|
1005
|
+
entityName: this.FormEntityInfo.Name,
|
|
826
1006
|
});
|
|
827
1007
|
}
|
|
1008
|
+
/** @deprecated Use {@link OnApplyClicked}. */
|
|
1009
|
+
async onApplyClicked() {
|
|
1010
|
+
return this.OnApplyClicked();
|
|
1011
|
+
}
|
|
828
1012
|
/**
|
|
829
1013
|
* Resolve a ComponentSpec that includes code, trying multiple sources in order.
|
|
830
1014
|
*/
|
|
831
1015
|
async resolveSpecWithCode() {
|
|
832
1016
|
// 1. Prefer the live React bridge's resolved spec (non-form path).
|
|
833
|
-
const resolved = this.
|
|
1017
|
+
const resolved = this.ResolvedComponentSpec;
|
|
834
1018
|
if (resolved?.code)
|
|
835
1019
|
return resolved;
|
|
836
1020
|
// 2. For form artifacts, the React component lives inside <mj-interactive-form>.
|
|
837
1021
|
// Reach into it to get the resolved spec from the component registry.
|
|
838
|
-
const formReactSpec = this.
|
|
1022
|
+
const formReactSpec = this.InteractiveForm?.reactComponent?.resolvedComponentSpec;
|
|
839
1023
|
if (formReactSpec?.code)
|
|
840
1024
|
return formReactSpec;
|
|
841
1025
|
// 3. Re-parse the artifact version's Content directly — the agent stores the
|
|
@@ -848,7 +1032,7 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
848
1032
|
return freshParse;
|
|
849
1033
|
}
|
|
850
1034
|
// 4. DB fallback — fetch from MJ: Components by name.
|
|
851
|
-
const name = resolved?.name ?? this.
|
|
1035
|
+
const name = resolved?.name ?? this.Component?.name;
|
|
852
1036
|
if (name) {
|
|
853
1037
|
const dbSpec = await this.fetchFullSpecByName(name);
|
|
854
1038
|
if (dbSpec?.code)
|
|
@@ -886,9 +1070,9 @@ let ComponentArtifactViewerComponent = class ComponentArtifactViewerComponent ex
|
|
|
886
1070
|
i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
|
|
887
1071
|
} if (rf & 2) {
|
|
888
1072
|
let _t;
|
|
889
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
890
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
891
|
-
} }, outputs: { tabsChanged: "tabsChanged", openEntityRecord: "openEntityRecord", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 7, vars: 3, consts: [["interactiveForm", ""], ["reactComponent", ""], [1, "component-artifact-viewer", 3, "ngClass"], [1, "component-preview"], [1, "error-state"], [1, "permission-warning"], [3, "ComponentSpec", "ReactContainerElement"], [1, "fa-solid", "fa-exclamation-triangle"], [2, "text-align", "left", "max-width", "500px", "color", "var(--mj-text-muted)", "line-height", "1.6"], [2, "margin-top", "20px"], [1, "form-artifact-toolstrip"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-info"], [1, "form-artifact-toolstrip-label"], ["type", "button", 1, "form-artifact-picker-chip", 3, "click"], [1, "fa-solid", "fa-magnifying-glass"], [1, "form-artifact-picker-chip-badge"], [1, "fa-solid", "fa-chevron-down"], [1, "form-artifact-toolstrip-entity"], [1, "form-artifact-toolstrip-warning", 3, "title"], [2, "flex", "1"], ["type", "button", 1, "form-artifact-apply-btn"], [1, "form-artifact-picker-panel"], [1, "form-artifact-form-host"], [1, "fa-solid", "fa-triangle-exclamation"], ["type", "button", 1, "form-artifact-apply-btn", 3, "click"], [1, "fa-solid", "fa-circle-check"], [1, "form-artifact-picker-panel", 3, "click"], ["type", "text", "placeholder", "Search records by name\u2026", 1, "form-artifact-picker-search", 3, "input", "value"], [1, "form-artifact-picker-results"], [1, "form-artifact-picker-empty"], [1, "form-artifact-picker-row"], [1, "form-artifact-picker-row", 3, "click"], [1, "fa-solid", "fa-circle-dot"], [3, "componentSpec", "record"], [1, "fa-solid", "fa-exclamation-circle"], [1, "permission-warning-icon"], [1, "fa-solid", "fa-shield-halved"], [1, "permission-warning-section"], [1, "permission-warning-hint"], [1, "permission-warning-section-label"], [1, "fa-solid", "fa-table"], [1, "fa-solid", "fa-database"], [3, "component"], [1, "no-code-state"], [3, "componentEvent", "openEntityRecord", "initialized", "component"], [1, "fa-solid", "fa-file-lines"], [3, "Closed", "ComponentSpec", "ReactContainerElement"]], template: function ComponentArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1073
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ReactComponent = _t.first);
|
|
1074
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.InteractiveForm = _t.first);
|
|
1075
|
+
} }, outputs: { tabsChanged: "tabsChanged", OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", ApplyFormRequested: "ApplyFormRequested", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 7, vars: 3, consts: [["interactiveForm", ""], ["reactComponent", ""], [1, "component-artifact-viewer", 3, "ngClass"], [1, "component-preview"], [1, "error-state"], [1, "permission-warning"], [3, "ComponentSpec", "ReactContainerElement"], [1, "fa-solid", "fa-exclamation-triangle"], [2, "text-align", "left", "max-width", "500px", "color", "var(--mj-text-muted)", "line-height", "1.6"], [2, "margin-top", "20px"], [1, "form-artifact-toolstrip"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-info"], [1, "form-artifact-toolstrip-label"], ["type", "button", 1, "form-artifact-picker-chip", 3, "click"], [1, "fa-solid", "fa-magnifying-glass"], [1, "form-artifact-picker-chip-badge"], [1, "fa-solid", "fa-chevron-down"], [1, "form-artifact-toolstrip-entity"], [1, "form-artifact-toolstrip-warning", 3, "title"], [2, "flex", "1"], ["type", "button", 1, "form-artifact-apply-btn"], [1, "form-artifact-picker-panel"], [1, "form-artifact-form-host"], [1, "fa-solid", "fa-triangle-exclamation"], ["type", "button", 1, "form-artifact-apply-btn", 3, "click"], [1, "fa-solid", "fa-circle-check"], [1, "form-artifact-picker-panel", 3, "click"], ["type", "text", "placeholder", "Search records by name\u2026", 1, "form-artifact-picker-search", 3, "input", "value"], [1, "form-artifact-picker-results"], [1, "form-artifact-picker-empty"], [1, "form-artifact-picker-row"], [1, "form-artifact-picker-row", 3, "click"], [1, "fa-solid", "fa-circle-dot"], [3, "componentSpec", "record"], [1, "fa-solid", "fa-exclamation-circle"], [1, "permission-warning-icon"], [1, "fa-solid", "fa-shield-halved"], [1, "permission-warning-section"], [1, "permission-warning-hint"], [1, "permission-warning-section-label"], [1, "fa-solid", "fa-table"], [1, "fa-solid", "fa-database"], [3, "component"], [1, "no-code-state"], [3, "componentEvent", "openEntityRecord", "initialized", "component"], [1, "fa-solid", "fa-file-lines"], [3, "Closed", "ComponentSpec", "ReactContainerElement"]], template: function ComponentArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
892
1076
|
i0.ɵɵelementStart(0, "div", 2)(1, "div", 3);
|
|
893
1077
|
i0.ɵɵconditionalCreate(2, ComponentArtifactViewerComponent_Conditional_2_Template, 14, 2, "div", 4)(3, ComponentArtifactViewerComponent_Conditional_3_Template, 17, 7)(4, ComponentArtifactViewerComponent_Conditional_4_Template, 11, 2, "div", 5)(5, ComponentArtifactViewerComponent_Conditional_5_Template, 3, 1);
|
|
894
1078
|
i0.ɵɵelementEnd();
|
|
@@ -909,16 +1093,20 @@ export { ComponentArtifactViewerComponent };
|
|
|
909
1093
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentArtifactViewerComponent, [{
|
|
910
1094
|
type: Component,
|
|
911
1095
|
args: [{ standalone: false, selector: 'mj-component-artifact-viewer', template: "<div class=\"component-artifact-viewer\" [ngClass]=\"cssClass\">\n <!-- Component Preview (full screen) -->\n <div class=\"component-preview\">\n @if (hasError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <h3>{{ errorMessage }}</h3>\n <p>This component could not be loaded. This usually happens when:</p>\n <ul style=\"text-align: left; max-width: 500px; color: var(--mj-text-muted); line-height: 1.6;\">\n <li>The component registry is unavailable or unreachable</li>\n <li>The component version does not exist in the registry</li>\n <li>There was a network error during component retrieval</li>\n </ul>\n @if (errorDetails) {\n <details style=\"margin-top: 20px;\">\n <summary>Technical Details</summary>\n <pre>{{ errorDetails }}</pre>\n </details>\n }\n </div>\n } @else if (isFormArtifact) {\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FORM-AWARE BRANCH\n Spec declares componentRole: 'form'. Render via\n <mj-interactive-form> bound to a real Top-1 record\n (or a synthetic NewRecord fallback). Picker chip\n lets the user swap records; Apply promotes the\n spec to an EntityFormOverride.\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <div class=\"form-artifact-toolstrip\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n <span class=\"form-artifact-toolstrip-label\">Previewing record:</span>\n <button\n type=\"button\"\n class=\"form-artifact-picker-chip\"\n (click)=\"showRecordPicker = !showRecordPicker\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <strong>{{ formRecordLabel || 'No record' }}</strong>\n @if (!formRecordIsReal) {\n <span class=\"form-artifact-picker-chip-badge\">Mock</span>\n }\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n @if (formEntityInfo) {\n <span class=\"form-artifact-toolstrip-entity\">{{ formEntityInfo.DisplayName || formEntityInfo.Name }}</span>\n }\n @if (formInitError) {\n <span class=\"form-artifact-toolstrip-warning\" [title]=\"formInitError\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </span>\n }\n <span style=\"flex: 1;\"></span>\n @if (formEntityInfo) {\n <button\n type=\"button\"\n class=\"form-artifact-apply-btn\"\n (click)=\"onApplyClicked()\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Apply to my form\n </button>\n }\n </div>\n\n @if (showRecordPicker && formEntityInfo) {\n <div class=\"form-artifact-picker-panel\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"text\"\n class=\"form-artifact-picker-search\"\n placeholder=\"Search records by name\u2026\"\n [value]=\"recordSearchTerm\"\n (input)=\"onPickerSearchInput($any($event.target).value)\" />\n @if (recordSearchResults.length > 0) {\n <ul class=\"form-artifact-picker-results\">\n @for (r of recordSearchResults; track r.ID) {\n <li\n class=\"form-artifact-picker-row\"\n (click)=\"onPickerSelect(r)\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n <span>{{ r.Label }}</span>\n </li>\n }\n </ul>\n } @else if (recordSearchTerm.length > 0) {\n <div class=\"form-artifact-picker-empty\">No matches.</div>\n } @else {\n <div class=\"form-artifact-picker-empty\">Start typing to search.</div>\n }\n </div>\n }\n\n @if (formRecord && component) {\n <div class=\"form-artifact-form-host\">\n <mj-interactive-form\n #interactiveForm\n [componentSpec]=\"component\"\n [record]=\"formRecord\">\n </mj-interactive-form>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>Form preview unavailable</h3>\n <p>{{ formInitError || 'Could not bind a record to this form.' }}</p>\n </div>\n }\n } @else if (isPermissionBlocked) {\n <!-- Permission warning \u2014 user lacks access to one or more data sources -->\n <div class=\"permission-warning\">\n <div class=\"permission-warning-icon\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <h3>Insufficient Permissions</h3>\n <p>This component requires data access that you don't currently have:</p>\n\n @if (permissionResult!.missingEntities.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Entities</span>\n <ul>\n @for (entity of permissionResult!.missingEntities; track entity) {\n <li><i class=\"fa-solid fa-table\"></i> {{ entity }}</li>\n }\n </ul>\n </div>\n }\n\n @if (permissionResult!.missingQueries.length > 0) {\n <div class=\"permission-warning-section\">\n <span class=\"permission-warning-section-label\">Queries</span>\n <ul>\n @for (query of permissionResult!.missingQueries; track query) {\n <li><i class=\"fa-solid fa-database\"></i> {{ query }}</li>\n }\n </ul>\n </div>\n }\n\n <p class=\"permission-warning-hint\">Contact your administrator to request access.</p>\n </div>\n } @else {\n <!-- Default (non-form) interactive component path -->\n @if (component && (component.code || component.namespace)) {\n <mj-react-component\n #reactComponent\n [component]=\"component\"\n (componentEvent)=\"onComponentEvent($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (initialized)=\"onReactComponentInitialized()\">\n </mj-react-component>\n } @else if (component) {\n <!-- Component spec exists but no code - show informational message -->\n <div class=\"no-code-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <h3>Component Specification</h3>\n <p>This component has specifications but no executable code yet.</p>\n <p>View the Functional, Data, or Spec tabs for details.</p>\n </div>\n } @else {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <h3>No Component Loaded</h3>\n <p>The component data is missing or invalid.</p>\n </div>\n }\n }\n </div>\n\n <!-- Feedback overlay panel (invoked from header button via AskUserForFeedback) -->\n @if (ShowFeedbackPanel && resolvedComponentSpec) {\n <mj-component-feedback-panel\n [ComponentSpec]=\"resolvedComponentSpec\"\n [ReactContainerElement]=\"reactComponent?.container?.nativeElement || null\"\n (Closed)=\"ShowFeedbackPanel = false\">\n </mj-component-feedback-panel>\n }\n</div>\n", styles: [".component-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--mj-bg-surface);\n}\n\n.component-preview {\n flex: 1;\n padding: 15px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n min-height: 0;\n min-width: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n/* Ensure React component takes full height */\n.component-preview mj-react-component {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-status-error);\n flex: 1;\n min-height: 300px;\n}\n.error-state i {\n font-size: 48px;\n margin-bottom: 16px;\n}\n.error-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n}\n.error-state p {\n margin: 0 0 12px 0;\n color: var(--mj-text-muted);\n}\n.error-state details {\n margin-top: 16px;\n text-align: left;\n max-width: 600px;\n}\n.error-state details summary {\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-bottom: 8px;\n}\n.error-state details summary:hover {\n color: var(--mj-text-primary);\n}\n.error-state details pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* State for component spec without executable code */\n.no-code-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n color: var(--mj-text-muted);\n flex: 1;\n}\n.no-code-state i {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-brand-primary);\n}\n.no-code-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-secondary);\n}\n.no-code-state p {\n margin: 0 0 8px 0;\n color: var(--mj-text-muted);\n}\n\n\n/* ====================================================================\n FORM-AWARE BRANCH (componentRole === 'form')\n Top strip: record-picker chip + Apply button.\n Below: dropdown picker panel.\n Below: <mj-interactive-form> bound to the picked record.\n ==================================================================== */\n\n.form-artifact-toolstrip {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n.form-artifact-toolstrip-label {\n font-weight: 600;\n}\n.form-artifact-toolstrip-entity {\n margin-left: 4px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n}\n.form-artifact-toolstrip-warning {\n color: var(--mj-status-warning-text);\n}\n\n.form-artifact-picker-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n padding: 4px 10px;\n font-size: 12px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.form-artifact-picker-chip:hover,\n.form-artifact-picker-chip:focus {\n border-color: var(--mj-border-focus);\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-chip strong {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n.form-artifact-picker-chip-badge {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 999px;\n}\n\n.form-artifact-apply-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n padding: 5px 12px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n.form-artifact-apply-btn:hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.form-artifact-picker-panel {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.form-artifact-picker-search {\n width: 100%;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n.form-artifact-picker-search:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.form-artifact-picker-results {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.form-artifact-picker-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n}\n.form-artifact-picker-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n.form-artifact-picker-row i {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n.form-artifact-picker-empty {\n color: var(--mj-text-muted);\n font-size: 12px;\n font-style: italic;\n}\n\n.form-artifact-form-host {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n min-width: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n/* ====================================================================\n PERMISSION WARNING\n Shown before rendering when the user lacks read access to one or\n more entities/queries required by the component.\n ==================================================================== */\n\n.permission-warning {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n text-align: center;\n flex: 1;\n min-height: 300px;\n}\n.permission-warning-icon {\n font-size: 48px;\n margin-bottom: 16px;\n color: var(--mj-status-warning-text, #b45309);\n}\n.permission-warning h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n color: var(--mj-text-primary);\n}\n.permission-warning > p {\n margin: 0 0 16px 0;\n color: var(--mj-text-muted);\n}\n.permission-warning-section {\n text-align: left;\n max-width: 400px;\n width: 100%;\n margin-bottom: 12px;\n}\n.permission-warning-section-label {\n display: block;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n.permission-warning-section ul {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.permission-warning-section li {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken, var(--mj-bg-surface));\n border-radius: 6px;\n}\n.permission-warning-section li i {\n color: var(--mj-status-warning-text, #b45309);\n font-size: 12px;\n}\n.permission-warning-hint {\n margin-top: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n"] }]
|
|
912
|
-
}], () => [{ type: i1.AngularAdapterService }, { type: i0.ChangeDetectorRef }], {
|
|
1096
|
+
}], () => [{ type: i1.AngularAdapterService }, { type: i0.ChangeDetectorRef }], { ReactComponent: [{
|
|
913
1097
|
type: ViewChild,
|
|
914
1098
|
args: ['reactComponent']
|
|
915
|
-
}],
|
|
1099
|
+
}], InteractiveForm: [{
|
|
916
1100
|
type: ViewChild,
|
|
917
1101
|
args: ['interactiveForm']
|
|
918
1102
|
}], tabsChanged: [{
|
|
919
1103
|
type: Output
|
|
1104
|
+
}], OpenEntityRecord: [{
|
|
1105
|
+
type: Output
|
|
920
1106
|
}], openEntityRecord: [{
|
|
921
1107
|
type: Output
|
|
1108
|
+
}], ApplyFormRequested: [{
|
|
1109
|
+
type: Output
|
|
922
1110
|
}], applyFormRequested: [{
|
|
923
1111
|
type: Output
|
|
924
1112
|
}] }); })();
|