A Trackable is made and edited in one form, TrackableForm (apps/renderer/src/components/trackables/TrackableForm.tsx), at /trackables/create and /trackables/update. It is a single scrolling form with no wizard and no steps. The edit page remounts it per trackable (key on routes/trackables.update.tsx), so going from one trackable’s edit page to another’s never keeps the first one’s draft. It is one component because its sections are coupled through one submit: the chosen structure decides which branch of onSubmit runs, and the value schema, the derived spec and the presentation each feed the one payload it saves. Splitting it along its visual sections would spread that submit across several files.

One sectioned form

In order:

  1. Trackable: the name, description and colour, then the structure, Computation: Direct, Derived (the Derived Trackable term’s short form) or Tag. Then, by the choice:
    • a direct trackable’s fields, in the fields editor (Value Types), with its own value’s sections below them: the options and In order for options, the choices and Only these for a list, the words for true and false for a yes/no. A trackable whose only field is its own value shows that field’s kind and settings with no Name box; once it has fields beside it, its own value’s row is headed by the trackable’s name, and every other field has one Name box;
    • a derived trackable’s formula, in the formula builder (Derived Authoring);
    • a tag’s Exclusive, its members, and Summarised by (Tags).
  2. Tags, shown when there is a tag to take: a checkbox for each tag it could take, leaving out itself and its descendants.
  3. Capture, for a direct trackable with a value to start: Prefill, and Quick-add amounts for a number (Capture Model).
  4. Cadence, for a direct trackable: its place in the Rundown (The Rundown), what a day with nothing logged means, Whole day, whether its entries put days on hold, and whether it is a routine.
  5. Zones, where its values have a numeric scale (Zones).

A trackable’s visualizations, the one it opens on, and their chart types and calendar shading are set on its page once it exists, not here (Visualizations). A visualization of several trackables is made in the Editor for Several Trackables and belongs to none of them.

When editing, the structure collapses to one line naming it (Direct, Derived Trackable or Tag, and a direct one’s fields) with Change beside it and “can invalidate entries you have already logged”, since it is the choice that can; the control stays live rather than locked. The Inbox’s structure has no Change, since it stays text (Inbox).

Labels

The form’s headings and its less obvious controls are glossary terms with their (i), through FormSection’s info: the Trackable, Tags and Cadence sections, Prefill, Limit, Step, Stale after and Whole day. Capture is a typed heading with no (i). Zones names info="zone", a term the glossary does not have, so TermInfo draws nothing there. No label carries a parenthetical; its explanation is in the (i) (UI Vocabulary and the Info Affordance).

A number field’s settings each have a label above them: Unit, Min and Max (the Limits) and Step. Unit, Min, Max and Step each carry an (i), and Unit is the glossary’s term (apps/renderer/src/components/fields/FieldsEditor.tsx). The unit list names the unit a preference resolves to, “kg (my preference)”, so it reads differently from a plain “kg” that does not follow the preference. Limits are kept in the unit they were typed in, and checked as Capture Model says.

What the draft rules out is absent

Each control is checked against what the rest of the draft has decided, and one that cannot apply is not shown rather than disabled: Prefill only where there is a value to start (takesPrefill); Zones only where the value has a numeric scale (a number, an interval’s length, a clock time, a moment read by when it was logged) and not on a derived yes/no; List only where a field already is one. A derived trackable is judged by what its formula produces, not by number fields it never shows. On a trackable’s page, the chart types a visualization offers are only those its value can be drawn as (chartTypesFor), each shown as a small picture (ChartGlyph).

The preview

TrackablePreview draws the draft with the trackable chart, as the saved trackable will draw: beside the form and sticky on a wide screen, inline above the sections that change it on a narrow one. It always says where its data comes from. A direct trackable being edited, whose kind of value has not changed in the draft and which has entries, shows “Your last 30 days”; a derived draft is evaluated as it stands, “Computed from your data”, new or not, since its inputs have history; anything else draws deterministic sample data inside the draft’s limits, “Sample data — not yours”, which does not flicker as you type. A moment has no sample to draw, so a new one’s preview is an empty chart under that label. A tag, or a draft with nothing to chart, has no preview. There is no preview of logging.

What a change does to entries

Every setting of a trackable is at one of three levels:

  • Safe, changed freely: the name, colour and description, an option’s label and colour, loosened Limits, units and Step, visualizations, cadence, Stale after.
  • Unsafe but editable: a direct trackable made Derived or a Tag, which stops reading every entry it has, kept stored; a field’s kind, a field hidden or removed, which end dates an interval, an option entries hold no longer offered, a choice’s options put in order or taken out of it, and Limits tightened so that entries fall outside them (those entries keep their values and still save with a new time or note, Value Types). unsafeChanges (packages/core/src/trackable-changes.ts) finds them by comparing the saved definition with the draft, a field known by its key. What a saved number field measures is not editable at all: its numbers are stored in that measure’s base unit, so the form fixes it once the field is saved. A derived trackable or a tag has no entries of its own, so no change to one is unsafe.
  • Made yours: an unsafe change to a trackable that follows its module makes it yours, and the module’s updates stop reaching it (Modules). made_yours_at is written by the same update as the new definition, so a save that fails leaves it following.

On save the form asks once when a change is unsafe, listing each in a sentence with how many entries it reaches (entriesReached, unsafeChangeText), and, for a module’s follower, saying that it becomes yours. Tightened Limits are asked about only when some entry falls outside them (changesToAsk). A safe change saves without asking. A removed field is hidden (hidden: true): not asked when logging, its values kept, and listed under the fields as “Hidden, their values kept” with Bring back, which is safe; a new field not yet saved is simply dropped. The form never changes a stored option’s code, so relabelling is the only change to an option, and it is safe; a removed option is kept as a retired one (Stranded Option Data). Changing which end dates an interval rewrites the affected entries’ times on save (redated).

The form keeps whatever stored configuration it does not offer, so an edit cannot drop it: the save starts from a copy of the stored capture and presentation and sets only what the form owns. Computed fills, the constant starting value, a source and record summaries come through an edit untouched.

Options

The options section guides toward a scale rather than a list of words: Options is the kind the field picker offers for a choice, the In order checkbox says what it means in a line beneath (“In order, worst to best: logged with a slider and analysed as a number”, or “No order: logged by picking one, and counted rather than averaged”), each option shows the code it will be stored as, and Means none is offered for a new option when no option is coded 0 yet (Value Types).

Trackable · Value Types · Capture Model · Presentation Layer · Derived Authoring · Page Specs