Journal

../../../_images/osp-journal-timeline.png ../../../_images/osp-journal-table.png

A journal is a chronological log attached to a record. Each entry records who wrote it, when, and it can carry file attachments. Journals are used to trace user interactions (for example an acknowledgement or a maintenance note on an alarm) and to let operators annotate a record over time.

The journal is a single capability exposed through three surfaces:

  • Inside an alarm table. The alarm table and alarm history table widgets show the journal of the selected alarm in a side panel. On a live table the journal is editable; on a history table it is read-only.

  • Inside a collection table. A JOURNAL render column adds a journal side panel to a collection table, where the entries are stored on the collection document itself. This is where the input form, table view and timeline formatter can be overridden — see Journal on a collection table.

  • As a standalone widget. The Journal dashboard widget detaches the journal panel from a table and renders it on its own, linked back to the table with viewAs — see Detached journal widget.

The same journal can also be embedded as a form component scoped to a journal array property.

Capabilities

Journal features

Capability

Support

Comment

Show the journal as a chat timeline

Supported feature

Default display mode. See Display modes.

Show the journal as a table

Supported feature

Rows expose the journal properties as columns. See Display modes.

Let users switch between timeline and table at runtime

Supported feature

Enabled unless disableTypeSwitch is set. See Display modes.

Format the timeline text with an expression

Supported feature

Use journalSettingsOverride.timelineTextFormatter. See Journal on a collection table.

Define the journal table columns and sort

Supported feature

Use journalSettingsOverride.tableView. See Journal on a collection table.

Show a per-row summary above the journal

Supported feature

Use summaryFormatterExpression. See Panel behaviour and summary.

Show the journal panel when several rows are selected

Supported feature

Use displayWithMultipleRows. See Panel behaviour and summary.

Display the author from a user-preference attribute

Supported feature

Use usernameAttribute. See Panel behaviour and summary.

Track who created or edited each entry (edit history)

Supported feature

The meta trail is filled automatically for collection and form journals. See Entry data model.

Add a free-text entry (GitHub Flavoured Markdown)

Supported feature

Type a message and submit with Ctrl+Enter. See Adding and editing entries and Alarm Table.

Let the user set the entry timestamp

Supported feature

Set inputMethod to TimestampMessage. See Adding and editing entries.

Restrict who can edit entries

Supported feature

editMode accepts all, self or none. See Adding and editing entries.

Conditionally allow adding or editing entries

Supported feature

Evaluate enabledAddEditEntryExpression. See Adding and editing entries.

Capture structured entries with a custom input form

Supported feature

Use journalSettingsOverride.form. See Custom input form and Customize the input and table of a form journal component.

Prefill form fields from live values

Supported feature

Uses the form bindings. See Custom input form.

Populate form fields from a collection (dropdowns / lookups)

Supported feature

Collection-backed fields fetch their options through the collections module. See Custom input form and Customize the input and table of a form journal component.

Add an entry to every selected row at once

Supported feature

Submit with Ctrl+Shift+Enter. See Alarm Table.

Force a journal entry from a menu action or script

Supported feature

Call alarms.addJournalEntry from a script. See Force journal entry on alarm menu actions.

Attach a journal to a collection-table row

Supported feature

Add a JOURNAL render column to the collection view. See Journal on a collection table and Customize the input and table of a form journal component.

Store journal entries inside the collection document

Supported feature

Entries are an array field written by document diffs. See Journal on a collection table and Collection table with row detailed view.

Expand a collection-table row to show its journal

Supported feature

Set tableRowDetail to the journal property. See Collection table with row detailed view.

Use journalSettingsOverride outside a collection table

Not supported feature

The override (form / tableView / timeline formatter) is only honoured for CollectionTable views. See Limitations.

Attach files to an entry by drag and drop

Supported feature

Requires uploadId. Drop files onto the journal. See Attachments and Use menus to upload file as attachments on alarms.

Attach files to an entry with a file picker

Supported feature

Requires uploadId. Use the paper-clip in the input row. See Attachments.

Restrict allowed file types and size

Supported feature

Configure authorizedContentTypes and maxSize in upload.ospp. See Attachments and Use menus to upload file as attachments on alarms.

Preview and download attachments (image, PDF, video, …)

Supported feature

Click a thumbnail to open the preview modal. See Attachments.

Show attachments on an alarm history table journal

Not supported feature

Attachments are dropped on the history path (the history entry carries no attachment list). See Limitations.

Limit the number of attachments per entry

Not supported feature

No per-entry count limit is enforced. See Limitations.

Automatically delete orphaned files when an entry or alarm is removed

Not supported feature

The entry only stores file identifiers; deleting it does not remove the stored files. See Limitations.

Detach the journal into its own dashboard widget

Supported feature

Use a Journal widget bound with viewAs. See Detached journal widget.

Bind the detached widget to a live alarm table (editable)

Supported feature

Point viewAs at an AlarmTable widget id. See Detached journal widget.

Bind the detached widget to an alarm history table

Partial support

Point viewAs at an AlarmHistoryTable; the journal becomes read-only. See Detached journal widget.

Validate that viewAs resolves to an existing widget

Not supported feature

The referenced widget id is not checked at configuration time. See Limitations.

Toggle table-mode toolbar buttons and column resize mode

Supported feature

Use the disableToolbar* flags and resizeMode. See the JournalWidget settings.

List of configuration files

Filename

Short description

Format

Link to documentation

dashboard.view#JournalWidget

Defines the standalone Journal widget (detached panel, viewAs, display type).

json

Link

view.web (JOURNAL render column)

Adds a journal side panel to an alarm or collection table, with input method, edit mode, attachments (uploadId) and collection overrides (journalSettingsOverride).

json

Link

upload.ospp

Declares the upload configuration referenced by uploadId (allowed file types, size, storage endpoint) used for attachments.

json

Link

List of examples

Short description

Link to documentation

Customize the input and table of a journal with a collection-backed form

Link

Store and expand a journal on a collection table row

Link

Force a journal entry from an alarm menu action

Link

Upload files as attachments on alarms

Link

Write to the journal during a maintenance workflow

Link

Display modes

A journal is rendered in one of two display modes, selected with the type setting:

  • Timeline (default): entries are shown as a chat-like conversation, newest activity in context, with the message text rendered as Markdown.

  • Table: entries are shown as rows, one column per journal property. In table mode the toolbar buttons (search, export, column chooser, filter, summary, clear) can be toggled with the disableToolbar* flags, and column resizing is controlled by resizeMode — see the JournalWidget settings.

Users can switch between the two modes at runtime unless disableTypeSwitch is set.

Adding and editing entries

By default an entry is a single Markdown message. The input behaviour is controlled per journal:

  • inputMethod: Message lets the user type only a message; TimestampMessage also lets the user choose the entry timestamp.

  • editMode: all lets a user edit any entry, self restricts editing to the user’s own entries, and none makes entries immutable once written.

  • enabledAddEditEntryExpression: an expression evaluated to decide, at runtime, whether the user may add or edit an entry (for example only while an alarm is active).

From an alarm table the entry is added to the current alarm with Ctrl+Enter, or to all selected alarms with Ctrl+Shift+Enter.

Linked examples

Entry data model

A journal entry is a JSON object. Some fields are written on every entry; the rest are optional:

Field

Type

Description

id

string

Unique identifier of the entry. Always written.

user

string

Author of the entry (or the name resolved from usernameAttribute). Always written.

timestamp

number

Creation time of the entry. Always written.

text

string

The entry message, in GitHub Flavoured Markdown. With a custom input form the form fields take the place of this single message.

attachments

string[]

Identifiers of the uploaded files. Optional — see Attachments.

status

string

Visual status of the entry: success, warning, error or info. Optional.

meta

object[]

Edit-history trail of the entry: one element per change, { user, timestamp, operation } where operation is create, edit or delete. Optional.

Note

meta is optional and is filled in automatically by the front-end when an entry is created or edited — you never write it yourself. It is only produced and displayed for journals on a collection table or in a form; alarm journals do not track it, and it is absent from the alarm JournalEntry on the back end.

When you add a JOURNAL render to a collection table, declare the journal as an array property in the collection schema.ospp following the shape above. Declaring meta (and id / user / timestamp) only matters if your schema is strict (additionalProperties: false); otherwise the automatically-written fields would be rejected on validation. With a permissive schema you may declare only the fields you actually display.

Custom input form

Instead of the default single-message box, a journal entry can be captured through a full form, letting you add structured fields (a category, a severity, a reference number …) to every entry. Set journalSettingsOverride.form to the id of a form configuration.

When a form is used:

  • the form schema and layout come from the referenced form configuration;

  • the form bindings prefill fields from the current live values;

  • form fields can be collection-backed — their dropdown options are read from a collection through the collections module (a read-only lookup; it does not store the entry);

  • on submit, the form’s field values become the properties of the stored journal entry.

Linked examples

Journal on a collection table

Adding a JOURNAL render column to a collection table view gives each row its own journal side panel. Unlike the alarm journal, the entries are stored on the collection document itself, as an array field that is mutated through document diffs (PUSH / PULL).

On collection-table views the journalSettingsOverride object lets you tailor the journal:

  • form: the form used to insert or update an entry (see Custom input form);

  • tableView: the columns and sort used by the Table display, so custom entry fields can be shown as columns;

  • timelineTextFormatter: an expression that formats the text shown for each entry in the Timeline display.

Note

journalSettingsOverride is only honoured for CollectionTable-related views. On an alarm table it is ignored — see Limitations.

Linked examples

Attachments

A journal entry can carry file attachments. Attachments are enabled by setting uploadId on the JOURNAL render column to the id of an upload configuration.

The upload.ospp configuration declares:

  • authorizedContentTypes (required): the MIME types accepted (for example image/png, application/pdf);

  • maxSize: the maximum size per file in bytes (defaults to 5 MB);

  • storageConfiguration: the host and port of the storage service (defaults to osp-storage:8443).

Once uploadId is set, the user can add files by drag and drop onto the journal or through the file picker (the paper-clip in the input row). Each file is uploaded, validated against the allowed types and size, and stored by the storage service; the entry keeps only the resulting file identifiers. Attachments are shown as thumbnails and can be opened in a preview modal (image, PDF, video, …) or downloaded. Access to an attachment is governed by the read/write rights on the uploadId item, and the content type is re-checked on download.

Linked examples

Panel behaviour and summary

  • summaryFormatterExpression: an expression evaluated to render a summary line above the journal side panel (for example a count or a status).

  • displayWithMultipleRows: whether to keep showing the journal side panel when several rows are selected or shown at once.

  • usernameAttribute: the user-preference attribute used to display the author’s name instead of the raw user id.

Detached journal widget

The standalone Journal dashboard widget renders a journal panel on its own, instead of inside a table’s side panel. It is bound to a table with the required viewAs setting, which holds the widget id of the alarm table it mirrors:

  • the widget subscribes to the same data as the referenced table;

  • if viewAs points at an AlarmTable, the journal is editable;

  • if it points at an AlarmHistoryTable, the journal is read-only (entries cannot be added).

The widget’s own type (Timeline / Table) and its table-mode toolbar flags are described in the JournalWidget settings.

Limitations

  • journalSettingsOverride (custom form, tableView and timelineTextFormatter) is only applied on CollectionTable-related views; it is ignored elsewhere.

  • Journals shown from an alarm history table are read-only, and their attachments are not delivered — the history entry carries no attachment list.

  • There is no limit on the number of attachments per entry, and no size limit across an entry (only a per-file maxSize).

  • Removing a journal entry (or its alarm) does not delete the stored attachment files; the entry holds only file identifiers, so orphaned files are not cleaned up automatically.

  • The viewAs target of a detached widget is not validated at configuration time; a wrong or missing widget id fails silently at runtime.