Skip to content

Refactor File menu for multi-Dashboard creation, import, and export #463

Description

@BorisTyshkevich

Related to #430 and follows the unified File menu from #452.

Problem

The File menu now shows workspace, Library, and Dashboard operations in one stable list, but its Dashboard behaviour still assumes that one exact Dashboard is already open:

  • there is no New dashboard… command;
  • Import Dashboard… is disabled on the Query surface with “Open a dashboard”;
  • importing may target or replace an exact open Dashboard instead of adding a new Dashboard to the workspace;
  • Export Dashboard… is unavailable unless an exact Dashboard is open, even when the workspace contains Dashboards that could be selected.

That interaction model no longer fits a workspace that can contain multiple Dashboards. The global File menu should manage workspace documents without requiring the user to navigate to one first.

Product decisions

Menu order

Use this stable order on every surface:

New workspace…
New dashboard…
────────────────────────
Import workspace…
Import queries…
Import dashboard…
────────────────────────
Export workspace…                  .json
Export dashboard…                  .json
────────────────────────
Download Library as Markdown       .md
Download Library as SQL            .sql
────────────────────────
<N> Library queries · <M> dashboards

Use sentence case consistently: dashboard, not Dashboard, inside menu labels.

The existing rule remains: surface and workspace context may change enabled state, reason text, or a command’s resolved target, but must not hide or reorder rows.

New dashboard

Add New dashboard… immediately after New workspace….

Behaviour:

  1. require a writable current workspace;
  2. ask for the Dashboard name using the existing anchored dialog/menu primitives;
  3. trim and validate the name;
  4. mint a stable Dashboard id;
  5. append a new empty Dashboard document to the latest committed workspace aggregate;
  6. preserve all existing Dashboards and queries byte-for-byte;
  7. commit through app.mutateWorkspace / the repository validation path;
  8. open the new Dashboard in Dashboard Edit mode after a successful commit.

Rules:

  • duplicate display names are allowed; identity is the Dashboard id;
  • Cancel and Escape commit nothing;
  • a failed commit leaves navigation and local state unchanged and surfaces the diagnostic;
  • do not create a compatibility replacement or overwrite dashboards[0];
  • do not create any saved query, panel, variable configuration, or Library entry.

Disabled reason:

  • no writable workspace: No workspace or the repository’s established unavailable wording.

Import dashboard

Redefine Import dashboard… as an additive workspace operation:

Import one portable Dashboard as a new Dashboard in the current workspace.

It must no longer require an open Dashboard and must be available from Query, Dashboard View, Dashboard Edit, and the empty-Dashboard placeholder whenever a writable workspace exists.

Behaviour:

  • decode and validate the portable bundle before committing;
  • select the Dashboard from the bundle when the format can contain more than one;
  • import the selected Dashboard as a new Dashboard document;
  • remint local Dashboard identity when required by the import contract;
  • import or reconcile its dependent queries through the existing conflict planner;
  • never replace or merge into the currently open Dashboard implicitly;
  • open the imported Dashboard in Edit mode after a successful commit.

If replacement/merge is needed later, expose it as an explicit Dashboard-context operation rather than overloading the global File command.

Disabled reason:

  • no writable workspace: No workspace.

Remove Open a dashboard, Edit mode only, and exact-open-Dashboard targeting from this command.

Export dashboard

Make Export dashboard… workspace-aware rather than surface-gated.

Behaviour:

  • zero Dashboards: disabled with No dashboards;
  • one Dashboard: export that Dashboard directly;
  • multiple Dashboards with an exact Dashboard currently open: preselect that Dashboard;
  • multiple Dashboards with no exact Dashboard open: show a Dashboard chooser;
  • the chooser lists Dashboard names and enough secondary identity to distinguish duplicate names;
  • export uses the existing portable bundle builder and includes the selected Dashboard’s dependency closure;
  • export is available in both Dashboard View and Edit modes and from the Query surface.

The selected export target must always be exact by Dashboard id. No fallback to the first Dashboard is allowed.

Menu model and UI

Update src/core/file-menu-model.ts and src/ui/file-menu.ts so the pure model remains the sole authority for:

  • row order;
  • separators;
  • labels and extensions;
  • enabled/disabled state and reason text;
  • whether export can resolve directly or requires a chooser.

Add a new action id for new-dashboard and choose a Dashboard/add icon distinct from new-workspace where practical.

The footer remains:

1 Library query · 1 dashboard
2 Library queries · 3 dashboards

with correct singular/plural forms at every count, including zero.

Tests

Cover the File-menu model and UI for:

  • Query, Dashboard View, Dashboard Edit, empty collection, unresolved Dashboard selection, missing workspace, one Dashboard, and multiple Dashboards;
  • identical row order on every surface;
  • New dashboard… availability and successful append/navigation;
  • duplicate Dashboard names with distinct ids;
  • cancelled and rejected creation;
  • additive import from every surface;
  • import preserving existing Dashboards;
  • zero/one/many export targeting;
  • chooser preselection from the currently open Dashboard;
  • exact-id export with duplicate names;
  • no fallback to dashboards[0];
  • keyboard operation, focus return, Escape, and outside-click dismissal;
  • current footer counts and grammar.

Acceptance criteria

  • The File menu contains New dashboard… in the agreed stable position on every surface.
  • Creating a Dashboard appends it to the current workspace and opens it in Edit mode.
  • Import dashboard… is additive and does not require an open Dashboard.
  • Export dashboard… works from Query and Dashboard surfaces and selects an exact Dashboard safely.
  • Existing Dashboards and Library queries are never overwritten by implicit fallback behaviour.
  • Menu rows do not appear, disappear, or reorder when the work surface changes.
  • npm test, npm run check:arch, and relevant Chromium/WebKit E2E tests pass.

Non-goals

  • A permanent + button in the Dashboards sidebar header; this issue establishes the canonical command first.
  • Dashboard rename, duplicate, or delete commands.
  • Importing into or replacing an existing Dashboard.
  • Changing workspace import/export semantics.
  • Changing Library download formats.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions