@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.
Files changed (125) hide show
  1. package/dist/lib/components/artifact-message-card.component.d.ts +60 -8
  2. package/dist/lib/components/artifact-message-card.component.d.ts.map +1 -1
  3. package/dist/lib/components/artifact-message-card.component.js +135 -39
  4. package/dist/lib/components/artifact-message-card.component.js.map +1 -1
  5. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +58 -6
  6. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
  7. package/dist/lib/components/artifact-type-plugin-viewer.component.js +113 -35
  8. package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
  9. package/dist/lib/components/artifact-version-download.d.ts +5 -3
  10. package/dist/lib/components/artifact-version-download.d.ts.map +1 -1
  11. package/dist/lib/components/artifact-version-download.js +11 -7
  12. package/dist/lib/components/artifact-version-download.js.map +1 -1
  13. package/dist/lib/components/artifact-version-history.component.d.ts +74 -8
  14. package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
  15. package/dist/lib/components/artifact-version-history.component.js +152 -34
  16. package/dist/lib/components/artifact-version-history.component.js.map +1 -1
  17. package/dist/lib/components/artifact-viewer-panel.component.d.ts +328 -35
  18. package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
  19. package/dist/lib/components/artifact-viewer-panel.component.js +701 -213
  20. package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
  21. package/dist/lib/components/file-artifact-toolbar.component.d.ts +112 -10
  22. package/dist/lib/components/file-artifact-toolbar.component.d.ts.map +1 -1
  23. package/dist/lib/components/file-artifact-toolbar.component.js +197 -23
  24. package/dist/lib/components/file-artifact-toolbar.component.js.map +1 -1
  25. package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +9 -1
  26. package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
  27. package/dist/lib/components/plugins/audio-artifact-viewer.component.js +20 -4
  28. package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
  29. package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts +23 -5
  30. package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts.map +1 -1
  31. package/dist/lib/components/plugins/code-artifact-viewer.component.js +69 -31
  32. package/dist/lib/components/plugins/code-artifact-viewer.component.js.map +1 -1
  33. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +136 -18
  34. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
  35. package/dist/lib/components/plugins/component-artifact-viewer.component.js +285 -97
  36. package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
  37. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +2 -2
  38. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +7 -7
  39. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
  40. package/dist/lib/components/plugins/component-permission-evaluation.d.ts +2 -0
  41. package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -1
  42. package/dist/lib/components/plugins/component-permission-evaluation.js +6 -2
  43. package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -1
  44. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts +17 -6
  45. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
  46. package/dist/lib/components/plugins/data-artifact-viewer.component.js +32 -22
  47. package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
  48. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts +56 -4
  49. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts.map +1 -1
  50. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +142 -36
  51. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
  52. package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts +14 -2
  53. package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts.map +1 -1
  54. package/dist/lib/components/plugins/docx-artifact-viewer.component.js +32 -8
  55. package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
  56. package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts +17 -3
  57. package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts.map +1 -1
  58. package/dist/lib/components/plugins/html-artifact-viewer.component.js +36 -8
  59. package/dist/lib/components/plugins/html-artifact-viewer.component.js.map +1 -1
  60. package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +41 -5
  61. package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -1
  62. package/dist/lib/components/plugins/image-artifact-viewer.component.js +102 -30
  63. package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -1
  64. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +33 -5
  65. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
  66. package/dist/lib/components/plugins/json-artifact-viewer.component.js +89 -33
  67. package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
  68. package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts +12 -2
  69. package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts.map +1 -1
  70. package/dist/lib/components/plugins/markdown-artifact-viewer.component.js +28 -8
  71. package/dist/lib/components/plugins/markdown-artifact-viewer.component.js.map +1 -1
  72. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +4 -0
  73. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -1
  74. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +14 -6
  75. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -1
  76. package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts +47 -5
  77. package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts.map +1 -1
  78. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +129 -45
  79. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
  80. package/dist/lib/components/plugins/save-query-dialog.component.d.ts +5 -1
  81. package/dist/lib/components/plugins/save-query-dialog.component.d.ts.map +1 -1
  82. package/dist/lib/components/plugins/save-query-dialog.component.js +12 -4
  83. package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
  84. package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts +17 -3
  85. package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts.map +1 -1
  86. package/dist/lib/components/plugins/svg-artifact-viewer.component.js +36 -8
  87. package/dist/lib/components/plugins/svg-artifact-viewer.component.js.map +1 -1
  88. package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +9 -1
  89. package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
  90. package/dist/lib/components/plugins/video-artifact-viewer.component.js +20 -4
  91. package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
  92. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts +28 -4
  93. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts.map +1 -1
  94. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +64 -16
  95. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
  96. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +9 -1
  97. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
  98. package/dist/lib/components/previews/audio-artifact-preview.component.js +20 -4
  99. package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
  100. package/dist/lib/components/previews/image-artifact-preview.component.d.ts +16 -2
  101. package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
  102. package/dist/lib/components/previews/image-artifact-preview.component.js +35 -7
  103. package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
  104. package/dist/lib/components/previews/video-artifact-preview.component.d.ts +9 -1
  105. package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
  106. package/dist/lib/components/previews/video-artifact-preview.component.js +20 -4
  107. package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
  108. package/dist/lib/interfaces/artifact-viewer-plugin.interface.js.map +1 -1
  109. package/dist/lib/services/artifact-file.service.d.ts +8 -0
  110. package/dist/lib/services/artifact-file.service.d.ts.map +1 -1
  111. package/dist/lib/services/artifact-file.service.js +22 -6
  112. package/dist/lib/services/artifact-file.service.js.map +1 -1
  113. package/dist/lib/services/artifact-icon.service.d.ts +2 -0
  114. package/dist/lib/services/artifact-icon.service.d.ts.map +1 -1
  115. package/dist/lib/services/artifact-icon.service.js +5 -1
  116. package/dist/lib/services/artifact-icon.service.js.map +1 -1
  117. package/dist/lib/services/artifact-preview-resolver.service.d.ts +2 -0
  118. package/dist/lib/services/artifact-preview-resolver.service.d.ts.map +1 -1
  119. package/dist/lib/services/artifact-preview-resolver.service.js +5 -1
  120. package/dist/lib/services/artifact-preview-resolver.service.js.map +1 -1
  121. package/dist/lib/snapshot-helpers.d.ts +10 -0
  122. package/dist/lib/snapshot-helpers.d.ts.map +1 -1
  123. package/dist/lib/snapshot-helpers.js +25 -5
  124. package/dist/lib/snapshot-helpers.js.map +1 -1
  125. 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 { evaluateComponentPermissions } from './component-permission-evaluation';
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
- reactComponent;
328
- interactiveForm;
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
- openEntityRecord = new EventEmitter();
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
- applyFormRequested = new EventEmitter();
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
- isFormArtifact = false;
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
- formEntityInfo = null;
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
- formRecord = null;
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
- formRecordIsReal = false;
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
- formRecordLabel = '';
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
- showRecordPicker = false;
351
- recordSearchTerm = '';
352
- recordSearchResults = [];
353
- formInitError = null;
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
- component = null;
356
- componentCode = "";
357
- componentName = '';
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 resolvedComponentSpec() {
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.reactComponent?.resolvedComponentSpec || this._cachedResolvedSpec || this.component;
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
- hasError = false;
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
- errorDetails = '';
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
- permissionResult = null;
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.component?.namespace || !!this.component?.code;
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.permissionResult = null;
575
+ this.PermissionResult = null;
420
576
  if (this.artifactVersion?.Content) {
421
- this.component = SafeJSONParse(this.artifactVersion.Content);
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.hasError = true;
592
+ this.HasError = true;
437
593
  this.errorMessage = 'Failed to load component';
438
- this.errorDetails = error instanceof Error ? error.message : String(error);
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.resolvedComponentSpec;
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.permissionResult = evaluateComponentPermissions(spec, currentUser, provider);
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 !!this.permissionResult && !this.permissionResult.canRun;
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.hasError = true;
634
+ this.HasError = true;
475
635
  this.errorMessage = 'Failed to initialize component runtime';
476
- this.errorDetails = error instanceof Error ? error.message : String(error);
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.resolvedComponentSpec;
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.resolvedComponentSpec?.name) {
548
- this.componentName = this.resolvedComponentSpec.name;
707
+ if (this.ResolvedComponentSpec?.name) {
708
+ this.ComponentName = this.ResolvedComponentSpec.name;
549
709
  }
550
- if (this.resolvedComponentSpec?.code) {
551
- this.componentCode = BuildComponentCompleteCode(this.resolvedComponentSpec);
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
- onReactComponentInitialized() {
562
- if (this.reactComponent?.resolvedComponentSpec &&
563
- this.reactComponent.resolvedComponentSpec !== this.component) {
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.reactComponent.resolvedComponentSpec;
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
- onComponentEvent(event) {
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.hasError = true;
743
+ this.HasError = true;
580
744
  this.errorMessage = 'Component Failed to Load';
581
- this.errorDetails = errorEvent.payload.error || 'Unknown error occurred while loading the component';
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
- onOpenEntityRecord(event) {
756
+ OnOpenEntityRecord(event) {
589
757
  // Transform to use 'compositeKey' name for consistency with Angular components
590
- this.openEntityRecord.emit({
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.reactComponent?.getCurrentDataState?.();
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.resolvedComponentSpec;
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.resolvedComponentSpec;
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.isFormArtifact = false;
654
- this.formEntityInfo = null;
655
- this.formRecord = null;
656
- this.formRecordIsReal = false;
657
- this.formRecordLabel = '';
658
- this.formInitError = null;
659
- const spec = this.component;
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.isFormArtifact = true;
834
+ this.IsFormArtifact = true;
663
835
  const entityName = getDeclaredFormEntityName(spec);
664
836
  if (!entityName) {
665
- this.formInitError = 'Form artifact has no declared entity. Showing without record context.';
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.formInitError = `Entity "${entityName}" not registered with the active provider.`;
843
+ this.FormInitError = `Entity "${entityName}" not registered with the active provider.`;
672
844
  return;
673
845
  }
674
- this.formEntityInfo = entity;
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.formRecord = record;
681
- this.formRecordIsReal = true;
682
- this.formRecordLabel = this.computeRecordLabel(record);
852
+ this.FormRecord = record;
853
+ this.FormRecordIsReal = true;
854
+ this.FormRecordLabel = this.computeRecordLabel(record);
683
855
  }
684
856
  else {
685
- this.formRecord = await this.buildFixtureRecord(entity);
686
- this.formRecordIsReal = false;
687
- this.formRecordLabel = 'Mock data';
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 onPickerSearchInput(term) {
751
- this.recordSearchTerm = term;
752
- if (!this.formEntityInfo || term.trim().length === 0) {
753
- this.recordSearchResults = [];
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.formEntityInfo.NameField?.Name;
928
+ const nameField = this.FormEntityInfo.NameField?.Name;
757
929
  if (!nameField) {
758
- this.recordSearchResults = [];
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.formEntityInfo.Name,
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.recordSearchResults = (result.Results ?? []).map(r => ({
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.recordSearchResults = [];
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 onPickerSelect(item) {
786
- if (!this.formEntityInfo)
961
+ async OnPickerSelect(item) {
962
+ if (!this.FormEntityInfo)
787
963
  return;
788
964
  try {
789
- const rec = await this.ProviderToUse.GetEntityObject(this.formEntityInfo.Name, this.ProviderToUse.CurrentUser);
965
+ const rec = await this.ProviderToUse.GetEntityObject(this.FormEntityInfo.Name, this.ProviderToUse.CurrentUser);
790
966
  const pk = new CompositeKey();
791
- pk.LoadFromURLSegment(this.formEntityInfo, item.ID);
967
+ pk.LoadFromURLSegment(this.FormEntityInfo, item.ID);
792
968
  const loaded = await rec.InnerLoad(pk);
793
969
  if (loaded) {
794
- this.formRecord = rec;
795
- this.formRecordIsReal = true;
796
- this.formRecordLabel = item.Label;
797
- this.showRecordPicker = false;
798
- this.recordSearchTerm = '';
799
- this.recordSearchResults = [];
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 onApplyClicked() {
818
- if (!this.formEntityInfo)
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.applyFormRequested.emit({
1003
+ this.ApplyFormRequested.emit({
824
1004
  spec,
825
- entityName: this.formEntityInfo.Name,
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.resolvedComponentSpec;
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.interactiveForm?.reactComponent?.resolvedComponentSpec;
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.component?.name;
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.reactComponent = _t.first);
890
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.interactiveForm = _t.first);
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 }], { reactComponent: [{
1096
+ }], () => [{ type: i1.AngularAdapterService }, { type: i0.ChangeDetectorRef }], { ReactComponent: [{
913
1097
  type: ViewChild,
914
1098
  args: ['reactComponent']
915
- }], interactiveForm: [{
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
  }] }); })();