feat: project separation in the flow list (0.25.0)

Filter the file list by the host's active project — flows without
a project: key count as 'general', display-only, the file is never
rewritten. New flows are stamped with the active project's key
(general and all-projects stay unstamped). Adds a toolbarTrailing
slot so the host can mount its workspace switcher in the editor's
single toolbar, and a flowsDir injection point so widget tests run
against a temp dir instead of the operator's ~/.chain flows.
Covered by pure filter-semantics tests plus hermetic widget tests
for filtering, the project-empty state, and new-flow stamping.

Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
flemming-it 2026-07-22 13:56:29 +02:00
parent ab97e5e834
commit c4a39a3779
6 changed files with 302 additions and 9 deletions

View file

@ -24,6 +24,21 @@ String parseFlowProject(String yaml) {
return '';
}
/// The project a flow file effectively belongs to: its own
/// `project:` slug, or `general` when the file declares none.
/// Display/filter semantics only the FILE stays the truth and
/// is never rewritten to make this explicit.
String effectiveFlowProject(String fileProject) =>
fileProject.isEmpty ? 'general' : fileProject;
/// Whether a flow file belongs in the list under the active
/// workspace filter. Empty [activeProject] = "all projects";
/// otherwise the file's effective project (no key = `general`)
/// must match.
bool flowVisibleInProject(String fileProject, String activeProject) =>
activeProject.isEmpty ||
effectiveFlowProject(fileProject) == activeProject;
/// Mirror of the hub's `normalize_project_slug`: lowercase,
/// collapse spaces/underscores/dashes to a single `-`, drop
/// everything else, trim trailing dashes. Empty in empty out