📝

CMS — Master Components

9 new components under projects/cms/master/
🗂️

Content Catalogue

cms/master/contentcatalogue/

Paginated, searchable content list with multi-filter support. The main browse hub for all CMS content.

  • Filter by Status, Space, and Content Type simultaneously
  • Debounced keyword search (300 ms) — switches between searchContent() and getContentList()
  • Grid / List view toggle
  • Status badge renderer: Draft · In Review · Approved · Published · Archived
  • Client-side pagination (pageNo, pageSize signals)
Signals OnPush New
✏️

Content Editor

cms/master/contenteditor/

Structured, multi-tab editor for building CMS documents from containers and blocks.

  • Tab navigation between document sections
  • Container add using CmsEditorService.addContainer()
  • Block add within selected container via addBlock()
  • Real-time props editing with debounced auto-save (2 s) via onBlockPropsChange()
  • Auto-loads document on init; resets state on destroy
Signals OnPush New
🧩

Block Library

cms/master/blocklibrary/

Discovery panel listing all available block types an author can insert into a document.

  • Built-in canonical blocks: RichText, Checklist, Warning, File, Table, Image, Video, QRCode, Decision, Accordion, Banner
  • Server-side override — custom block types loaded from getContainerTypeList()
  • Live search and category filter via computed signals
Signals OnPush New
📦

Collections

cms/master/collections/

Dynamic content collections — groups of content items resolved at runtime via query rules.

  • Create, edit, and save named collections
  • Preview resolved items via db.resolveCollection(collectionId)
  • Lazy preview load with separate loading state
Signals OnPush New
📣

Campaigns

cms/master/campaigns/

Campaign management for targeted content delivery — notifications, assignments, and learning paths.

  • Campaign types: Notification · Assignment · Learning Path
  • Status lifecycle: Draft → Scheduled → Sent → Closed
  • Send campaign action with db.sendCampaign()
  • Assignment list with per-item status update
Signals OnPush New
🛤️

Learning Paths

cms/master/learningpaths/

Sequenced content journeys — ordered lists of content items authors build into a learning path.

  • Create and manage multiple learning paths
  • Add individual content items by content ID
  • Reorder items with moveItem() — updates positionNo in real time
Signals OnPush New
📊

Content Analytics

cms/master/contentanalytics/

Analytics dashboard showing content and channel metrics for a configurable date range.

  • Default range: last 30 days (auto-set on init)
  • Derived counts: Published / Draft / In Review via computed signals
  • Channel stats loaded in parallel with content stats
Signals OnPush New
🌐

Content Portal

cms/master/portal/

End-user content portal — browse, view full documents, and play learning paths.

  • Three views: Browse → View → Learning
  • Space-filtered content listing
  • Full document fetch on item open via getFullDocument()
  • Back navigation between views
Signals OnPush New
⚙️

Render Output

cms/master/renderoutput/

Multi-format output generation — renders content through design-system-backed rendering profiles.

  • Select rendering profile + design system
  • Multi-select content IDs for batch generation
  • Output status: Pending → Generating → Done / Failed
  • Output history list per run
Signals OnPush New
⚙️

CMS — Services

New CmsEditorService + CmsDbService; updated OntologyService
🎛️

CmsEditorService

cms/service/cms-editor.service.ts — NEW

Central reactive state store for the content editor. Manages document, container, and block selection state entirely with Angular signals.

Signals

  • currentDocument — full doc tree (containers + blocks)
  • selectedContainerIdx / selectedBlockId
  • isDirty / isSaving — track auto-save state
  • selectedContainer / selectedBlock — computed

Auto-Save Pipeline

  • Subject<{blockId, propsJson}> piped through debounceTime(2000)
  • switchMap cancels in-flight saves on rapid edits
  • Clears isSaving on completion
  • Immutable update pattern — spread + map, never mutate
Signals New
🔌

CmsDbService

cms/dbservice/cms.db.service.ts — NEW (196 lines)

HTTP data-access service covering all CMS backend API calls. Delegates to GBHttpService.

Content lifecycle

  • getContentFullDocument
  • getContentList (paged)
  • searchContent
  • submitForReview
  • approveContent
  • publishContent
  • archiveContent

Document structure

  • getContainersByContent
  • saveContentContainer
  • reorderContainers
  • deleteContentContainer
  • getBlocksByContainer
  • saveContentBlock
  • updateBlockProps
  • deleteContentBlock

Extended features

  • getVersionHistory
  • restoreVersion
  • getCollectionList / resolveCollection
  • saveCampaign / sendCampaign
  • getLearningPathList
  • generateOutput (profiles)
  • saveDesignSystem
New
🏷️

OntologyService

cms/service/ontology.service.ts — MODIFIED

Re-pointed from the Inventory module to the CMS Taxonomy endpoints.

  • Load URL: Cms.Taxonomy.Get (was Inventory.materialmaster.GetDataValidation)
  • Save URL: Cms.Taxonomy.Save
  • Delete URL: Cms.Taxonomy.Delete
  • Param key: TaxonomyId (was MaterialId)
Modified
🔗

CMS — New API Endpoints

60+ routes added to projects/gbhost/public/api/gb5api/cms.ts

Content Lifecycle

KeyMethodDescription
Cms.Content.GetContentFullDocumentGETFull document tree (containers + blocks)
Cms.Content.GetContentListGETPaged content list with filters
Cms.Content.SearchContentGETKeyword search with space/type filters
Cms.Content.SubmitForReviewPOSTMove content to In-Review status
Cms.Content.ApproveContentPOSTApprove reviewed content
Cms.Content.PublishContentPOSTPublish to portal
Cms.Content.ArchiveContentPOSTArchive published content

Document Structure (Containers & Blocks)

KeyMethodDescription
Cms.ContentContainer.GetByContentGETAll containers for a content item
Cms.ContentContainer.SavePOSTCreate / update container
Cms.ContentContainer.ReorderPOSTReorder containers by position
Cms.ContentContainer.DeleteDELETERemove container and its blocks
Cms.ContentBlock.GetByContainerGETAll blocks in a container
Cms.ContentBlock.GetFullDocumentGETFull block tree for document
Cms.ContentBlock.SavePOSTCreate / update block
Cms.ContentBlock.UpdatePropsPOSTPartial update of block props JSON
Cms.ContentBlock.DeleteDELETERemove single block

Channels, Collections, Campaigns, Learning Paths

KeyMethodDescription
Cms.Channel.GetChannelListGETAll channels
Cms.Channel.AddChannelContentPOSTAttach content to channel
Cms.Collection.ResolveCollectionGETResolve collection query → item list
Cms.Campaign.SendCampaignPOSTDispatch campaign to recipients
Cms.Campaign.UpdateAssignmentStatusPOSTUpdate per-user assignment status
Cms.LearningPath.SaveLearningPathItemPOSTAdd/reorder item in path

Design System, Rendering, Versioning

KeyMethodDescription
Cms.DesignSystem.GetSelectListGETDesign system options for renderer
Cms.RenderingProfile.GenerateOutputPOSTTrigger multi-format content render
Cms.ContentVersion.GetVersionHistoryGETVersion history for a content item
Cms.ContentVersion.RestoreVersionPOSTRestore older version
Cms.Taxonomy.Get / Save / DeleteGET / POST / DELETECMS taxonomy (ontology) management
📋

Work Instruction (WI) — Player & Renderer

3 new content components · 3 new renderer components · Print support · Extended model
📐

Model & Enum Changes

wi/src/lib/enums/wi.enums.ts + wi/src/lib/models/wi.models.ts

The WI data model gains three new content types and a full container hierarchy enabling multi-zone layouts.

ContentType enum — additions

RichText = 0
Image = 1
Video = 2
PDF = 3
Checklist = 4
Warning = 5
DecisionBranch = 6
File = 7 ← NEW
QRCode = 8 ← NEW
DataTable = 9 ← NEW

WiContainerType enum — NEW

Single = 0
TwoColumn = 1
Banner = 2
Accordion = 3
Tab = 4

WiStepContainer interface — NEW

interface WiStepContainer {
  containerId: number
  containerType: WiContainerType
  containerLabel?: string
  blocks: WiStepContent[] // blocks nested per container
}
ℹ️
Backward Compatibility: WiStep retains the existing flat contents?: WiStepContent[] field alongside the new containers?: WiStepContainer[]. The renderer auto-wraps flat content into a single container so no existing documents break.
NewModified
🏗️

3-Layer Renderer Architecture

wi/src/lib/renderer/

A clean hierarchical rendering pipeline separating document, container, and block concerns.

Layer 1
ContentDocumentRenderer
Input: containers[]
Maps each container to layer 2
→
Layer 2
ContentContainerRenderer
Input: WiStepContainer
Groups blocks by zone
Applies container CSS layout
→
Layer 3
ContentBlockRenderer
Input: WiStepContent
@switch on ContentType
Delegates to type component

Container layouts supported by ContentContainerRenderer:

Single (flex column) TwoColumn (CSS grid) Banner (full-width) Accordion (details/summary) Tab (zone tabs)

Blocks are sorted by blockInContainerPos within each named zone. Print mode flattens Accordion and Tab zones to block display.

NewRenderer
🖼️

WiContentBannerComponent

wi/player/content/wi-content-banner.component.ts

Renders a full-width hero / banner block with background image and bottom-aligned caption.

  • Input: block: WiStepContent (signal input)
  • Background image from block().mediaUrl
  • Caption from block().mediaCaption
  • Print: removes background, adds border for ink-safe output
New
📎

WiContentFileComponent

wi/player/content/wi-content-file.component.ts

Renders a downloadable file attachment block — linked file with icon.

  • Input: block: WiStepContent (signal input)
  • Display name: block().mediaCaption or filename from URL
  • Opens in new tab (target=_blank)
  • File type icon displayed alongside link
New
📊

WiContentTableComponent

wi/player/content/wi-content-table.component.ts

Renders a structured data table from JSON stored in contentRef.

  • Input: block: WiStepContent (signal input)
  • JSON format: { headers: string[], rows: string[][] }
  • Computed tableData() — safe parse with empty-state fallback
  • Standard thead/tbody HTML table with WI styling
New
🖨️

WiPrintComponent

wi/player/wi-print.component.ts

Print-optimized full-document view — renders every section and step of a WI in a single scrollable layout before calling window.print().

  • Input: wiId: number — fetches full detail on init
  • stepsForSection(sectionId) — groups steps by section
  • stepContainers(step) — backward-compat wrapper (flat → container)
  • Uses ContentDocumentRendererComponent per step
  • Print-specific SCSS: hides UI chrome, forces page breaks
New
🔄

WiPlayerStep — Updated

wi/player/wi-player-step.component.ts

Player step component updated to delegate rendering to the new document renderer.

  • activeContainers() — returns step.containers or wraps step.contents into single container
  • Added ContentDocumentRendererComponent to component imports
  • No breaking change to existing steps
Modified
✅

Summary

What this commit delivers end-to-end
📝

CMS — Full authoring system

  • Browse, search, filter all content (Catalogue)
  • Create & edit structured documents (Editor + Block Library)
  • Auto-save with debounce via CmsEditorService
  • Lifecycle: Draft → Review → Approved → Published → Archived
  • Version history & restore
  • Channels, Collections, Campaigns, Learning Paths
  • Multi-format rendering output
  • Analytics dashboard
  • End-user Portal (browse + read + learn)
📋

Work Instruction — Rich rendering

  • 3 new block types: File attachment, Data table, Banner/hero
  • Container model: Single / TwoColumn / Banner / Accordion / Tab layouts
  • 3-layer renderer pipeline (Document → Container → Block)
  • Zone-aware block grouping within containers
  • Full backward compatibility — flat content auto-wrapped
  • Print view with section/step grouping and page-break CSS
  • All new components use OnPush + signal inputs