FlowFuse / FlowFuse/flowfuse

Define the dialog component contract and migration pattern for the universal modal system

Open
#8,123 0 comments 0 reactions 1 assignee Claimed by @cstns View on GitHub
area:frontend
Dominant language
JavaScript
Stars
400
Forks
89
Avg merge
1d 21h
Merged PRs (30d)
146

Description

Before we start migrating dialogs to the universal store-based system (#8122), we need to agree as a team on what a "universal-ready" dialog component looks like, how it interacts with the dialog system, and where it lives.

## What needs to be decided

### 1. Dialog component interface

Right now, the few components that work with `Dialog.show()` (like `AddDeviceToGroupDialog`) reach into the `ux-dialog` store directly to do things like `setDisablePrimary()`. This works but couples the component to store internals.

We should provide a cleaner interface for dialog content components. Two options worth discussing:

* **Composable** (e.g. `useDialogContent()`): Dialog components call the composable to get access to methods like `setLoading()`, `disableConfirm()`, `setValidation()`, etc. Lighter, more flexible, opt-in.
* **Wrapper component**: A component that wraps dialog content and provides these methods via slots or provide/inject. More opinionated, enforces consistency.

A composable feels like the more natural fit given how the rest of the codebase works, but this is an open question.

### 2. File organization

Dialog components currently live in `pages/*/dialogs/` directories, co-located with the pages that use them. Since they'll no longer be tightly coupled to specific pages, they should move to `components/dialogs/` with a directory structure that mirrors the page tree:

* `pages/team/dialogs/InviteMemberDialog.vue` -> `components/dialogs/team/InviteMemberDialog.vue`
* `pages/instance/Settings/dialogs/ConfirmInstanceDeleteDialog.vue` -> `components/dialogs/instance/ConfirmInstanceDeleteDialog.vue`
* Shared/cross-cutting dialogs stay in `components/dialogs/` root

### 3. Pattern documentation

Once we settle on the approach, we should document it so new dialogs follow the same pattern from the start. This could live in a CONTRIBUTING note, a README in `components/dialogs/`, or just be well-established through examples.

## Context

The existing universal system (`stores/ux-dialog.js` + `services/dialog.js` + `PlatformDialog.vue`) already works and is proven by the drawer system which follows the same pattern. The goal here is to make sure the migration path is clean before we start moving ~54 dialogs onto it.

See #8122 for the full background and scope.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.