feat: add View-scoped quick access presentation

This commit is contained in:
2026-08-19 18:47:46 +02:00
parent cdbf2bf80b
commit 877dced738
5 changed files with 125 additions and 8 deletions
+53 -3
View File
@@ -771,6 +771,46 @@ export default function ViewsAdminPanel({
/>
)}
<section className="views-product-area-section">
<div className="views-section-heading">
<div>
<h4>Quick Access focus</h4>
<p className="muted small-note">
Recommend or focus namespaced tool IDs for this View. The
active account still needs the tool's permissions and visible surface.
</p>
</div>
</div>
<FormGrid columns={2} collapseAt="standard">
<FormField label="Recommended tool IDs" help="Comma-separated, for example tasks.work, files.recent">
<input
value={(draft.presentation.quickAccessRecommendedToolIds ?? []).join(", ")}
disabled={!definitionEditable || busy}
onChange={(event) => setDraft({
...draft,
presentation: {
...draft.presentation,
quickAccessRecommendedToolIds: commaSeparatedToolIds(event.target.value)
}
})}
/>
</FormField>
<FormField label="Focused tool IDs" help="When at least one listed tool is available, other Quick Access tools are hidden for this View.">
<input
value={(draft.presentation.quickAccessFocusedToolIds ?? []).join(", ")}
disabled={!definitionEditable || busy}
onChange={(event) => setDraft({
...draft,
presentation: {
...draft.presentation,
quickAccessFocusedToolIds: commaSeparatedToolIds(event.target.value)
}
})}
/>
</FormField>
</FormGrid>
</section>
<section className="views-surface-section">
<div className="views-section-heading">
<div>
@@ -1839,7 +1879,9 @@ function defaultPresentation(areas: ViewProductArea[]): ViewPresentation {
return {
navigationMode: "grouped",
productAreaOrder: areas.map((area) => area.id),
productAreaLabels: {}
productAreaLabels: {},
quickAccessRecommendedToolIds: [],
quickAccessFocusedToolIds: []
};
}
@@ -1878,7 +1920,9 @@ function revisionPresentation(
value?.product_area_order?.length
? value.product_area_order
: defaults.productAreaOrder,
productAreaLabels: value?.product_area_labels ?? {}
productAreaLabels: value?.product_area_labels ?? {},
quickAccessRecommendedToolIds: value?.quick_access_recommended_tool_ids ?? [],
quickAccessFocusedToolIds: value?.quick_access_focused_tool_ids ?? []
};
}
@@ -1905,10 +1949,16 @@ function presentationKey(value: ViewPresentation): string {
Object.entries(value.productAreaLabels ?? {})
.filter(([, label]) => label.trim())
.sort(([left], [right]) => left.localeCompare(right))
)
),
quickAccessRecommendedToolIds: value.quickAccessRecommendedToolIds ?? [],
quickAccessFocusedToolIds: value.quickAccessFocusedToolIds ?? []
});
}
function commaSeparatedToolIds(value: string): string[] {
return [...new Set(value.split(",").map((item) => item.trim()).filter(Boolean))];
}
function assignmentDraftKey(draft: AssignmentDraft): string {
return JSON.stringify({