feat: per-row start button on runnable flows (0.21.2)

Flows without missing modules get a play button in the list that
opens them directly on the Run tab - one click from the list to
entering inputs and starting a run. Rows with missing modules keep
the install badge as their single actionable path.

Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
flemming-it 2026-07-11 10:02:55 +02:00
parent c4d3751e85
commit 42f271679c
4 changed files with 49 additions and 1 deletions

View file

@ -289,6 +289,17 @@ class _FlowEditorPageState extends State<FlowEditorPage>
return files;
}
/// Row-level start: open the flow and land directly on the Run
/// tab, where inputs + the start button live. One click from the
/// list to running a flow.
Future<void> _startFile(_FlowFile f) async {
await _openFile(f);
if (!mounted) return;
if (_controller.analyzerErrorCount == 0) {
_tabs.animateTo(2);
}
}
Future<void> _openByName(String name) async {
final path = '${_defaultFlowsDir()}/$name.yaml';
final file = File(path);
@ -551,6 +562,7 @@ outputs:
),
onOpen: _openFile,
onRefresh: _refreshFiles,
onStart: _startFile,
onInstallMissing: widget.onInstallCapability == null
? null
: _installMissingCaps,
@ -1218,6 +1230,11 @@ class _FileList extends StatelessWidget {
final void Function(_FlowFile) onOpen;
final VoidCallback onRefresh;
/// Open the flow directly on the Run tab the per-row start
/// affordance the usertest asked for. Rows with missing modules
/// don't offer it (they can't run yet).
final void Function(_FlowFile) onStart;
/// Install the listed missing capabilities. `null` when the
/// host wired no install handler the warning badge still
/// renders, just without the one-click action.
@ -1230,6 +1247,7 @@ class _FileList extends StatelessWidget {
required this.installedNames,
required this.onOpen,
required this.onRefresh,
required this.onStart,
required this.onInstallMissing,
});
@ -1401,6 +1419,25 @@ class _FileList extends StatelessWidget {
],
),
),
// Per-row start: one click from the list to the
// Run tab. Hidden while modules are missing
// the install badge is the actionable path then.
if (missing.isEmpty)
IconButton(
onPressed: () => onStart(f),
tooltip: strings.listStartTooltip,
icon: Icon(
Icons.play_arrow_rounded,
size: 20,
color: theme.colorScheme.primary,
),
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 32,
minHeight: 32,
),
),
],
),
),