Terminology
This area covers 32 features. Watch the walkthrough, then use the reference below — each feature links to the exact moment it appears (▶).
Who this is for: Translator / reviewer. Each feature below lists the role/permission it requires.
Features
View terminology page and tab navigation ▶ 00:00
As a translator, I want to see the terminology page with tabs for managed concepts, review queue, candidates, and violations, so that I can organize my term work by stage.
How it works. User navigates to /project/:id/terminology. The page renders with header (Back button, Export CSV/TBX, Import, Add concept buttons) and a tab strip showing four tabs: 'Concepts', 'Review queue', 'Candidate terms', and 'Violations'. Tab selection changes content pane. Empty states show placeholder text and context-appropriate CTA buttons.
Key files
src/components/TerminologyPage.tsx:801src/components/TerminologyPage.tsx:1181-1230
View library statistics header ▶ 00:00
As a project lead, I want to see aggregated terminology metrics (active concepts, % enforced, % infringed, cells analyzed, top-5 most infringed terms), so that I can monitor compliance at a glance.
How it works. A card at the top of TerminologyPage shows four stat boxes: 'Active concepts' (count), 'Enforced' (%), 'Infringed' (%), 'Cells analyzed' (count). Percentages only display when cells exist. Top-5 most-infringed section appears below if violations exist, showing concept name + violation count in pills. Colors: emerald for 100% enforced or 0% infringed, amber for 1-20% infringed, red for >20% infringed.
Key files
src/components/TerminologyPage.tsx:580-682src/lib/terminology/stats.ts:1-77
Create a concept (add source term + renderings + notes + status) ▶ 00:05
As a project lead, I want to add a new concept with a source term, one or more target renderings (each tagged required/alternate/forbidden), optional notes, and an initial status (suggested/approved/old), so that I can build the termbase.
How it works. User clicks 'Add concept' button, dialog opens with fields: 'Source term' (text input, required, auto-focused), 'Target renderings' (repeating group with rendering text + status dropdown + remove button), 'Add rendering' button adds a new empty row, 'Notes' (optional text), 'Status' dropdown (default 'suggested'). Save button validates: source term and at least one rendering required. Success closes dialog; error displays inline.
Key files
src/components/TerminologyPage.tsx:199-361src/lib/terminology/store.ts:28-42
Edit a concept (update source term, renderings, notes, status) ▶ 00:00
As a project lead, I want to edit an existing concept to update its source term, renderings, notes, or status, so that I can refine terminology definitions over time.
How it works. User clicks pencil icon on a concept row, the same ConceptDialog opens with 'Edit concept' title and pre-filled values. Rendering rows can be edited, added, or removed. Status dropdown allows draft↔approved↔old transitions. Save validates same as create, persists, closes dialog.
Key files
src/components/TerminologyPage.tsx:1348-1359src/lib/terminology/store.ts:55-67
Delete a concept with confirmation ▶ 00:00
As a project lead, I want to delete a concept with a confirmation dialog to prevent accidents, so that I can remove obsolete terms.
How it works. User clicks trash icon on a concept row, ConfirmActionDialog opens with title 'Delete concept' and message showing concept name. A checkbox states 'I understand this deletes the concept and all its renderings for everyone in the project.' Only after checking the box does the 'Delete concept' button (destructive style) enable. Cancel or dismiss closes dialog without deleting.
Key files
src/components/TerminologyPage.tsx:1376-1390src/lib/terminology/store.ts:78-82
Add rendering to a concept ▶ 00:00
As a project lead, I want to add a new target rendering to an existing concept during editing, so that I can expand the approved translation options.
How it works. In the edit dialog, 'Add rendering' button appends a new row with empty text, status='admitted', and a remove button. User fills text and optionally changes status. Save persists the new rendering.
Key files
src/components/TerminologyPage.tsx:235-237src/components/TerminologyPage.tsx:291-309
Remove rendering from a concept ▶ 00:00
As a project lead, I want to remove a rendering from a concept, so that I can clean up obsolete or incorrect translations.
How it works. In the edit dialog, clicking the trash icon on any rendering row removes it. After deletion, remaining rows shift up. At least one rendering must remain for save to succeed.
Key files
src/components/TerminologyPage.tsx:231-233src/components/TerminologyPage.tsx:175-182
Set rendering status (required/alternate/forbidden) ▶ 00:00
As a project lead, I want to tag each rendering as 'required' (preferred), 'alternate' (admitted), or 'forbidden', so that I can specify which translations are mandatory, acceptable, or must-not-use.
How it works. In the edit dialog, each rendering row has a Status dropdown with three options: 'required' (green, emerald pill), 'alternate' (muted gray), 'forbidden' (red, strikethrough). Selection persists in the concept. On the concepts list view, rendering chips reflect the chosen status with matching colors and label.
Key files
src/components/TerminologyPage.tsx:148-174src/components/TerminologyPage.tsx:72-76
Set concept status (suggested/approved/old) ▶ 00:00
As a project lead, I want to set each concept's status to 'suggested' (draft), 'approved' (active), or 'old' (deprecated), so that I can control which terms are enforced and which are archived.
How it works. In the add/edit dialog, 'Status' dropdown shows three options: 'suggested', 'approved', 'old'. New concepts default to 'suggested'. On the concepts list, status badges show the current status with color coding: blue secondary for suggested, default for approved, destructive for old. Only 'approved' concepts are compiled into rules and enforced.
Key files
src/components/TerminologyPage.tsx:323-346src/components/TerminologyPage.tsx:100-124
Add concept notes (optional context for translators) ▶ 00:00
As a project lead, I want to add optional contextual notes to a concept, so that translators understand the nuance and usage context.
How it works. In the add/edit dialog, a 'Notes (optional)' text input accepts free-form context text (e.g., 'Often appears in ceremonial contexts'). Notes are stored and displayed (truncated) in the concepts table. Notes are preserved during merge and export.
Key files
src/components/TerminologyPage.tsx:313-321src/components/TerminologyPage.tsx:204
Import concepts from CSV ▶ 00:00
As a project lead, I want to import a termbase from a CSV file with columns (sourceTerm, rendering, status, notes), so that I can bulk-load existing terminology.
How it works. User clicks 'Import' button, TermbaseImportDialog opens with two tabs: CSV and TBX. On CSV tab, a drag-drop zone accepts .csv/.tsv files. Format: one row per rendering (grouped by sourceTerm), columns: sourceTerm, rendering, status ('preferred'/'admitted'/'forbidden', case-insensitive), notes (optional, first occurrence per sourceTerm wins). Status defaults to 'preferred'. Imported concepts receive status 'active'. Parsing errors (malformed CSV, invalid status) display inline. Success closes dialog and reloads concepts.
Key files
src/components/TerminologyPage.tsx:373-496src/lib/terminology/csv.ts:42-90
Import concepts from TBX ▶ 00:00
As a project lead, I want to import a termbase from a TBX-Basic XML file, so that I can load standard ISO 30042 term resources.
How it works. In the TermbaseImportDialog, TBX tab accepts .tbx/.xml files via drag-drop or file picker. Parser is lenient: reads <termEntry>, <term>, and <termNote type='administrativeStatus'> elements. First langSet = source term, subsequent = target renderings. Status mapping: 'preferredTerm-admn-sts' → required, 'admittedTerm-admn-sts' → alternate, 'deprecatedTerm-admn-sts' → forbidden. Missing status defaults to 'preferred'. Imported concepts receive status 'active'.
Key files
src/components/TerminologyPage.tsx:373-496src/lib/terminology/tbx.ts:101-180
Export concepts to CSV ▶ 00:00
As a project lead, I want to export terminology as CSV for backup or editing in a spreadsheet, so that I can manage the termbase offline.
How it works. User clicks 'Export CSV' button (enabled when >= 1 concept exists). Browser downloads 'termbase.csv' file with header row and one row per rendering, columns: sourceTerm, rendering, status, notes (concept notes repeated on every row of that concept). CSV is RFC 4180 compliant (quoted fields with escaped quotes). Concepts with no renderings emit a placeholder row with empty rendering.
Key files
src/components/TerminologyPage.tsx:921-928src/lib/terminology/csv.ts:24-39
Export concepts to TBX ▶ 00:00
As a project lead, I want to export terminology as TBX for interoperability with other CAT tools, so that I can share the termbase.
How it works. User clicks 'Export TBX' button (enabled when >= 1 concept exists). Browser downloads 'termbase.tbx' file with TBX-Basic XML structure: <martif> root, <termEntry> per concept, langSets for source and target, <termNote type='administrativeStatus'> for status. Status mapping: required → preferredTerm-admn-sts, alternate → admittedTerm-admn-sts, forbidden → deprecatedTerm-admn-sts.
Key files
src/components/TerminologyPage.tsx:930-937src/lib/terminology/tbx.ts:68-100
Drill down to concept detail (term occurrences + enforcement verdicts) ▶ 00:00
As a translator, I want to click on a source term to see every cell occurrence of that term and whether each translation is enforced or infringed, so that I can review coverage.
How it works. User clicks the source term text (blue link) in a concepts row, a side panel opens (TerminologyTermDetail) overlaying the main page. The panel shows the source term as a header, rendering chips (managed), and a list of occurrences. Each occurrence row shows: cell reference (group/id), source snippet (truncated, left-aligned), verdict chip (green 'enforced', red 'infringed', or gray 'n/a'), and target text (plain or inline-editable if user has edit permission). Close button (X) dismisses the panel.
Key files
src/components/TerminologyPage.tsx:899-901src/components/TerminologyPage.tsx:1085-1100src/components/TerminologyTermDetail.tsx:1-250
Edit cell target inline from term detail ▶ 00:00
As a translator with edit permission, I want to edit the target translation directly from the term detail view, so that I can fix terminology violations without leaving the drill-down.
How it works. In TerminologyTermDetail, each occurrence row shows the target text. If the user has edit permission (contributor+), clicking the target text enters edit mode: a TranslatedEditor appears, accepting rich text input. Pressing Ctrl+Enter or clicking outside saves the change via emitTargetCellCommit(), emitting a target-edit event to the outbox. Verdict updates reflect the new translation.
Key files
src/components/TerminologyTermDetail.tsx:114-209src/components/TerminologyTermDetail.tsx:127-155
Close term detail panel ▶ 00:00
As a translator, I want to close the term detail panel and return to the concepts list, so that I can review other terms.
How it works. User clicks the X button at the top-right of the TerminologyTermDetail panel, or presses Escape. Panel dismisses, focus returns to main concepts view.
Key files
src/components/TerminologyTermDetail.tsx:13src/components/TerminologyPage.tsx:1093
Promote predicted equivalent to managed rendering ▶ 00:00
As a project lead in the term detail view, I want to promote an AI-predicted equivalent to an approved 'alternate' rendering, so that I can incorporate machine-suggested glosses into the managed vocabulary.
How it works. In TerminologyTermDetail, below the rendering chips, an EquivalentsPanel shows two sections: 'Managed (your decisions)' with existing renderings, and 'AI-assumed (predicted)' with probabilistic predictions (χ² + EM consensus, confidence bands, few-shot evidence). Each predicted row has an 'Promote' button (enabled if canManageTermbase=true). Clicking 'Promote' adds the predicted text as a new 'alternate' rendering, persists, and updates the managed section.
Key files
src/components/TerminologyTermDetail.tsx:246-247src/components/TerminologyPage.tsx:1001-1037src/components/EquivalentsPanel.tsx:139-150
Review queue — view draft concepts awaiting approval ▶ 00:00
As a project lead, I want to see all draft concepts in a review queue, so that I can approve or reject mined/promoted terms before they enter the controlled vocabulary.
How it works. User clicks the 'Review queue' tab. A TerminologyReviewQueue component renders with a collapsible header showing badge count and label (e.g., '3 concepts awaiting review'). Each queue row shows: source term, rendering chips with status labels, optional notes, and two action buttons (green checkmark 'Approve', red X 'Reject'). Approve sets status='active'; Reject deletes the concept. Read-only view for non-managers.
Key files
src/components/TerminologyReviewQueue.tsx:1-211src/components/TerminologyPage.tsx:801-804src/components/TerminologyPage.tsx:1239-1252
Approve draft concept (move to active) ▶ 00:00
As a project lead, I want to approve a draft concept from the review queue to move it into the active managed vocabulary, so that it starts enforcing.
How it works. User clicks the green checkmark button on a queue row. The concept's status changes from 'draft' to 'active', it is removed from the queue, and the active concepts count in stats/list increments. Approve button is disabled during the async save.
Key files
src/components/TerminologyReviewQueue.tsx:112-121src/lib/terminology/store.ts:177-179
Reject draft concept (delete from review queue) ▶ 00:00
As a project lead, I want to reject a draft concept from the review queue, so that I can discard unwanted promoted or mined terms.
How it works. User clicks the red X button on a queue row. A confirmation may appear (depends on FRO-291 implementation for review queue; currently direct delete). The concept is removed from the project entirely. The queue count decrements.
Key files
src/components/TerminologyReviewQueue.tsx:122-131src/lib/terminology/store.ts:187-194
Mine candidate terms from loaded corpus ▶ 00:00
As a project lead, I want to see candidate terms automatically mined from the loaded source and WIP cell texts, ranked by linguistic significance, so that I can discover key terms to manage.
How it works. User clicks the 'Candidate terms' tab. On first activation, a Web Worker off-thread runs the candidate-extraction pipeline (C-value nestedness, NC-value context weighting, G² keyness) over the project's loaded cells (source + translated text). Candidates are ranked by NC-value (default). A CandidateTermsPanel renders with a list of ranked candidates, each showing: term text, n-gram length badge, frequency count, NC/C/G² scores (with tooltips), and 'Promote to managed' button (disabled if already managed). Mining status shows 'Mining…' spinner while processing.
Key files
src/components/TerminologyPage.tsx:823-887src/lib/terminology/candidates.ts:1-150
Promote candidate term to draft concept ▶ 00:00
As a project lead, I want to promote a candidate term to a draft concept with one click, so that I can fast-track high-confidence discoveries into the review queue.
How it works. User clicks 'Promote to managed' on a candidate row. A draft Concept is created with sourceTerm=candidate.term, status='draft', empty renderings. The edit dialog immediately opens with the source term pre-filled. User adds renderings, notes, and optionally changes status, then saves. If a concept with that source term already exists, the promote is skipped silently.
Key files
src/components/TerminologyPage.tsx:969-997src/lib/terminology/candidates.ts:1-150
View terminology violations inbox (group by concept) ▶ 00:00
As a project lead, I want to see all terminology violations grouped by concept, so that I can identify which terms are most problematic in the project.
How it works. User clicks the 'Violations' tab. A TerminologyViolationsInbox renders, compiling active concepts to rules and scanning the project cells. Violations are grouped by concept: each concept row shows source term (bold), total violation count (badge), and sub-badges for 'missing approved' (amber) and 'forbidden present' (red). Each group is expandable, revealing individual violation rows: infraction type badge, cell reference (clickable), and cell preview text. Empty state: 'No terminology violations. Only approved concepts with renderings are enforced.'
Key files
src/components/TerminologyViolationsInbox.tsx:1-200src/lib/terminology/violations-inbox.ts:1-50
Expand violation group to see cell infractions ▶ 00:00
As a project lead, I want to expand a violation group to see the specific cells that infringe the term, so that I can navigate to and fix them.
How it works. User clicks a concept row in the violations inbox. The group expands, showing a list of infraction rows. Each row displays: infraction kind badge (amber 'missing' or red 'forbidden'), cell reference (clickable, styled as link), and cell preview (source or translated snippet). Clicking the cell reference navigates to the editor focused on that cell (if onJumpToCell callback is wired).
Key files
src/components/TerminologyViolationsInbox.tsx:122-200src/components/TerminologyPage.tsx:1231-1238
Merge duplicate concepts ▶ 00:00
As a project lead, I want to select 2+ duplicate concepts and merge them into a single survivor, so that I can deduplicate the termbase.
How it works. User clicks 'Merge duplicates' button (visible when >= 2 concepts). TerminologyMergeDialog opens with two steps: (1) SELECT: checkboxes for each concept with selection order badges (first selected = survivor). Instruction text explains the merge behavior. (2) PREVIEW: shows the survivor (keeps id), merged renderings (union, case-insensitive dedup, survivor wins on collision), combined notes (concatenated with |, deduplicated), and list of removed concepts (badges, destructive red). Back/Confirm buttons. Confirm merges and closes dialog.
Key files
src/components/TerminologyMergeDialog.tsx:1-351src/components/TerminologyPage.tsx:1217-1228src/components/TerminologyPage.tsx:1369-1374
Merge enforces minimum 2 concepts ▶ 00:00
As a user, I want the merge button to only enable when 2+ concepts are selected, so that invalid merges are prevented.
How it works. In the merge dialog select step, 'Preview merge' button is disabled until at least 2 concepts are checked. Hovering shows tooltip explaining the requirement.
Key files
src/components/TerminologyMergeDialog.tsx:257-264
Rendering status chips in concepts list ▶ 00:00
As a translator, I want to see rendering status visually in the concepts list (required/alternate/forbidden chips), so that I can quickly identify the approval levels without opening each concept.
How it works. In the concepts table, each rendering appears as an inline chip: emerald 'rendering·required' (preferred), gray 'rendering·alternate' (admitted), red strikethrough 'rendering·forbidden'. Chips are grouped per concept row and wrap across multiple lines.
Key files
src/components/TerminologyPage.tsx:78-94src/components/TerminologyPage.tsx:528-532
Terminology chip decoration in editor (visual indicator of managed terms) ▶ 00:12
As a translator editing a cell, I want to see small chip indicators on managed source terms in the editor, so that I can instantly recognize terminology that needs attention.
How it works. When editing a source cell with active concepts, each matched term (case-insensitive, wildcard-aware) is highlighted with a small colored dot chip (absolute positioned, top-right of the word, does not affect line height). Hovering shows tooltip 'Managed term: [sourceTerm]'. Only active concepts participate.
Key files
src/lib/richtext/terminology-chip-plugin.ts:1-134src/components/TerminologyPage.tsx:1
Pre-acceptance warning band for forbidden/missing renderings ▶ 00:00
As a translator using AI copilot, I want to see advisory warnings when an AI completion uses a forbidden term or misses an approved term before I accept it, so that I can catch terminology issues early without blocking my work.
How it works. After AI copilot returns a completion, PreAcceptanceWarningBand evaluates detectPreAcceptanceWarnings(completionText, sourceText, concepts). If warnings exist, a rounded amber band appears above/below the completion: 'Terminology advisory' header, then bullet list of warnings. Forbidden-present warnings (louder, alert icon, amber bold text): 'Forbidden rendering "[text]" used for [sourceTerm].' Preferred-absent warnings (quieter, info icon, amber regular text): 'No approved rendering of [sourceTerm] found in the completion.' Band is ADVISORY ONLY: it does not block accept/commit.
Key files
src/components/PreAcceptanceWarningBand.tsx:1-90src/lib/terminology/preacceptance.ts:34-91
Wildcard matching for inflectional terms (e.g., grace* matches grace/graced/gracia) ▶ 00:00
As a project lead, I want to define a source term with a trailing `*` wildcard to match inflected forms without manually listing each variant, so that I can cover grace, graced, gracia, etc. with one entry.
How it works. User enters 'grac*' in the source term field. The system treats `*` as standing for zero-or-more Unicode letters (\p{L}*). Matching is case-insensitive and word-boundary aware (leading/trailing boundaries apply unless `*` is present). Enforcement, chips, preacceptance warnings, and candidate exclusion all use the same matcher, so grac* consistently matches grace/graced/gracia/gracier/gracious.
Key files
src/lib/terminology/match.ts:1-85src/lib/terminology/candidates.ts:23-24
Role-based access control (Project Lead+ edits termbase, Contributor+ edits cells) ▶ 00:00
As an organization owner, I want to enforce that only Project Leads can add/edit/delete/import concepts and manage approvals, while Contributors can only inline-edit cells in the term detail view, and Viewers have read-only access, so that the termbase stays curated.
How it works. User role is checked against syncRole.level (or local defaults for no-origin projects). TERMBASE_EDIT_LEVEL = 500 (Project Lead+): Add, Edit, Delete, Import, Export, Approve/Reject, Merge buttons/dialogs enabled. canEditCells = 400+ or local: inline edit in term detail allowed. Below 400 or viewer: all terminated features disabled, tooltips show 'Requires Project Lead role or higher to manage term base definitions.'
Key files
src/components/TerminologyPage.tsx:694-725src/components/TerminologyPage.tsx:711-724