cf2854a0291012525f5d4151367c9f2135d2df95
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8c7553d619 |
copy: the product says "tags" now, and the schema keeps saying Label
Android / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 16s
CI & Build / integration (push) Successful in 23s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m7s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m17s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 8m4s
Two words for one concept cost real comprehension: over a single exchange
the operator concluded that auto-tagging did not exist (it does, in
`derive.rs`) and that a tag-management view did not exist (it does,
`LabelsModal.vue`). The `#` is how most of these get made, so the `#` wins
the noun.
User-visible strings only, on all three surfaces plus the server's errors.
`Label`, `NoteLabel`, `via_tag`, `label_id`, the tables, `/api/labels` and
the FFI names are all untouched — renaming those touches migrations and the
wire format to buy nothing a reader can see.
Two of these were more than a find-and-replace:
* Android's `label_from_tag` said "from #tag", sitting beside a chip that
already renders as `#name`. Once every one of them IS a tag that hint is
circular. What it actually tells you is that the note's BODY owns this
one — which is why it alone has no remove cross — so it now says "from
the text".
* The web's empty state said "No labels yet — create one above" while
Android's already mentioned the `#` route. The web now says it too. That
is the exact fact the operator did not have.
The paired `aria-label`s went with their `title`s; a screen reader saying
"label" while the tooltip says "tag" is the same confusion with a smaller
audience.
Left alone deliberately: `json_error("invalid label")` and
`"label_ids must be a list"` in `notes/__init__.py` name the `?label=` query
parameter and the `label_ids` request field. Those are wire surface, not the
word a person reads.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3MMqUtzX1TJgA1oypvm1c
|
||
|
|
6fbee27f9c |
A tag with no colour of its own derives one from its name
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 4s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 15s
CI & Build / integration (push) Successful in 18s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Update manifest (push) Successful in 6s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m52s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m10s
Android / Kotlin + Rust (APK) (push) Successful in 7m43s
Every #tag ever typed is `default`. `notes/tags.py` mints one as `Label(owner_id=…, name=name)` with no colour, so it takes the column default — which means tag-driven note colour, built on top, would have left the board exactly as grey as it was. Four #todo notes in the operator's screenshot, four different colours, because the tint is per-note-id and ignores tags entirely. DERIVED RATHER THAN PERSISTED AT MINT TIME, reversing the plan in 2965. That plan wanted a hashed colour written wherever a label is born, and named the risk in its own body: `find_or_create_label` is "easy to miss, and it is the common one", because most tags are born from typing `#grocery`, not from a management screen. Deriving has no mint points to miss, needs no backfill for the tags that already exist, and reuses the hash and the fixture the notes already have. The cost is that renaming a tag recolours it. That is defensible — the name IS the tag — and an explicitly picked colour is still stored and still wins, so tag colours stay editable exactly as asked. Lowercased before hashing: tags dedupe case-insensitively, so #Todo and #todo are one tag and must not be two colours. All five places a label's colour is drawn now resolve the same way — the card chip, the editor chip, the drawer's tag list, and the management modal's dot and swatch ring. The modal's ring follows the resolved colour rather than the stored one, so opening the picker highlights what you can already see instead of nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
44a5466793 |
M9 S5 (frontend): shared BaseModal for the standard modals + BaseInput in Account
- BaseModal.vue (new): the backdrop + dialog-panel shell (dimmed fixed overlay, bordered rounded panel, role=dialog, close on Escape + backdrop mousedown). Caller sizes/pads/shadows the panel via `panelClass`, picks start/center `align`, and sets an `ariaLabel` for header-less panels. - LabelsModal, CommandPalette, and the AppShell keyboard-shortcuts overlay drop their hand-rolled backdrop+panel shells and slot their content into BaseModal (~12 lines of overlay boilerplate each → gone). - NoteEditor deliberately keeps its own shell: its backdrop mousedown is drag-guarded and its Esc/⌘-Enter handling is bespoke (unsaved-edit safety), so folding it in would risk regressing the app's core editing surface (rule 28). - AccountView's one device-name field now uses the shared BaseInput. SettingsView is intentionally NOT converted — its rows are a horizontal label+control pattern (checkbox/number/text, direct value mutation), a different shape than BaseInput's vertical form field. Frontend-only; CI vue-tsc is the type/template gate (no local typecheck, rule 10). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |
||
|
|
ae0c748507 |
M6: label management — usage counts + merge
Extends the existing label manager (create/rename/color/delete) with the two missing maintenance tools (task 1904), so the label list stays clean — which matters more now that #tags mint labels automatically. Backend: GET /api/labels returns a per-label note count (one grouped query); new POST /api/labels/<id>/merge moves the source label's notes onto a target and deletes the source (repoint via delete+reinsert to avoid mutating the composite PK; preserves via_tag; dedupes notes already on the target). Body #tags are NOT rewritten, so a tag-sourced label re-mints on next edit if its #tag text remains — a documented nuance. Frontend: LabelsModal shows each label's note count and a 'merge into…' picker; also restores the previously-missing close (x) and merge icons. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |
||
|
|
f321c2bf70 |
labels: per-label color
Give labels a color (migration 0011 adds labels.color, server_default 'default' so existing labels keep the neutral chip). The PATCH endpoint now updates name and/or color; note serialization carries each label's color. Frontend: a swatch picker per label in the Edit-labels modal, colored chips on cards + in the editor (LABEL_CHIP_CLASSES), and a color dot on each sidebar label. Reuses the note color vocabulary. (Graph node coloring rides this in the graph-liveliness task.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |
||
|
|
2046600a95 |
M2 labels frontend: sidebar shell + label filter, chips, picker, manage
- AppShell: persistent left sidebar (Notes · labels · Archive · Trash) + top bar (site name, admin Settings, sign out); BoardView now renders inside it. - labels store (list/create/rename/delete); Note gains labels[]; notes store gains setLabels + label-aware reconcile + /api/notes?label= loading. - /label/:id route → label-filtered board. - LabelPicker (tag a note, create-on-the-fly) in the editor; label chips shown on cards and in the editor; LabelsModal to create/rename/delete labels. - api client PUT; new icons (note/tag/pencil/plus/check); nav-link styles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |