From db90b6c45e2f43dbeb1256d5b343562e4eb208f0 Mon Sep 17 00:00:00 2001 From: Michael Porter Date: Sat, 13 Jun 2026 19:43:31 -0400 Subject: [PATCH 1/2] feat(edge_fields): add per-field "Hide in views" toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds optional `hide_in_views` flag to EdgeField, a toggle in the Edge Field settings panel, and a filter step so hidden fields drop from the Matrix and Tree side views. Codeblocks and page views are unaffected. Closes #132 (item 3 — per-field view visibility). --- .../settings/EdgeFieldSettings.svelte | 27 +++++++++++++++++++ src/components/side_views/Matrix.svelte | 14 +++++++--- src/components/side_views/TreeView.svelte | 14 +++++++--- src/interfaces/settings.ts | 1 + src/utils/edge_fields.ts | 10 +++++++ 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/components/settings/EdgeFieldSettings.svelte b/src/components/settings/EdgeFieldSettings.svelte index 89dd33e2..c9825379 100644 --- a/src/components/settings/EdgeFieldSettings.svelte +++ b/src/components/settings/EdgeFieldSettings.svelte @@ -186,6 +186,17 @@ autosave(); }, + + set_hidden: (edge_field: EdgeField, hidden: boolean) => { + const target = settings.edge_fields.find( + (f) => f.label === edge_field.label, + ); + if (!target) return; + + target.hide_in_views = hidden || undefined; + + autosave(); + }, }, groups: { @@ -460,6 +471,22 @@ {/each} + + {#each group_labels as group_label} field_group_labels.includes(group.label)) .flatMap((group) => group.fields), ); + +export const omit_hidden_view_fields = ( + edge_fields: BreadcrumbsSettings["edge_fields"], + labels: string[], +) => { + const hidden = new Set( + edge_fields.filter((f) => f.hide_in_views).map((f) => f.label), + ); + return labels.filter((l) => !hidden.has(l)); +}; From 9da727680cdf5acacf9f1e388405d7b5c81f9e6f Mon Sep 17 00:00:00 2001 From: Michael Porter Date: Sat, 13 Jun 2026 19:49:15 -0400 Subject: [PATCH 2/2] fix(edge_fields): cascade field removal to transitive rules and source defaults Removing an edge field left dangling references that rename already cleans: transitive rules referencing the label kept generating implied edges (a stale close_field could surface a phantom field in views), and explicit_edge_sources.*.default_field pointers were left pointing at the deleted label. remove() now drops transitive rules that reference the field and clears any matching source default. --- .../settings/EdgeFieldSettings.svelte | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/components/settings/EdgeFieldSettings.svelte b/src/components/settings/EdgeFieldSettings.svelte index c9825379..975e3928 100644 --- a/src/components/settings/EdgeFieldSettings.svelte +++ b/src/components/settings/EdgeFieldSettings.svelte @@ -88,6 +88,38 @@ ); }); + // Drop transitive rules that reference the removed field — + // unlike rename, there's no replacement label to substitute. + settings.implied_relations.transitive = + settings.implied_relations.transitive.filter( + (rule) => + rule.close_field !== edge_field.label && + !rule.chain.some( + (attr) => attr.field === edge_field.label, + ), + ); + + // Clear any edge source default pointing at the removed field. + const sources = settings.explicit_edge_sources; + if (sources.tag_note.default_field === edge_field.label) + sources.tag_note.default_field = ""; + if ( + sources.list_note.default_neighbour_field === + edge_field.label + ) + sources.list_note.default_neighbour_field = ""; + if (sources.dendron_note.default_field === edge_field.label) + sources.dendron_note.default_field = ""; + if ( + sources.johnny_decimal_note.default_field === + edge_field.label + ) + sources.johnny_decimal_note.default_field = ""; + if (sources.date_note.default_field === edge_field.label) + sources.date_note.default_field = ""; + if (sources.regex_note.default_field === edge_field.label) + sources.regex_note.default_field = ""; + autosave(); },