Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


id: TEDY.01.4 template: tool-feature module: tedy state: Proposed traces-from: [] source-refs:

  • reference-editor/app/src/app/resources/code-system/containers/concepts
  • terminology-server/ts/code-system (concept + entity-version transaction)
  • helex-tx/modules/tedy/frontend/src/pages/code-system/CodeSystemConceptsTab.tsx
  • helex-tx/modules/tedy/frontend/src/pages/code-system/concepts/presentation.ts
  • helex-tx/modules/tedy/frontend/src/pages/code-system/concepts/ConceptPresentationTable.tsx
  • helex-tx/modules/tedy/frontend/src/pages/code-system/concepts/ConceptCell.tsx
  • helex-tx/modules/tedy/frontend/src/pages/code-system/concepts/ConceptColumnBuilder.tsx
  • helex-tx/modules/tedy/frontend/src/pages/code-system/concepts/ConceptEditForm.tsx
  • helex-tx/libs/tedy/src/lib/client/conceptClient.ts
  • helex-tx/libs/tedy/src/lib/hooks/useConcepts.ts
  • helex-tx/libs/tedy/src/lib/utils/conceptDisplay.ts author: TEDY bootstrap created: 2026-08-09 updated: 2026-08-09

TEDY.01.4 – Code System Concept Presentation

Feature grouping

Child of TEDY.01 – Code System (Common Spec). Refines the Concepts tab of TEDY.01.3 – Code System View. Siblings: TEDY.01.1 List, TEDY.01.2 Add.

Description

The Concepts tab renders a Code System’s concepts through a configurable, definition-driven presentation instead of a fixed code / display / status table. A Code System carries far more per concept than three columns can show — designations in many languages and typed property values (some resolved against other code systems or value sets) — and large systems are hierarchical (e.g. an ICD-10 edition with tens of thousands of concepts under an is-a tree).

The user composes which fields appear, how they are grouped into columns, and how designations / properties are laid out, using a two-column drag builder. The layout is derived by default from the Code System definition and persisted per Code System. The presentation table itself stays read-only (“light immutable”); editing a concept happens in the selected row’s detail form, which saves the whole concept back through the entity-version transaction.

┌ Concepts ───────────────────────── [ Search ] [ ⚙ Configure ] [ ⛃ ] ┐   ┌ Concept ───────────┐
│ Code        │ Display / Designations │ Properties                    │   │ allergy   [active] │
│ allergy     │ Allergy                │ valueset: …/allergy           │   │ Designations   +Add│
│             │ en: Allergy            │ ui-component: select          │   │ en Allergy     ★   │
│             │ et: Allergia           │ usage: clinical               │   │ et Allergia    ☆   │
│             │ ru: Аллергия           │ careplan-printout: true       │   │ Properties  +Add ▾ │
│ diagnosis   │ Diagnosis              │ conceptOrder: 10              │   │ valueset […]       │
│             │ en: Diagnosis          │ codesystem: …/rhk10           │   │ …                  │
│             │ …                      │ …                             │   │           [ Save ] │
└──────────────────────────────────────────────────────────────────────┘   └────────────────────┘

Glossary Terms

Per TEDY.01 § Glossary, plus:

TermMeaning
PresentationThe per-Code-System layout config: mode, editable flag, and columns.
ColumnA first-level group in the presentation; renders one table cell per concept.
ElementA second-level item inside a column: code, display, status, designations, properties, or br (line break).
Designation blockA single element that renders a concept’s designations, optionally filtered to chosen languages.
Property blockA single element that renders a concept’s property values, optionally filtered to chosen properties.
Defined propertyA CodeSystem.property entry, carrying kind (property | designation), type, showInList, and an optional Coding rule.

Business Feature Sitemap

flowchart LR
    ROOT[TEDY.01] --> VIEW[TEDY.01.3 View]
    VIEW --> CT[TEDY.01.4 Concept Presentation]
    CT --> TBL[Read-only table\nplain / hierarchical]
    CT --> CFG[Configure builder\ndrag columns]
    CT --> EDIT[Editable detail\ntransaction save]

The presentation config model

Two levels only: columns (level 1) → elements (level 2). code is pinned as the first element of the first column and cannot be moved or removed.

type ConceptElement =
  | { kind: 'code' }                                // pinned first; not movable/removable
  | { kind: 'display'; bold?: boolean }
  | { kind: 'status' }
  | { kind: 'designations'; languages?: string[] }  // undefined/empty ⇒ all languages
  | { kind: 'properties'; names?: string[] }        // undefined/empty ⇒ all showInList
  | { kind: 'br' };                                  // explicit line break

interface ConceptColumn {
  id: string;
  title?: string;                    // non-localized header override (legacy / fallback)
  titles?: Record<string, string>;   // localized header per language code, e.g. { en: 'Term', et: 'Termin' }
  elements: ConceptElement[];
}

interface ConceptPresentation {
  mode: 'plain' | 'hierarchical';
  editable: boolean;
  columns: ConceptColumn[];
}
  • designations and properties are single whole-block elements — the user places the block, then chooses which languages / which properties it includes. Individual designations are never split across columns. A block may share a column with other elements (the default groups display + designations).
  • Singleton elements (code, display, status, designations, properties) may appear at most once across the whole presentation; br may repeat.
  • Localized column header — a column may carry a per-language header via titles (keyed by language code, from the CS’s supported languages). When absent, the header is auto-derived from the column’s elements. Resolution for a display language L: titles[L]title (legacy) → any set titles value → the auto-derived label. This is a presentation preference only (client-side; no server field).

Default presentation (derived from the CS definition)

  • mode = hierarchical when CodeSystem.hierarchyMeaning is set, else plain.
  • editable = false.
  • columns = [ [code], [display(bold), designations], [properties] ], where the designations block defaults to all languages and the properties block defaults to properties with showInList. A line break is rendered automatically before the designations block (it is not the first text in its column).

Read-only cell rendering rules (per column, per concept)

Each element renders in order into a single cell:

  • codeconcept.code.
  • displayconceptDisplay(concept, language) (bold when bold).
  • status → status chip (the concept’s current entity-version status).
  • designations → the concept’s designations, filtered to languages if set (else all), preferred-language first, each shown as lang + ": " + value, and preceded by a line break unless it is the first text already in the column.
  • properties → each included property (names if set, else showInList) as label: value, one per line; Coding values resolve to a display via the property rule (value set / code systems); each preceded by a line break unless first in the column.
  • br → a line break.

Configuration builder

Opened from a Configure button on the concepts toolbar (an AppDrawer, size 880). Built with @dnd-kit (module-local dependency) as a two-container sortable.

  • Left — palette + settings: mode select (plain | hierarchical); editable checkbox; a menu with Clear (empty all but the pinned code column) and Reset to defaults (recompute from the CS definition); and the source elements not yet placed (display, status, designations, properties).
  • Right — presentation builder: ordered columns, each a droppable group of sortable elements, with an Add line break affordance and an Add column button. display carries a Bold toggle; designations and properties carry an inline picker (languages / property names, “All” when none chosen). code is rendered pinned in the first column and is not draggable or removable.
  • Drag palette → column adds; drag element → palette removes; drag within/between columns reorders (never before the pinned code).
  • Rename column — each column header has a rename (✎) control opening a popover with one input per supported language (seeded from the column’s titles); the control is highlighted when a custom header is set. Blank inputs fall back to the auto-derived label.
  • Apply persists the presentation (including per-column titles) and updates the live table; Cancel discards.

Persistence

Per Code System, in browser localStorage under key helex.tedy.conceptPresentation.{codeSystemId}. On load the saved config is used; absent (or on Reset) the default is recomputed from the CS definition. No server-side presentation store exists.

Editable detail + save

When editable is on, selecting a row opens the editable concept detail form (otherwise the read-only view is shown):

  • Designations — rows of language select · type select · value · preferred star · delete; Add appends a row.
  • Property values — one row per value, typed by the defined property: boolean → checkbox; integer / decimal → number input; CodingTxConceptSelect scoped by the property rule.valueSet (falling back to code + code-system inputs); otherwise a text input. Add property appends from the CS’s defined value-properties.
  • Save builds { concept, entityVersion } with the complete designation and property-value lists and POSTs the concept transaction (full replace of the current entity version — terminology-server has no JSON-patch). Version-scoped when a version route is active, else resource-level. The concepts query is invalidated on success.

Data Model

Reuses TEDY.01 § Data Model. Fields consumed here:

  • CodeSystem.hierarchyMeaning — association type driving the tree (e.g. is-a).
  • CodeSystem.property[] (defined properties) — name, type, kind (property | designation), showInList, and rule ({ valueSet?, codeSystems? }) for Coding resolution.
  • CodeSystemVersion.supportedLanguages / preferredLanguage — the language set and preferred order.
  • concept → versions[] → { designations[], propertyValues[], associations[] }:
    • Designation: name (value), language, preferred, status, designationType.
    • EntityPropertyValue: value, entityProperty (name), entityPropertyId, entityPropertyType.
    • concept.leaf / concept.childCount gate the tree expander.

API Endpoints

All under /ts/code-systems/{id} (see TEDY.01 § API).

PurposeCall
List (flat, paged)GET …/concepts?textContains&codeSystemEntityStatus&codeSystemVersion&displayLanguage&limit&offset&sort
Roots (tree)GET …/concepts?associationRoot={hierarchyMeaning}&sort=code&limit&offset
Children (one level, lazy)`GET …/concepts?associationSource={hierarchyMeaning}
Filtered treeGET …/concepts/tree-search?associationType={hierarchyMeaning}&textContains=… → flat items with parentCode + matched
Save (transaction)POST …/[versions/{version}/]concepts/transaction body { concept, entityVersion }
DeleteDELETE …/concepts/{code}

Envelope: { data, meta }; errors per the TEDY.01 error contract.

Sitemap / Navigation

No new routes. Enhances the existing Concepts tab of TEDY.01.3: /tedy/code-systems/{id}/concepts (resource-level) and the version-scoped concepts route when active. The Configure drawer and detail panel are in-page surfaces.

Security / Permissions

  • Read: browse the presentation with CodeSystem read access.
  • Edit (the editable toggle + Save): requires *.CodeSystem.write; the Save action is gated by the same privilege as TEDY.01.2 / the code-system edit flow.
  • Presentation config is a client-only preference — no permission implications.

Non-Functional Requirements

  • Hierarchical mode loads children lazily, one level per expand, so a 30k+ concept system opens without fetching the whole tree.
  • The table is never inline-editable; editing is isolated to the detail form to keep large lists responsive.
  • i18n: all builder / edit labels in en / et / ru (tedy.concept.presentation.*, tedy.concept.edit.*); designation language codes render verbatim.

Business Tests

  1. Default layout — a plain CS opens with columns code · display(bold) + designations · properties(showInList); designations read lang: value, preferred-language first.
  2. Hierarchical — a CS with hierarchyMeaning opens as a tree; expanding a node lazily loads its children; leaves show no expander.
  3. Configure round-trip — add / remove / reorder columns and elements, toggle bold, pick designation languages and properties, Apply → the table updates and the config survives reload; Reset restores the derived default; Clear leaves only the pinned code.
  4. Code pinnedcode cannot be dragged, removed, or displaced from the first cell.
  5. Editable detail — with editable on, selecting a row shows the edit form; a boolean property renders a checkbox, a Coding property a value-set select; Save posts the transaction and the row reflects the change after refresh.
  6. Localized column header — rename a column with a title per language, Apply → the header shows the title for the active display language and survives reload; switching the display language shows that language’s title (or the auto-derived label if none set).

Source Code References

  • Presentation model + persistence: presentation.ts.
  • Read-only table (plain + hierarchical): ConceptPresentationTable.tsx, ConceptCell.tsx.
  • Builder: ConceptColumnBuilder.tsx (@dnd-kit).
  • Editable detail: ConceptEditForm.tsx.
  • Tab wiring: CodeSystemConceptsTab.tsx.
  • Data layer: libs/tedy conceptClient.ts (searchConcepts, searchConceptRoots, searchConceptChildren, searchConceptTree, saveConcept, deleteConcept) + useConcepts.ts (useConcepts, useConceptRoots, useSaveConcept).

Differences (live vs source)

  • The reference editor’s concept view is a fixed code / display / status table with a separate edit dialog. TEDY generalises the read layout into a definition-driven, user-composed presentation while keeping the same terminology-server contracts (concept list params, hierarchy via hierarchyMeaning, entity-version transaction).
  • “Patch” in the original requirement maps to the entity-version transaction (full replace); terminology-server exposes no JSON-patch for concepts.
  • Presentation config is a TEDY-only client preference; the reference product has no equivalent per-CS layout store.

Traces

traces-from is empty pending a user story (EMR rules require a story before a solution spec). Gap: create a thin “configure how a Code System’s concepts are presented” story and link it here before promotion to Accepted.