API Responses & Visual Rendering Guide

For each of the 5 container layout types — Single, Banner, TwoColumn, Tab, Accordion — this document shows the exact JSON the API returns, and a projected rendering of how it appears after the Angular renderer processes it. Based on test dataset WiId=1001 / CMS ContentId=5001.

API JSON Responses Visual Renderings WI Steps 201–205 CMS Containers 601–605

Endpoint

GET /wi/WI/GetWIFullDetail

Returns full nested structure

Response nesting

3

sections → steps → containers → blocks

Payload field

contentRef

JSON string — parse before use

Contents

  1. Single Column (Step 201 · CMS 601)
  2. Banner (Step 202 · CMS 602)
  3. Two Column (Step 203 · CMS 603)
  4. Tab Panel (Step 204 · CMS 605)
  5. Accordion (Step 205 · CMS 604)
  6. API Field Reference
☰

Single Column

containerType: 0 WI Step 201 · ContainerId 301  |  CMS Container 601
API Request
GET /wi/WI/GetWIFullDetail
    ?WiId=1001
Response — Step 201 containers[ ] (abbreviated)
{
  "wiId": 1001,
  "wiCode": "WI-BKT-001",
  "sections": [{
    "wiSectionId": 101,
    "sectionTitle": "Preparation & Safety",
    "steps": [{
      "wiStepId": 201,
      "stepTitle": "Tool & PPE Pre-check",
      "containers": [{
        "containerId": 301,
        "containerType": 0,  // Single
        "containerLabel": "Tool Check",
        "blocks": [
          {
            "wiStepContentId": 3001,
            "contentType": 0,  // RichText
            "contentSource": 0,  // Inline
            "zoneName": "main",
            "blockInContainerPos": 1,
            "contentRef": "{\"html\":\"<p>Verify all required tools...</p>\",\"plainText\":\"...\"}"
          },
          {
            "wiStepContentId": 3002,
            "contentType": 4,  // Checklist
            "zoneName": "main",
            "blockInContainerPos": 2,
            "contentRef": "{\"title\":\"Pre-start Checklist\",\"items\":[...]}"
          }
        ]
      }]
    }]
  }]
}
Rendered Output — how ContentContainerRenderer produces this
Live visual projection
Step 1 Tool & PPE Pre-check

Verify all required tools and PPE are present before starting.

Pre-start Checklist
Torque wrench (range 10–50 Nm)
Safety glasses
Anti-static wrist strap
Alignment jig (BKT-JIG-01)
M6 hex bolts ×6 (pre-torqued bag)

Banner

WI Step 202 · ContainerId 302  |  CMS Container 602
API Request
GET /wi/WI/GetWIFullDetail
    ?WiId=1001
// Step 202 in sections[0].steps[1]
Response — Step 202 containers[ ] (abbreviated)
"containers": [{
  "containerId": 302,
  "containerType": 2,  // Banner
  "containerLabel": "Danger Notice",
  "blocks": [
    {
      "wiStepContentId": 3010,
      "contentType": 10,  // Banner block
      "zoneName": "main",
      "blockInContainerPos": 1,
      "contentRef": "{
        \"title\": \"DANGER\",
        \"message\": \"Ensure main power isolator is
           in OFF position and locked...\",
        \"imageUrl\": \"/assets/wi/banners/electrical-danger.jpg\",
        \"ctaLabel\": \"View LOTO Procedure\",
        \"ctaUrl\": \"/wi/1002\"
      }"
    },
    {
      "wiStepContentId": 3011,
      "contentType": 5,  // Warning
      "zoneName": "main",
      "blockInContainerPos": 2,
      "contentRef": "{
        \"message\": \"Confirm isolation with voltage tester.\",
        \"warningLevel\": 3
      }"
    }
  ]
}]
Rendered Output
Live visual projection
Step 2 Electrical Isolation Confirmation
⚡ DANGER
Ensure main power isolator is in OFF position and locked before proceeding. Tag-out/Lock-out (LOTO) must be applied.
View LOTO Procedure →
🚫 Confirm isolation with approved voltage tester. Do not rely on visual switch position alone.
⊞

Two Column

containerType: 1 WI Step 203 · ContainerId 303  |  CMS Container 603
API Request
GET /wi/WI/GetWIFullDetail
    ?WiId=1001
// Step 203 in sections[1].steps[0]
Response — Step 203 containers[ ] (abbreviated)
"containers": [{
  "containerId": 303,
  "containerType": 1,  // TwoColumn
  "blocks": [
    {
      "wiStepContentId": 3020,
      "contentType": 1,  // Image
      "contentSource": 2,  // FileStore
      "zoneName": "left",   // ← LEFT column
      "blockInContainerPos": 1,
      "contentRef": "{\"imageUrl\":\"/assets/...\",\"caption\":\"Fig 1\"}"
    },
    {
      "wiStepContentId": 3021,
      "contentType": 0,  // RichText
      "zoneName": "right",  // ← RIGHT column
      "blockInContainerPos": 1
    },
    {
      "wiStepContentId": 3022,
      "contentType": 5,  // Warning
      "zoneName": "right",  // ← same RIGHT column
      "blockInContainerPos": 2  // stacked below RichText
    }
  ]
}]
How the renderer reads TwoColumn blocks: it groups all blocks by zoneName, then renders the "left" group in column 1 and the "right" group in column 2. Within each zone, blocks are sorted by blockInContainerPos. There is no separate "left zone API" — it is all one flat blocks[] array, differentiated only by zoneName.
Rendered Output
Live visual projection
Step 3 Bracket Alignment
bracket-alignment.png
Fig 1 — Alignment mark positions
  1. Position bracket so all 4 alignment marks are visible.
  2. Insert M6 bolts finger-tight into all 6 holes.
  3. Verify bracket is flush with the datum face (±0.5 mm).
  4. Confirm no cable routing is pinched behind bracket.
⚠️ Brackets must be flush. A gap >0.5 mm requires shimming — see Engineering Note EN-BKT-03.
⊟

Tab Panel

containerType: 4 WI Step 204 · ContainerId 304  |  CMS Container 605
API Request
GET /wi/WI/GetWIFullDetail
    ?WiId=1001
// Step 204 in sections[1].steps[1]
Response — Step 204 containers[ ] (abbreviated)
"containers": [{
  "containerId": 304,
  "containerType": 4,  // Tab
  "containerLabel": "Model Variant Torque",
  "blocks": [
    // TAB 1: "Model A (2023+)"
    { "wiStepContentId": 3030,
      "contentType": 0,    // RichText
      "zoneName": "Model A (2023+)",
      "blockInContainerPos": 1 },
    { "wiStepContentId": 3031,
      "contentType": 9,    // DataTable
      "zoneName": "Model A (2023+)",
      "blockInContainerPos": 2 },

    // TAB 2: "Model B (2021-2022)"
    { "wiStepContentId": 3032, "contentType": 0,
      "zoneName": "Model B (2021-2022)", "blockInContainerPos": 1 },
    { "wiStepContentId": 3033, "contentType": 9,
      "zoneName": "Model B (2021-2022)", "blockInContainerPos": 2 },

    // TAB 3: "Legacy (pre-2021)"
    { "wiStepContentId": 3034, "contentType": 5,
      "zoneName": "Legacy (pre-2021)", "blockInContainerPos": 1 },
    { "wiStepContentId": 3035, "contentType": 0,
      "zoneName": "Legacy (pre-2021)", "blockInContainerPos": 2 }
  ]
}]
How the renderer reads Tab blocks: it extracts the unique set of zoneName values in insertion order — these become the tab labels. Each tab's content is the blocks where zoneName === tabLabel, sorted by blockInContainerPos. To add a new tab: insert a block with a new zone name. To reorder tabs: the renderer preserves the DB insertion order of the first occurrence of each zone name.
Rendered Output — "Model A (2023+)" tab active
Live visual projection
Step 4 Torque Application
Model A (2023+)
Model B (2021-2022)
Legacy (pre-2021)

Model A uses the revised torque sequence. Apply bolts in the cross-pattern shown on the jig label.

FastenerTorque (Nm)PassTool
M6 outer ×4101st passT-10
M6 outer ×418FinalT-10
M6 centre ×222Single passT-20
— "Model B (2021-2022)" tab (when clicked) —

Model B uses an older bracket profile. Torque in sequential order (1→6) not cross-pattern.

FastenerTorque (Nm)Tool
M6 ×615T-10
M8 centre30T-20
≡

Accordion

containerType: 3 WI Step 205 · ContainerIds 305 + 306  |  CMS Container 604
API Request
GET /wi/WI/GetWIFullDetail
    ?WiId=1001
// Step 205 in sections[1].steps[2]
// This step has TWO containers:
//   containers[0] = Accordion (3 panels)
//   containers[1] = Single   (QR code)
Response — Step 205 containers[ ] (abbreviated)
"containers": [
  {
    "containerId": 305,
    "containerType": 3,  // Accordion
    "containerLabel": "Reference & Checklist",
    "blocks": [
      {
        "wiStepContentId": 3040,
        "contentType": 9,  // DataTable
        "zoneName": "Fastener Specifications",
        "blockInContainerPos": 1
      },
      {
        "wiStepContentId": 3041,
        "contentType": 4,  // Checklist
        "zoneName": "Completion Checklist",
        "blockInContainerPos": 1
      },
      {
        "wiStepContentId": 3042,
        "contentType": 7,  // File
        "contentSource": 2,  // FileStore
        "zoneName": "Safety Data Sheet",
        "blockInContainerPos": 1
      }
    ]
  },
  {
    "containerId": 306,
    "containerType": 0,  // Single (second container on same step)
    "containerLabel": "Final Action",
    "blocks": [{
      "wiStepContentId": 3043,
      "contentType": 8,  // QRCode
      "zoneName": "main",
      "blockInContainerPos": 1,
      "contentRef": "{\"targetUrl\":\"/wi/signoff?...\",\"label\":\"Scan to sign-off\"}"
    }]
  }
]
How the renderer reads Accordion blocks: exactly like Tab — the unique zoneName values become accordion panel headers. Each panel contains the blocks matching that zone, sorted by blockInContainerPos. Step 205 also shows that a single step can have multiple containers: the Accordion is positionNo=1 and the Single (QR code) is positionNo=2. The renderer iterates step.containers[] in order, rendering each container independently below the previous one.
Rendered Output — Accordion expanded, Single below
Live visual projection
Step 5 Completion & Sign-off
Fastener Specifications ▲
Part NoDescriptionQtyTorque NmClass
M6-HEX-SSM6 Hex Bolt Stainless618Grade 8
M6-WSH-SSM6 Flat Washer6N/A316 SS
LOCTITE-243Thread Lock Medium1 dropN/ABlue
Completion Checklist ▲
Final Inspection Checklist
All 6 bolts torqued to spec
Bracket flush with datum (checked with gauge)
Cable routing clear of bracket edges
Loctite 243 applied and cured (min 10 min)
Work area cleaned of metal swarf
Safety Data Sheet ▼
📄 Loctite 243 Safety Data Sheet.pdf 200 KB ↓ Download
Scan to record digital sign-off

CMS Equivalents — same request pattern, same rendering logic

CMS API Requests (for ContentId 5001)
// Get all containers for a CMS document
GET /cms/ContentContainer/GetContentContainersByContent
    ?ContentId=5001

// Get blocks for one container (e.g. the Banner container)
GET /cms/ContentBlock/GetContentBlocksByContainer
    ?ContentContainerId=602

// Save/update block content (the CMS editor auto-save call)
PUT /cms/ContentBlock/UpdateBlockProps
{
  "blockId": 4010,
  "propsJson": "{\"title\":\"...\",\"message\":\"...\"}"
}
CMS ContainerTypeLayout keyPropsJson fieldEquivalent WI field
601SINGLEcontainerTypeCode="SINGLE"PropsJsoncontentRef
602BANNERcontainerTypeCode="BANNER"PropsJsoncontentRef
603TWOCOLcontainerTypeCode="TWOCOL"PropsJsoncontentRef
604ACCORDIONcontainerTypeCode="ACCORDION"PropsJsoncontentRef
605TABcontainerTypeCode="TAB"PropsJsoncontentRef

API Field Reference

FieldSourceTypeNotes
containers[] WiStep WiStepContainer[] New field. If absent (legacy steps), renderer wraps contents[] into a synthetic Single container.
containerType WiStepContainer WiContainerType enum (int) 0=Single, 1=TwoColumn, 2=Banner, 3=Accordion, 4=Tab. Drives which layout template is used.
zoneName WiStepContent / ContentBlock string For Single: always "main". For TwoColumn: "left" or "right". For Tab/Accordion: becomes the tab label / panel header. Case-sensitive.
blockInContainerPos WiStepContent int Ordering within a zone. Position 1 in "left" and position 1 in "right" are independent. Always starts at 1.
contentRef WiStepContent string (serialized JSON) Raw JSON string — renderer calls JSON.parse(block.contentRef). Schema depends on contentType.
propsJson ContentBlock (CMS) string (serialized JSON) Same pattern as contentRef — same JSON schemas, different field name.
contentType WiStepContent ContentType enum (int) 0=RichText 1=Image 2=Video 3=PDF 4=Checklist 5=Warning 6=DecisionBranch 7=File 8=QRCode 9=DataTable 10=Banner
positionNo (on container) WiStepContainer int Order of containers within a step. One step can have multiple containers (e.g. Step 205 has an Accordion at pos=1 and a Single at pos=2).
GB5 · WI + CMS Layout Guide · Based on test dataset WiId=1001 / CMS ContentId=5001 · Test data file: docs/test-data-inserts.sql