Skip to main content

Sources

Docs: Panes, Perceptions, Policies, Plots, and Workspace Pool. Web App: A Pane’s own controls save a setting when you choose to keep it, such as a date range or a pivot, and show it again when the Page reloads.

Structure

A Preference is a setting: a value that a person saved for one Pane, for themselves, shared for the whole Parable, or shared for one group. A chosen date range, a pivot layout, a selected team, and a theme choice are settings. The value has the type of the Pane’s Perception preferences field, and the Pane’s code names each setting with a handle, such as dateRange. A Plot that reads a Pane by name reads its setting under the handle preferences (Plots). A Perception that does not declare preferences types its settings by its primitive, as every Perception did before preferences existed. Every setting has one scope, and the product names it the same way wherever a scope is shown or chosen: A shared setting is held per Parable: each Workspace’s copy of a Parable has its own shared settings, so the scope reads This Parable, not Workspace. A group is any group of people the Parable’s own data describes, at any level of its hierarchy: in Team Time Spend, a Division, a Department or a Team. The levels and their names come from the Parable’s content, so a Workspace whose organization has other levels gets those, and nothing in the platform depends on a level. A group setting names its group by the ID a Plot of the Parable gives it, such as a category’s ID, in the canonical form the API returns; Parable keeps no list of groups, so a Pane offers the groups its own Plot reads. When the scope is chosen, show one section per level, named as the Parable names it, listing that level’s groups. A Workspace’s Parable holds at most one setting for each Pane, handle, and scope, and one for each group. This Parable, each group and a person can each hold a setting under the same handle. Parable does not fall back from one scope to another; the Pane’s code decides which to show. Most Panes let the most specific win: a person’s own setting, else the deepest group they belong to, then each level above it, else This Parable’s. A Pane that offers several, such as Hide for Me and Hide for This Parable, labels each choice with its scope. Preferences hold settings: the values that fill a Parable’s Pieces when it runs. The app itself — its Pages, Panes, Perceptions, Policies, Palettes, and Plots — is versioned with the Parable and changes only through the authoring save or a published Version. The app’s defaults belong in the Pane’s code and Perception. A setting never changes the app’s React, CSS, or the text of its Policies, though a Policy can read one (Security). The one setting that holds code is a Plot’s SQL, below, and it changes only through a Version.

Live or Versioned

Each Page’s or Pane’s settings are Live or Versioned, and its Perception says which by wrapping preferences in Live<T> or Versioned<T> from parable/foundation:
The mode covers every handle of the Page or Pane. A Perception that wraps preferences in neither is Live, as every setting was before modes existed; say so with Live<T> when a Policy reads the setting (Security). Because the declaration is part of the Perception, choosing a mode is itself a change to the Parable: it saves into your Changes like any edit, or straight to the Parable when it is Personal. The Preferences tab beside Policies lists each setting with its scope, its mode, its value and who set it, and its How changes apply switch edits the declaration for you. It lists the settings of the selected Page or Pane and of every Pane it declares, at any depth, each under its Pane, as the Policies tab walks them; the switch then names whose mode it sets, as How Toolbar’s settings change, since it sets the selected Page’s or Pane’s mode alone and each listed Pane shows its own. A Pane whose Perception declares preferences and holds no saved setting shows Default: its code’s default applies. A Page holds no settings of its own, so a Page’s tab offers no mode and lists its Panes’ settings. A Perception that declares preferences: null keeps no settings, so its tab offers no mode either, says so, and lists the settings of the Panes it declares. When nothing the tab lists can keep a setting, it says No settings rather than waiting for one. A Versioned setting belongs to the Parable, so it has only shared scopes: This Parable and a group. A save for Me on a Versioned Pane is refused (PA-AU-040). Plot SQL saved as a setting. A Pane whose Perception declares readonly preferences: Versioned<PlotSql> keeps its Plot’s SQL as its setting, under the Plot’s handle. A save of it is the Plot’s new SQL in a new Version, so the Plot gate checks it, and each Version keeps the SQL it was published with. Such a Pane has no other settings, and its Plot may not be named preferences. Plot SQL is always Versioned: Live<PlotSql> does not compile. Saving it needs edit.plots as well as edit.preferences, as editing the Plot does, and reading it needs view.plots.

Services

Pane code saves and reads its own settings through the preferences.values binding of its generated module. The binding belongs to the calling Pane; it cannot read or write another Pane’s settings. Rendering and reading never create a setting. A setting saved before its Pane’s Perception changed can stop fitting the Pane’s type, for example when a field it lacks became required. A read leaves that setting out: list returns the Pane’s other settings, and get returns null, so the Pane shows its defaults in its place. The Parable’s window says A saved setting no longer fits and the Pane’s name once, with whose setting it was. The setting stays stored, and delete still removes it. While it is stored, a save of the same handle as a new setting (expectedRevision: 0) is refused as a revision conflict. The Workspace API has five operations, and Ponder can use each as a tool: A save names the Pane, the handle, whether the setting is shared, the group for a group setting, an optional name and icon, the value, and expectedRevision. A group setting is shared, so it sets shared and names the group in group:
expectedRevision: 0 creates the setting and is refused if one already exists. Any other number replaces the value that revision read. The save returns the setting’s ID and new revision, not the value, and its outcome. A save or delete of a Versioned setting also takes release, minor (the default) or major, and an optional message that describes the change. Who makes the change decides what happens: A Live setting’s outcome is live, and it ignores release and message. In Pane code, preferences.mode reads live or versioned and preferences.plotSql reads whether the settings are Plot SQL; both come from the Perception and cannot be changed from code:
A Versioned save answers once the Version is published or the Changes are proposed. The server gives a save 60 seconds, and the web app waits for its answer, so the Pane waits up to 65 seconds. When the save answers, the Parable’s window says what happened, outside the Pane: Published v1.84 (minor) with what changed and a link to it, or Saved to your Changes with a link to them. A save that takes longer than the web app waits is still running on the server, not failed: a save that passed its checks finishes after its request ends. The save rejects with the code PREFERENCE_WRITE_PENDING, and the window says Still saving your change with Refresh. When the Version is published, the window says Updated to v1.84. Everyone else with the Parable open hears of the new Version at once: a reader on the newest reading sees Updated to v1.84, and a reader of an older Version sees v1.84 is available with a link to it. IDs are Identity UUIDs in the canonical base62 form the API returns. Pass the IDs that reads and saves return rather than a hyphenated UUID.

Storage

A Live setting takes effect at once and keeps its history. It is not part of a Version: publishing does not copy, reset, or roll it back, and reading an older Version reads today’s value under today’s Policies. A Versioned setting’s values are part of its Page or Pane, so each Version and each set of Changes holds its own. The API reads the values of the definition you are viewing: List and Read take refId or versionId, as Save does. When a Version is published, its Versioned values become the settings SQL and Policies read, so workspace.preferences, a Policy’s fromSetting and a Report run read the current Version’s values. A Version published before a Pane’s settings became Versioned reads their live value. The server checks every value against the Pane’s preferences (else its primitive) when it is saved. A value that does not match is refused (PA-AU-040). Selecting a saved value to render a Pane checks it against that definition’s setting type too. Changing that type does not rewrite existing settings; an incompatible selection is refused until its saved value is updated. A Plot reads settings with plain SQL through workspace.preferences. It returns the settings the person running the query can read for the selected Workspace and Parable: their own (Me), and the ones shared for This Parable or a group whose Pane’s view.preferences Policy allows them, as the settings API decides.
The columns are id, parable, pane_key, handle, actor_kind, actor_id, name, value, revision, and updated_at. actor_kind names the scope: person for Me, workspace for This Parable, and group for a group setting, whose actor_id is the group’s ID (the stored names predate the product’s). Filter on it when a query needs one scope, since a handle can match one row for each. To let the most specific win, keep per handle the reader’s row, else the row of their deepest group, else This Parable’s:
Here my_groups stands for the Parable’s own Plot of the groups the reader belongs to, one per level, with each level’s depth counted from the top. actor_id reads as the canonical ID text, so a Plot that derives group IDs returns them in that form; parable_cast_identity_uuid turns a hyphenated UUID into it. value is JSON text, which a Plot parses with the JSON functions. A Report run reads the shared settings, This Parable’s and every group’s, as they were when the run was captured, never a person’s own. The run reads the ones its principal may read; a person viewing the run reads the ones they may read now. A Plot with its own schedule or materialization cannot read the table. See Workspace Pool for both, with an example.

Security

Settings need an active Workspace membership on a live account. A suspended, revoked, or missing member, or a deleted account, reaches no settings, even with a seat on the Parable. A person’s setting is theirs alone: nobody else can read, change, or delete it. A shared setting belongs to This Parable and follows the Pane’s current Policies on the line: view.preferences permits reading, create.preferences permits creating, edit.preferences permits replacing, and delete.preferences permits deleting. These are separate grants; editing does not imply creating or deleting. Selecting an older Version does not restore its former grants. Every save and delete carries the revision you last read. A newer revision refuses the write (PA-AU-002); read the setting again and retry without losing your draft. A setting is data unless a Policy reads it. A grant in a Page’s or Pane’s Policies can take its value from a This Parable setting (fromSetting). Changing or deleting that setting also needs permission to edit the Policies that read it, its value must be a valid grant, and every change is recorded. Any other setting grants nothing, and no setting changes the app’s React, CSS, or the text of its Policies. A setting a Policy reads decides who may do what, so its Perception must say whether it is Live or Versioned. Until it does, the Page’s or Pane’s Warnings & Errors name it (PA-AU-050), and it is Live. Choose Live when a change must reach every Version at once, as an audience a Policies Page edits usually must; choose Versioned when a change of who may do what should be reviewed and published like the rest of the Parable. The server reads a setting’s mode from the Parable as it is now, never from the Version being read or from the caller, and enforces it on every save and delete, whichever Pane, tool or API makes it. Removing someone from the Parable’s participants removes their access to its shared settings on their next request.

Reference

Generated Workspace API reference for this Piece: