// FlowsPage — Studio's flow surface. Thin host wrapper around // the swappable fai_studio_flow_editor package: loads the // hub's installed capabilities, hands them + a Studio-side // FlowRunDriver to the editor, and lets the editor own // everything else (file list, three-tab body, properties // panel, run progress, …). // // Pre-0.52 versions split file-listing and run-dialog state // across this page. v0.52 moves all of that into the editor // package so a swap is one pubspec change — Studio doesn't // need to know what's inside the editor any more. import 'package:fai_studio_flow_editor/fai_studio_flow_editor.dart'; import 'package:flutter/material.dart'; import '../data/flow_run_driver.dart'; import '../data/hub.dart'; class FlowsPage extends StatefulWidget { /// Pre-load this flow when the editor first builds. Studio /// keeps the parameter so the Cmd+K palette + welcome page /// can deep-link straight into a specific flow. final String? initialFlowName; const FlowsPage({super.key, this.initialFlowName}); @override State createState() => _FlowsPageState(); } class _FlowsPageState extends State { late Future> _capabilities; late final StudioFlowRunDriver _driver; @override void initState() { super.initState(); _driver = StudioFlowRunDriver(); _capabilities = _loadCapabilities(); } /// Pulls the capability identifiers the picker dialog /// offers when adding a step. `@` so /// the operator can see exactly what they'll be wiring in, /// matching the format the `use:` field expects. Soft-fails /// to an empty list if the hub is unreachable — the editor /// falls back to a free-form text field in that case. Future> _loadCapabilities() async { try { final caps = await HubService.instance.allCapabilities(); final entries = caps .map((c) => '${c.capability}@${c.version}') .toSet() .toList() ..sort(); return entries; } catch (_) { return const []; } } @override Widget build(BuildContext context) { final locale = Localizations.localeOf(context); final editorLocale = locale.languageCode == 'de' ? FlowEditorLocale.de : FlowEditorLocale.en; return FutureBuilder>( future: _capabilities, builder: (context, snap) { final caps = snap.data ?? const []; return FlowEditorPage( initialFlowName: widget.initialFlowName, locale: editorLocale, runDriver: _driver, availableCapabilities: caps, ); }, ); } }