Skip to content

@memberjunction/ng-artifacts

Angular artifact viewer plugin system for rendering different artifact types (JSON, Code, Markdown, HTML, SVG, React Components) with version history, message cards, and an extensible plugin architecture.

The @memberjunction/ng-artifacts package provides a pluggable viewer system for MemberJunction conversation artifacts. Each artifact type (JSON, Code, Markdown, HTML, SVG, Component) is rendered by a dedicated viewer plugin, selected automatically based on the artifact’s type metadata. The package also includes components for artifact version history browsing, viewer panels, and inline message cards.

graph TD
    A[ArtifactsModule] --> B[Viewer Components]
    A --> C[Plugin System]
    A --> D[Services]

    B --> B1[ArtifactViewerPanelComponent]
    B --> B2[ArtifactVersionHistoryComponent]
    B --> B3[ArtifactMessageCardComponent]
    B --> B4[ArtifactTypePluginViewerComponent]

    C --> C0[BaseArtifactViewerComponent]
    C --> C1[JsonArtifactViewerComponent]
    C --> C2[CodeArtifactViewerComponent]
    C --> C3[MarkdownArtifactViewerComponent]
    C --> C4[HtmlArtifactViewerComponent]
    C --> C5[SvgArtifactViewerComponent]
    C --> C6[ComponentArtifactViewerComponent]

    D --> D1[ArtifactIconService]

    style A fill:#2d6a9f,stroke:#1a4971,color:#fff
    style B fill:#7c5295,stroke:#563a6b,color:#fff
    style C fill:#2d8659,stroke:#1a5c3a,color:#fff
    style D fill:#b8762f,stroke:#8a5722,color:#fff
Terminal window
npm install @memberjunction/ng-artifacts
import { ArtifactsModule } from '@memberjunction/ng-artifacts';
@NgModule({
imports: [ArtifactsModule]
})
export class YourModule { }

Full-featured panel with toolbar and version navigation:

<mj-artifact-viewer-panel
[artifactId]="selectedArtifactId"
[versionId]="selectedVersionId"
(versionChanged)="onVersionChanged($event)">
</mj-artifact-viewer-panel>

Automatically selects and loads the correct plugin based on artifact type:

<mj-artifact-type-plugin-viewer
[artifactVersion]="currentVersion"
[artifactTypeName]="'Code'">
</mj-artifact-type-plugin-viewer>

Timeline of artifact versions:

<mj-artifact-version-history
[artifactId]="selectedArtifactId"
(versionSelected)="onVersionSelected($event)">
</mj-artifact-version-history>

Compact card for displaying an artifact reference within a conversation message:

<mj-artifact-message-card
[artifact]="artifactRef"
(clicked)="onArtifactCardClicked($event)">
</mj-artifact-message-card>

All artifact viewer plugins implement this interface and are registered with @RegisterClass:

interface IArtifactViewerPlugin {
readonly componentType: Type<IArtifactViewerComponent>;
canHandle(artifactTypeName: string, contentType?: string): boolean;
getMetadata?(artifactVersion: ArtifactVersionEntity): ArtifactMetadata;
}
import { RegisterClass } from '@memberjunction/global';
import { BaseArtifactViewerComponent } from '@memberjunction/ng-artifacts';
@RegisterClass(BaseArtifactViewerComponent, 'MyCustomType')
@Component({
selector: 'my-custom-viewer',
template: `<div>{{ artifactVersion.Content }}</div>`
})
export class MyCustomViewerComponent extends BaseArtifactViewerComponent {
// Custom rendering logic
}
PluginArtifact TypeDescription
JsonArtifactViewerComponentJSONFormatted JSON with syntax highlighting
CodeArtifactViewerComponentCodeCode editor with language detection
MarkdownArtifactViewerComponentMarkdownRendered markdown content
HtmlArtifactViewerComponentHTMLSandboxed HTML rendering
SvgArtifactViewerComponentSVGSVG image rendering
AudioArtifactViewerComponentAudioAudio playback via mj-media-player (transport, waveform scrubber, playback speed)
VideoArtifactViewerComponentVideoVideo playback via mj-media-player (transport, fullscreen, playback speed)
ComponentArtifactViewerComponentComponentDynamic React/Angular component rendering

Audio and video artifacts (both the full viewer and the inline conversation preview) embed the generic mj-media-player from @memberjunction/ng-media-player.

Provides appropriate Font Awesome icons for artifact types:

import { ArtifactIconService } from '@memberjunction/ng-artifacts';
constructor(private iconService: ArtifactIconService) {}
getIcon() {
const icon = this.iconService.getIconForType('Code');
// Returns 'fa-solid fa-code'
}
PackageDescription
@memberjunction/coreCore framework
@memberjunction/core-entitiesEntity type definitions
@memberjunction/globalGlobal utilities and class registration
@memberjunction/interactive-component-typesInteractive component interfaces
@memberjunction/ng-base-typesBase Angular component types
@memberjunction/ng-code-editorCode editor for code artifacts
@memberjunction/ng-media-playerAudio/video playback (mj-media-player) for audio & video artifacts
@memberjunction/ng-notificationsNotification system
@memberjunction/ng-reactReact component bridge
@memberjunction/ng-shared-genericShared generic components
@memberjunction/ng-markdownMarkdown rendering
markedMarkdown parser
@angular/cdkAngular CDK
  • @angular/common ^21.x
  • @angular/core ^21.x
  • @angular/platform-browser ^21.x

Form-aware artifact viewer (interactive forms)

Section titled “Form-aware artifact viewer (interactive forms)”

When an artifact’s spec declares componentRole: 'form', the ComponentArtifactViewerComponent switches to its form-aware branch:

  • Resolves the entity from spec.entityName (or spec.dataRequirements.entities[0].name)
  • Loads TOP 1 record (ordered by NameField then __mj_CreatedAt) and mounts via <mj-interactive-form> bound to that real record
  • Falls back to a fresh NewRecord() when the entity has no rows
  • Exposes a search-as-you-type record picker so users can swap the bound record
  • Bubbles a top-level applyFormRequested @Output carrying { spec, entityName } when the user clicks “Apply to my form”

The InteractiveFormApplyService (exported from this package) consumes that event end-to-end: confirms with the user via MJDialogService, calls Get Active Form For Entity to detect existing state, then routes to Create Interactive Form (net-new) or Modify Interactive Form (refinement → new Pending version).

Consumers wire one line in their template:

<mj-artifact-viewer-panel
...
(applyFormRequested)="onApplyFormRequested($event)">
</mj-artifact-viewer-panel>

…and inject InteractiveFormApplyService in the handler.

Wired in ConversationChatAreaComponent (live chat) and ArtifactResource (standalone artifact viewing in Explorer).

Terminal window
cd packages/Angular/Generic/artifacts
npm run build

ISC