450 lines
26 KiB
Markdown
450 lines
26 KiB
Markdown
# GovOPlaN Interface Pattern Language
|
|
|
|
This document is the cross-repository pattern language for GovOPlaN user
|
|
interfaces. It turns the existing ethical doctrine, binding UI/UX decisions,
|
|
layout principles, and module boundary into a common composition and review
|
|
grammar. It does not replace those sources.
|
|
|
|
The companion [interface surface inventory](INTERFACE_SURFACE_INVENTORY.md)
|
|
records which surfaces the current code contributes and where each surface
|
|
enters the rollout.
|
|
|
|
## Source Of Truth And Precedence
|
|
|
|
Use the narrowest owning document when changing a rule:
|
|
|
|
1. `govoplan-core/docs/INTERFACE_ETHICS_AND_DESIGN_DOCTRINE.md` owns why a
|
|
consequential interface must preserve context, decision, consequence,
|
|
responsibility, contestability, and traceability.
|
|
2. `govoplan-core/docs/UI_UX_DECISION_LEDGER.md` owns accepted product decisions
|
|
such as progressive disclosure, adaptive forms, blocker language, guided
|
|
operations, and the platform theme contract.
|
|
3. `docs/FRONTEND_LAYOUT_PRINCIPLES.md` owns the high-level choice between a
|
|
full-space structured-data workspace and a heading/menu/card workflow or
|
|
configuration surface.
|
|
4. `govoplan-core/docs/MODULE_ARCHITECTURE.md` owns the shell, route, navigation,
|
|
UI-capability, and shared-component boundaries.
|
|
5. This document owns the common pattern names, placement grammar, wording and
|
|
state conventions, focused-view composition, and definition of done across
|
|
those sources.
|
|
|
|
If two rules appear to conflict, do not create a third local convention. Record
|
|
the conflict in the owning decision ledger, resolve it there, and update the
|
|
affected patterns and surfaces together.
|
|
|
|
## Product Contract
|
|
|
|
GovOPlaN should feel calm because it shows what is relevant to the task, not
|
|
because it hides authority, risk, or evidence. Every surface follows these
|
|
rules:
|
|
|
|
- Start with the user's current object and task.
|
|
- Show common actions before advanced controls.
|
|
- Keep context, status, problems, and the next action spatially connected.
|
|
- Make consequential effects explicit before execution and observed effects
|
|
inspectable afterwards.
|
|
- Treat permissions, policy, privacy, and module availability as behavior, not
|
|
decoration.
|
|
- Keep optional modules optional. Compose through core route and UI-capability
|
|
contracts, never sibling-private components.
|
|
- Use the centrally exported core components wherever a matching contract
|
|
exists. A module-local replacement is not an implementation choice: it is a
|
|
product exception that requires explicit product-owner authorization.
|
|
- Preserve a stable way back to the containing object and the broader system.
|
|
- Do not let navigation, selection, or a view switch imply consent.
|
|
|
|
## Surface Archetypes
|
|
|
|
Choose an archetype from the task, then specialize it for the domain. A route
|
|
may contain more than one bounded archetype, but it should have one dominant
|
|
one.
|
|
|
|
| Archetype | Use when | Standard anatomy | Do not use when |
|
|
| --- | --- | --- | --- |
|
|
| Directory or explorer | Users browse hierarchical collections such as files, mailboxes, calendars, addresses, or records. | Collection/source pane, collection actions, filter in the pane it affects, main list/content pane, optional detail pane. | The content is a set of unrelated settings or workflow stages. |
|
|
| List-detail workspace | Users repeatedly find objects, inspect one, and act without losing list context. | Search/filter/list, persistent selected-object context, detail/actions, stable selection and URL. | A single guided operation is the primary task. |
|
|
| Focused task view | Only a bounded composition is needed to complete one task. | Task identity and reason, selected object, necessary module regions/actions, progress or status, obvious exit to the full system. | Hiding a surface would obscure a consequence, blocker, or required evidence. |
|
|
| Create or edit | Users change one coherent object state. | Adaptive typed form, field-level validation, advanced section, save/cancel, unsaved-change guard. | Discovery-heavy setup or a broad consequential change needs staged review. |
|
|
| Guided setup or import | The user must discover, upload, map, test, or preflight before a safe result exists. | Named steps, current progress, preserved inputs, validation/problem list, review, resumable completion where work is durable. | An ordinary edit can be understood as one coherent form. |
|
|
| Review or decision | A person must inspect evidence and deliberately approve, reject, send, publish, or otherwise commit. | Decision context, evidence/problems, consequence and reversibility, authority/provenance, explicit action, resulting record. | The interaction is passive inspection. |
|
|
| Monitoring, progress, or report | Users observe asynchronous or aggregate state and intervene when needed. | Summary, filters, durable job/item state, last update, retry/reconcile/intervention, detail and evidence. | A toast is sufficient for a short, non-durable local action. |
|
|
| Administration or configuration | Users compare and configure separate concerns. | Heading and scope, grouped subnavigation, overview/list plus selected details, adaptive editor or guided risky operation, effective policy and source. | The primary task is browsing one structured object space. |
|
|
| Dashboard | Users need a task-oriented starting point across modules. | Prioritized actionable widgets, scoped status, clear destination per widget, explicit refresh/staleness. | It merely duplicates every module navigation item or metric. |
|
|
| Public service or entry | An unauthenticated or external participant starts or resumes a service. | Service identity, eligibility/context, privacy and evidence expectations, accessible form/task, save/resume or handoff. | The actor is performing internal administration. |
|
|
|
|
## Placement Grammar
|
|
|
|
### Shell And Navigation
|
|
|
|
- The global title bar and rail belong to core. A module contributes routes,
|
|
navigation metadata, and explicit UI capabilities; it does not reproduce the
|
|
shell.
|
|
- Global navigation answers "which service area?" Local subnavigation answers
|
|
"which stable facet of this object or area?" A progress indicator answers
|
|
"where am I in this operation?" Do not use those three controls
|
|
interchangeably.
|
|
- Keep the current tenant, actor, object, and selected version or scope stable
|
|
across local navigation. Guard unsaved work before navigation.
|
|
- Permission and capability filtering happens before view composition. A
|
|
missing menu item is not evidence that an actor lacks backend access, and a
|
|
visible item is never authorization by itself.
|
|
- Route, selection, panel, and view changes must not execute consequential
|
|
actions.
|
|
|
|
### Page And Workspace
|
|
|
|
- Structured directories use the full available content space and persistent
|
|
panes. They do not add a decorative heading row that reduces working height.
|
|
- Workflow, configuration, dashboard, and explanatory pages may use a heading.
|
|
The heading names the task or scoped object and contains only route-level
|
|
actions.
|
|
- Put a collection-wide create action in the heading of the collection it
|
|
affects. Use a short, specific label such as `Add` when the heading already
|
|
names the object. Do not duplicate that action in a permanently visible side
|
|
panel. A side panel used as the creation surface appears for creation and is
|
|
otherwise absent or returns to its documented non-creation purpose.
|
|
- Put filters beside the list or pane they affect. Put bulk actions immediately
|
|
above or beside the current selection. Put object actions with the object
|
|
detail, not in the global title bar.
|
|
- Full-page create and edit surfaces put their persistent action cluster in the
|
|
upper-right of the page heading. `Discard` comes before `Save …`, with the
|
|
primary save action at the far right. Keep both controls in the same place
|
|
across validation, loading, and saved states; guard unsaved work when the
|
|
user discards or navigates away.
|
|
- A page or panel has one visually primary action for its current state. Put
|
|
secondary actions beside it. Separate destructive actions and name their real
|
|
effect.
|
|
- Dialog actions use a stable footer: cancel/back first, then the primary action
|
|
at the end. Header and footer stay fixed while long bodies scroll.
|
|
- Use cards for independent groups, summaries, and settings blocks. Do not wrap
|
|
every region in a card or nest cards merely to create spacing.
|
|
- When a collapsible card contains one table and no other content, the table
|
|
uses the card's full available width and body height. The card/table region
|
|
owns overflow; do not add an inner max-width, decorative wrapper, duplicate
|
|
padding, or nested scroll container that reduces the working area.
|
|
- Row actions in tables are icon-only controls in a stable rightmost action
|
|
column. Order them by intent: inspect/open, edit, copy/duplicate,
|
|
transfer/share/download, retry/restore, then remove/delete last. Omit actions
|
|
that do not apply without closing the gap or changing the relative order.
|
|
Every icon has a translated accessible name and matching tooltip. Separate
|
|
destructive actions visually, and use a named confirmation/review surface
|
|
when the consequence cannot be understood from the icon and row context.
|
|
- Transient feedback should not shift the workspace. Durable failures, partial
|
|
results, and blockers remain attached to the affected item or operation.
|
|
|
|
### Detail And Explanation
|
|
|
|
- Keep the selected object's identity and material status visible while its
|
|
detail changes.
|
|
- Short field help sits with the label. Longer "Why?", policy source,
|
|
diagnostics, or provenance belongs in an expandable area, detail panel, or
|
|
review step.
|
|
- Empty space is not an error. An empty state states what is empty, why that can
|
|
happen, and the permitted next action. Do not show creation actions to actors
|
|
who cannot create.
|
|
|
|
## Visual Grammar
|
|
|
|
- Core owns the appearance contract and shared CSS tokens. Modules use core
|
|
colors, spacing, radii, shadows, focus treatment, status colors, and disabled
|
|
treatment; module CSS may specialize layout only.
|
|
- Establish hierarchy through spacing, typography, grouping, and placement
|
|
before adding borders or color.
|
|
- Color never carries status or required action alone. Pair it with text and,
|
|
where useful, an icon.
|
|
- Icons support recognition but do not replace accessible names. Use the core
|
|
icon-name mapping for navigation.
|
|
- Keep list columns, tree indentation, headers, dialog dimensions, and action
|
|
positions stable as content changes.
|
|
- Density is a user preference, not a license to remove labels, focus targets,
|
|
explanations, or consequences.
|
|
- Respect system/light/dark themes and reduced-motion preferences through the
|
|
core contract. Do not build module-local theme systems.
|
|
|
|
## Wording Grammar
|
|
|
|
Use the same noun for the same domain object in navigation, headings, fields,
|
|
actions, states, API-facing explanations, and documentation. Prefer the most
|
|
specific user-facing noun: "Recipients" rather than "Data", "Delivery job"
|
|
rather than "Process", and "Mail profile" rather than "Configuration" when
|
|
that is what the user is acting on.
|
|
|
|
Actions use a verb plus the object or consequence:
|
|
|
|
- Prefer `Save campaign`, `Review messages`, `Queue delivery`, `Retry failed
|
|
deliveries`, or `Delete calendar`.
|
|
- Avoid `Submit`, `OK`, `Continue`, or `Execute` when a more precise action is
|
|
available.
|
|
- Use `Continue` only when it advances a reversible guided flow without
|
|
committing the final effect.
|
|
- Do not say `Undo` when the system can only cancel future work, create a
|
|
correction, supersede a record, or request retraction.
|
|
|
|
State text describes observed state, not optimism. Use stable shared terms where
|
|
they fit: `Draft`, `Ready for review`, `Blocked`, `Queued`, `Running`,
|
|
`Retry scheduled`, `Partially completed`, `Completed`, `Failed`, and
|
|
`Cancelled`. Domain-specific states may refine these terms but should not give a
|
|
shared term a contradictory meaning.
|
|
|
|
Blocked and failed actions use the structured language from DUE-005:
|
|
|
|
- what is unavailable or failed
|
|
- why, in plain language
|
|
- what must happen next
|
|
- who can do it
|
|
- where to go
|
|
- optional technical details behind deliberate disclosure
|
|
|
|
Errors should identify the affected object and whether saved state or external
|
|
effects may already exist. Never expose raw exception text as the only user
|
|
message.
|
|
|
|
## State Contract
|
|
|
|
Every surface implements the states it can reach; it does not render a blank
|
|
region while waiting or collapse distinct outcomes into a generic error.
|
|
|
|
| State | Required treatment |
|
|
| --- | --- |
|
|
| Loading | Keep the stable shell and context visible. Name what is loading; preserve usable prior data when safe. |
|
|
| Empty | State the scope and reason, then show only permitted next actions. |
|
|
| Validation problem | Attach the problem to the field/item and provide a navigable summary when problems span regions or steps. |
|
|
| Permission denied | Name the unavailable action or object, the required actor/role where safe, and a valid exit. Do not leak protected data. |
|
|
| Capability unavailable | Distinguish not installed, disabled, not configured, unhealthy, and not permitted when the actor may know. Give the responsible actor and target. |
|
|
| Offline or unreachable | Preserve local context and unsaved input, show last-known/stale state, and offer a safe retry. Do not present network absence as an authentication failure. |
|
|
| Stale or conflicting | Show which data changed, preserve both values where feasible, and offer reload, merge, or explicit overwrite according to policy. |
|
|
| Partial result | Show completed and incomplete effects separately. Never label a partial operation successful without qualification. |
|
|
| Asynchronous work | Show durable job identity, queued/running/retry/block/final state, last update, progress if meaningful, and leave/return behavior. |
|
|
| Success | State the resulting object/effect and provide its evidence or destination. Use a transient toast only when the result is already visible and durable elsewhere. |
|
|
| Destructive or corrective action | Preview scope, downstream effects, reversibility limit, evidence, and required confirmation or approval. |
|
|
|
|
Long-running or external work must expose retry and reconciliation as observable
|
|
states. The UI must not imply that a request and its external effect were one
|
|
atomic success when an outbox, worker, or remote system sits between them.
|
|
|
|
## Consequence And Provenance
|
|
|
|
Before an action affects records, rights, policy, retention, communications,
|
|
money, external systems, or workflow state, its action surface must answer the
|
|
decision-surface questions in the interface doctrine. At minimum show:
|
|
|
|
- affected object and scope
|
|
- acting identity or system actor and relevant authority
|
|
- immediate and possible downstream effects
|
|
- whether the operation is reversible, cancellable, corrective, or final
|
|
- blockers and their resolution path
|
|
- audit/evidence that will be created
|
|
- effective policy or configuration source when it changes the decision
|
|
|
|
After execution, users must be able to reach the command/job, observed effects,
|
|
policy result, failures, retries, reconciliation outcome, actor, time, and source
|
|
data that explain the result. Provenance may be quiet by default, but it must not
|
|
be absent.
|
|
|
|
Privacy follows the same rule: lists, previews, logs, notifications, and
|
|
diagnostics show only the personal or secret data needed for the actor's task.
|
|
Redaction must be explicit enough that users do not mistake a redacted value for
|
|
missing source data.
|
|
|
|
## Focused Views
|
|
|
|
A focused view is a declarative UI composition for a task. It selects the
|
|
routes, local regions, navigation entries, and actions relevant to that task
|
|
after installed-module, capability, permission, and policy filtering. It does
|
|
not change backend authorization or domain state.
|
|
|
|
A view definition must be able to explain:
|
|
|
|
- its stable identifier, label, and task purpose
|
|
- the current object/scope and default destination
|
|
- included navigation and contributed regions/actions, with deterministic order
|
|
- the visible escape to the containing module and full system
|
|
- why the view is active and how the user may switch when switching is allowed
|
|
- what happens to unsaved work when entering, leaving, or switching views
|
|
|
|
Focused views follow these invariants:
|
|
|
|
- Do not hide a blocker, material consequence, provenance, or required review
|
|
merely to make the screen quieter.
|
|
- Preserve the global tenant/actor context and provide an obvious exit.
|
|
- Filter unavailable contributions without leaving broken separators, empty
|
|
groups, or dead destinations.
|
|
- A manual or automatic switch is navigation, not consent. Guard unsaved work
|
|
and never execute a domain action as a side effect.
|
|
- Display why a non-manual default was selected, for example a role or task
|
|
default, without exposing protected policy details.
|
|
- Treat an unknown or invalid view as a recoverable fallback to the normal
|
|
module surface.
|
|
|
|
When more than one source proposes a focused view, use this precedence:
|
|
|
|
1. a manual view pinned for the current user session
|
|
2. a current-task suggestion, including a future workflow-step suggestion
|
|
3. the user's saved default
|
|
4. the role or tenant default
|
|
5. the normal full interface
|
|
|
|
Show the active source and an escape to the full interface. A task or workflow
|
|
suggestion is never an authorization change and never locks the user into the
|
|
composition; tenant policy may constrain which views are selectable, but it
|
|
must not hide required evidence or remove that escape. Workflow implementation
|
|
is explicitly postponed and is not a prerequisite for defining, manually
|
|
selecting, testing, or piloting focused views. A future workflow module may
|
|
request a view through a core contract; it must not own the view composition
|
|
implementation.
|
|
|
|
## Accessibility And Responsive Contract
|
|
|
|
- Every action is reachable and operable by keyboard in a logical order.
|
|
- Use semantic headings, landmarks, labels, tables/lists, and native controls
|
|
before adding ARIA. Icon-only controls need stable accessible names.
|
|
- Focus is visible. Dialogs trap focus, announce their name, and return focus to
|
|
the control that opened them. Validation moves or links focus to the first
|
|
relevant problem without losing the problem summary.
|
|
- Loading, saved, failed, queued, progress, and externally updated states are
|
|
announced without repeatedly interrupting the user.
|
|
- Disabled primary actions need a focusable explanation; a pointer-only tooltip
|
|
is insufficient.
|
|
- Do not rely on color, hover, drag-and-drop, pointer precision, or animation as
|
|
the only interaction. Provide keyboard and explicit-control equivalents.
|
|
- At narrow widths and high zoom, preserve task order and action access. Collapse
|
|
secondary panes into an explicit drawer/step and never move a destructive
|
|
action into the primary position.
|
|
- Honor reduced motion. Avoid motion that implies progress when the operation is
|
|
merely waiting.
|
|
- Truncation has an accessible full-value path. Personal or secret values remain
|
|
redacted according to permission and policy in that path.
|
|
|
|
## Component Ownership
|
|
|
|
Core already exports shell, navigation, access-boundary, form, dialog, loading,
|
|
status, policy/provenance, blocker, review, table, tree, message-display, and
|
|
unsaved-change primitives. These centrally exported components are mandatory
|
|
across GovOPlaN wherever their contract covers the interaction. In particular,
|
|
use the core `Card` for logical sections, `DataGrid` for tabular collections and
|
|
row actions, and `ToggleSwitch` (the standard Toggle control) for boolean
|
|
settings. Styling a native element or a module-local component to imitate one
|
|
of these controls is duplication, not reuse.
|
|
|
|
A route or domain composition assembled from central primitives is not a custom
|
|
control. Any new reusable UI control, presentation primitive, or module-local
|
|
substitute is a custom component and requires explicit product-owner
|
|
authorization before implementation. Record the authorization in the owning
|
|
decision or issue together with:
|
|
|
|
- the narrowly defined purpose and consumers
|
|
- why no central component or composition satisfies the need
|
|
- the exact scope in which the exception may be used
|
|
- its accessibility, state, theme, and test contract
|
|
- whether it should remain domain-specific or later become a core component
|
|
|
|
An authorized custom component serves only that specific purpose. It must not
|
|
duplicate, fork, restyle into a substitute for, or silently broaden beyond a
|
|
central component. Code review convenience, an existing local implementation,
|
|
or a small visual difference is not authorization. When core gains the required
|
|
contract, migrate the exception unless the product owner explicitly retains it.
|
|
|
|
Do not promote a component only because two screens look similar. Promote it to
|
|
`@govoplan/core-webui` after a second consumer or a clear platform contract has
|
|
proved shared behavior, accessibility, state, and extension needs. Modules own
|
|
domain composition, wording, and policy semantics; core owns generic contracts
|
|
and appearance.
|
|
|
|
### Scheduling Request Composition Reference
|
|
|
|
The Scheduling request surface is the first explicit reference composition for
|
|
these rules:
|
|
|
|
- The `Scheduling requests` page heading owns one `Add` action.
|
|
- The left panel is shown for the creation view; it is not a second permanent
|
|
creation launcher beside the request list.
|
|
- `Basic information`, `Calendar integration`, `Candidate slots`, and
|
|
`Participants` are logical sections rendered with the central `Card`.
|
|
- Candidate slots and participants are row collections rendered with the
|
|
central `DataGrid`, including its stable action column.
|
|
- Calendar integration is a boolean choice rendered with the central
|
|
`ToggleSwitch`; dependent calendar controls are disclosed only when enabled.
|
|
- Each participant is one structured row containing name, email address, and
|
|
ordered row actions. An address-parsing text area is not the ordinary editor;
|
|
parsing pasted address lists belongs only in an explicitly designed bulk
|
|
import flow.
|
|
|
|
Apply the underlying placement and component rules to equivalent collection and
|
|
create/edit surfaces throughout the system; the Scheduling domain names are an
|
|
example, not a module-local convention.
|
|
|
|
## Test Expectations
|
|
|
|
For every changed surface, select tests from each applicable layer:
|
|
|
|
- route and permission tests: module enabled/disabled permutations, route guard,
|
|
contribution filtering, fallback, and direct-link behavior
|
|
- behavior tests: primary task, validation, unsaved-change guard, confirmation,
|
|
retry/reconcile, partial result, and leave/return behavior
|
|
- accessibility tests: semantic names/roles, keyboard order, focus entry/return,
|
|
live-state announcements, and non-color status meaning
|
|
- state tests: loading, empty, denied, capability-missing, stale/conflict,
|
|
offline, partial, success, and destructive/corrective outcomes as applicable
|
|
- composition tests: absent optional module, duplicate/unknown contribution,
|
|
deterministic ordering, and focused-view fallback
|
|
- presentation checks: supported widths/zoom, light/dark/system theme, reduced
|
|
motion, comfortable/compact density, and long translated text
|
|
- i18n checks: user-facing strings owned by the rendering package and structural
|
|
audits passing
|
|
- visual regression: useful for geometry and hierarchy after behavior and
|
|
accessibility assertions exist; never the only evidence
|
|
|
|
If the current harness cannot automate a required check, record the gap and the
|
|
manual evidence in the owning issue. "Not tested" is an inventory state, not a
|
|
reason to infer that a pattern is satisfied.
|
|
|
|
## Definition Of Done For A Surface
|
|
|
|
- The dominant task and archetype are recorded in the inventory.
|
|
- Placement, action hierarchy, wording, and every reachable state follow this
|
|
pattern language or an explicit ledger exception.
|
|
- Permission, capability, privacy, and redaction behavior are verified.
|
|
- Consequence, reversibility, authority, evidence, and provenance are present
|
|
where applicable.
|
|
- Keyboard, focus, announcement, responsive, theme, density, motion, and i18n
|
|
behavior are covered in proportion to the surface.
|
|
- Optional modules remain optional and no sibling-private UI import was added.
|
|
- Every matching central component is reused. Any custom-component exception
|
|
has recorded product-owner authorization, narrow scope, rationale, and tests,
|
|
and does not duplicate a central component.
|
|
- Behavioral/accessibility evidence is linked from the rollout matrix and issue.
|
|
- Configured-system help can reach the applicable pattern or reference topic
|
|
when [Docs #15](https://git.add-ideas.de/add-ideas/govoplan-docs/issues/15)
|
|
supplies that experience.
|
|
|
|
## First Pilot: Campaign
|
|
|
|
[Campaign #74](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/74)
|
|
is the first full-domain audit and migration. It should prove patterns before
|
|
generic extraction:
|
|
|
|
- [#59](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/59) and
|
|
[#73](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/73): stable,
|
|
accessible preview and attachment-detail overlays
|
|
- [#63](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/63): review
|
|
stages, outcomes, blockers, and intervention vocabulary
|
|
- [#62](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/62): explicit
|
|
synchronous/asynchronous send mode and durable delivery progress
|
|
- [#65](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/65): one
|
|
coherent report filtering and count-affordance model
|
|
- [#35](https://git.add-ideas.de/add-ideas/govoplan-campaign/issues/35): guided
|
|
first-campaign entry
|
|
|
|
These slices do not depend on the Workflow runtime. Campaign's current
|
|
domain-owned review/send state is enough to prove layout, wording, focused-view,
|
|
progress, intervention, and evidence patterns.
|
|
|
|
## Revision Procedure
|
|
|
|
1. Record a changed product decision in the core UI/UX decision ledger.
|
|
2. Update the relevant pattern here without copying the full owning doctrine.
|
|
3. Update the surface inventory and rollout owner/issues.
|
|
4. Change shared components only where the proven contract belongs to core.
|
|
5. Migrate and test affected module surfaces.
|
|
6. Publish configured-system pattern/reference help through the Docs module.
|