diff --git a/CHANGELOG.md b/CHANGELOG.md index a4856da..7cfbe52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.24.1 + +- No ALL-CAPS "FLOWS" panel header: the page toolbar already names + the page — the duplicate label read as a broken title hierarchy. + The refresh action moved next to the list filter. +- Doc comments name the current CLI (`chain install`). + ## 0.24.0 Usertest-panel fixes (flow list + language): diff --git a/lib/src/flow_editor_page.dart b/lib/src/flow_editor_page.dart index 3040dcd..a278e78 100644 --- a/lib/src/flow_editor_page.dart +++ b/lib/src/flow_editor_page.dart @@ -282,7 +282,8 @@ class _FlowEditorPageState extends State final commentIdx = line.indexOf('#', colonIdx + 1); final rhsEnd = commentIdx < 0 ? line.length : commentIdx; final tail = commentIdx < 0 ? '' : line.substring(rhsEnd); - final newLine = '${line.substring(0, colonIdx + 1)} ${fix.replacement}' + final newLine = + '${line.substring(0, colonIdx + 1)} ${fix.replacement}' '${tail.isEmpty ? '' : ' $tail'}'; if (newLine == line) return; lines[fix.line] = newLine; @@ -643,7 +644,8 @@ outputs: errorCount: _controller.analyzerErrorCount, onAddStep: _controller.activeName != null ? _addStep : null, onSave: _controller.activeName != null ? _save : null, - onRun: _controller.activeName != null && + onRun: + _controller.activeName != null && _controller.analyzerErrorCount == 0 ? () => _tabs.animateTo(2) : null, @@ -843,9 +845,7 @@ outputs: minLines: null, maxLines: null, gutterStyle: GutterStyle( - textStyle: mono.copyWith( - color: theme.colorScheme.onSurfaceVariant, - ), + textStyle: mono.copyWith(color: theme.colorScheme.onSurfaceVariant), background: theme.colorScheme.surfaceContainer, showLineNumbers: true, // Disable the built-in error column entirely — its @@ -1127,9 +1127,7 @@ class _TabActionStrip extends StatelessWidget { child: CircularProgressIndicator(strokeWidth: 2), ) : Icon( - errorCount > 0 - ? Icons.block - : Icons.play_arrow, + errorCount > 0 ? Icons.block : Icons.play_arrow, size: 18, ), label: Text(strings.run), @@ -1392,22 +1390,47 @@ class _FileListState extends State<_FileList> { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: FaiSpace.md, - vertical: FaiSpace.xs, - ), - decoration: BoxDecoration( - border: Border(bottom: BorderSide(color: theme.dividerColor)), + // No ALL-CAPS panel header: the page toolbar already says + // "Flows" — the duplicate label read as a broken title + // hierarchy (usertest art-director finding). The refresh + // action sits next to the filter instead. + Padding( + padding: const EdgeInsets.fromLTRB( + FaiSpace.md, + FaiSpace.xs, + FaiSpace.md, + FaiSpace.xs, ), child: Row( children: [ Expanded( - child: Text( - strings.listHeader, - style: theme.textTheme.labelSmall?.copyWith( - color: theme.colorScheme.onSurfaceVariant, - letterSpacing: 0.6, + child: SizedBox( + height: 28, + child: TextField( + onChanged: (v) => setState(() => _filter = v.trim()), + style: theme.textTheme.bodySmall, + decoration: InputDecoration( + isDense: true, + contentPadding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + prefixIcon: const Icon(Icons.search, size: 14), + prefixIconConstraints: const BoxConstraints( + minWidth: 28, + minHeight: 28, + ), + hintText: strings.listFilterHint, + hintStyle: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(FaiRadius.sm), + borderSide: BorderSide( + color: theme.colorScheme.outlineVariant, + ), + ), + ), ), ), ), @@ -1425,43 +1448,6 @@ class _FileListState extends State<_FileList> { ], ), ), - Padding( - padding: const EdgeInsets.fromLTRB( - FaiSpace.md, - FaiSpace.xs, - FaiSpace.md, - FaiSpace.xs, - ), - child: SizedBox( - height: 28, - child: TextField( - onChanged: (v) => setState(() => _filter = v.trim()), - style: theme.textTheme.bodySmall, - decoration: InputDecoration( - isDense: true, - contentPadding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - prefixIcon: const Icon(Icons.search, size: 14), - prefixIconConstraints: const BoxConstraints( - minWidth: 28, - minHeight: 28, - ), - hintText: strings.listFilterHint, - hintStyle: theme.textTheme.bodySmall?.copyWith( - color: theme.colorScheme.onSurfaceVariant, - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(FaiRadius.sm), - borderSide: BorderSide( - color: theme.colorScheme.outlineVariant, - ), - ), - ), - ), - ), - ), Expanded(child: _buildBody(context, theme)), ], ), @@ -1496,9 +1482,7 @@ class _FileListState extends State<_FileList> { final needle = _filter.toLowerCase(); final files = needle.isEmpty ? all - : all - .where((f) => f.name.toLowerCase().contains(needle)) - .toList(); + : all.where((f) => f.name.toLowerCase().contains(needle)).toList(); if (files.isEmpty) { // Flows exist, the filter just matches none — say that // instead of pretending the directory is empty. @@ -1601,7 +1585,7 @@ class _FileListState extends State<_FileList> { onInstall: widget.onInstallMissing == null ? null : () => - widget.onInstallMissing!(missing), + widget.onInstallMissing!(missing), ), ], ), @@ -2027,8 +2011,10 @@ class _DiagnosticStripState extends State<_DiagnosticStrip> { InkWell( onTap: () => setState(() => _expanded = !_expanded), child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), child: Row( children: [ Container( @@ -2222,16 +2208,10 @@ class _IssueRow extends StatelessWidget { child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.auto_fix_high, size: 13), - label: Text( - fix.label, - style: _monoTextStyle(size: 11), - ), + label: Text(fix.label, style: _monoTextStyle(size: 11)), style: FilledButton.styleFrom( visualDensity: VisualDensity.compact, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), minimumSize: const Size(0, 24), ), ), @@ -2280,7 +2260,10 @@ class _IssueHoverCard extends StatelessWidget { // to viewport so the card never spills off-screen on a // narrow window. const cardWidth = 380.0; - final maxLeft = (media.size.width - cardWidth - 12).clamp(8.0, double.infinity); + final maxLeft = (media.size.width - cardWidth - 12).clamp( + 8.0, + double.infinity, + ); final dx = (request.globalPosition.dx + 12).clamp(8.0, maxLeft); final dy = (request.globalPosition.dy + 18).clamp( 8.0, @@ -2300,9 +2283,7 @@ class _IssueHoverCard extends StatelessWidget { decoration: BoxDecoration( color: theme.colorScheme.surfaceContainerHigh, borderRadius: BorderRadius.circular(8), - border: Border.all( - color: theme.colorScheme.outlineVariant, - ), + border: Border.all(color: theme.colorScheme.outlineVariant), boxShadow: const [ BoxShadow( color: Color(0x33000000), @@ -2453,11 +2434,7 @@ class _FixDialogState extends State<_FixDialog> { return AlertDialog( title: Row( children: [ - Icon( - Icons.auto_fix_high, - size: 20, - color: theme.colorScheme.primary, - ), + Icon(Icons.auto_fix_high, size: 20, color: theme.colorScheme.primary), const SizedBox(width: 8), Text(strings.diagnosticFixDialogTitle), ], @@ -2579,10 +2556,7 @@ class _FixDialogRow extends StatelessWidget { FilledButton.tonalIcon( onPressed: () => onApplyFix(fix), icon: const Icon(Icons.auto_fix_high, size: 13), - label: Text( - fix.label, - style: _monoTextStyle(size: 11), - ), + label: Text(fix.label, style: _monoTextStyle(size: 11)), ), ], ), diff --git a/lib/src/flow_yaml_controller.dart b/lib/src/flow_yaml_controller.dart index 94f81bd..8582b78 100644 --- a/lib/src/flow_yaml_controller.dart +++ b/lib/src/flow_yaml_controller.dart @@ -108,7 +108,7 @@ class FlowYamlCodeController extends CodeController { /// Replace the analyzer's capability provider. Called by the /// editor host when the installed-capability list changes — - /// e.g. after `fai install` while the editor is open. + /// e.g. after `chain install` while the editor is open. void setAvailableCapabilities(List Function() provider) { analyzer = FlowAnalyzer(availableCapabilities: provider); } diff --git a/lib/src/l10n.dart b/lib/src/l10n.dart index 3c0c46b..953796d 100644 --- a/lib/src/l10n.dart +++ b/lib/src/l10n.dart @@ -17,7 +17,6 @@ class FlowEditorStrings { String get save => _t('Save', 'Speichern'); String get run => _t('Run', 'Ausführen'); String get refresh => _t('Refresh file list', 'Datei-Liste neu laden'); - String get listHeader => _t('FLOWS', 'FLOWS'); String get listStartTooltip => _t('Open on the Run tab', 'Im Starten-Tab öffnen'); String get copy => _t('Copy', 'Kopieren'); diff --git a/lib/src/quick_fix.dart b/lib/src/quick_fix.dart index c23bc91..cd4c863 100644 --- a/lib/src/quick_fix.dart +++ b/lib/src/quick_fix.dart @@ -69,8 +69,8 @@ class InstallCapabilityFix extends QuickFix { /// Ask the host to register a new module source for an unknown /// capability — used when the capability isn't in the public /// store. The host's handler typically prompts the operator -/// for a local path (`fai install --link`) or a URL -/// (`fai install `), then installs and reanalyzes. +/// for a local path (`chain install --link`) or a URL +/// (`chain install `), then installs and reanalyzes. /// /// This is the recovery path for private modules: the public /// store doesn't know about `htw.digiscout/onet-lookup`, but diff --git a/pubspec.yaml b/pubspec.yaml index 60d1f9d..8380d23 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: chain_studio_flow_editor description: Swappable inline YAML editor for F∆I Studio flows. -version: 0.24.0 +version: 0.24.1 publish_to: 'none' repository: https://git.flemming.ai/fai/studio-flow-editor