Create categories and tags in place from every assignment picker
Category and tag inputs across the transaction editor, Analyse corrections, and merchant defaults now mint missing entries without a detour through the registry pages. A bare name lands under the kind's root, "Parent / Name" targets that parent, and typing an existing name selects it instead of duplicating. Enter only creates when nothing matches, server rejections surface inline in the dropdown, and assignment pickers offer leaf categories only — the shape the server validates. Mutations now return the accepted state so callers can select the id the server just minted, and the revision-keyed remounts on Transactions and the registry pages are gone: they closed the open modal and threw away pending edits the moment any in-modal creation committed.
This commit is contained in:
+22
-18
@@ -21,7 +21,7 @@ import type {
|
||||
} from "./api";
|
||||
import { categoryPath, request } from "./api";
|
||||
import {
|
||||
CategoryOptions,
|
||||
CategoryCombobox,
|
||||
Empty,
|
||||
ErrorMessage,
|
||||
Field,
|
||||
@@ -550,17 +550,15 @@ function RegistryEditor({
|
||||
</select>
|
||||
</Field>
|
||||
<Field label="Parent category">
|
||||
<select
|
||||
<CategoryCombobox
|
||||
data={data}
|
||||
kind={kind}
|
||||
exclude={[...descendants]}
|
||||
emptyLabel="No parent (root)"
|
||||
mutate={mutate}
|
||||
value={parent}
|
||||
onChange={(e) => setParent(e.target.value)}
|
||||
>
|
||||
<option value="">No parent (root)</option>
|
||||
<CategoryOptions
|
||||
data={data}
|
||||
kind={kind}
|
||||
exclude={[...descendants]}
|
||||
/>
|
||||
</select>
|
||||
onChange={setParent}
|
||||
/>
|
||||
</Field>
|
||||
<p className="muted">
|
||||
Changing the parent moves this category and its entire subtree.
|
||||
@@ -590,15 +588,21 @@ function RegistryEditor({
|
||||
Use these defaults when this merchant is recognized
|
||||
</label>
|
||||
<Field label="Default category">
|
||||
<select
|
||||
<CategoryCombobox
|
||||
data={data}
|
||||
leavesOnly
|
||||
emptyLabel="No default category"
|
||||
mutate={mutate}
|
||||
value={category}
|
||||
onChange={(e) => setCategory(e.target.value)}
|
||||
>
|
||||
<option value="">No default category</option>
|
||||
<CategoryOptions data={data} />
|
||||
</select>
|
||||
onChange={setCategory}
|
||||
/>
|
||||
</Field>
|
||||
<TagPicker data={data} value={tags} onChange={setTags} />
|
||||
<TagPicker
|
||||
data={data}
|
||||
value={tags}
|
||||
onChange={setTags}
|
||||
mutate={mutate}
|
||||
/>
|
||||
<p className="muted">
|
||||
Defaults are only used when explicitly enabled. Editing defaults
|
||||
does not rewrite existing transactions.
|
||||
|
||||
Reference in New Issue
Block a user