fix(doctor): copy button per path row, readable chain count, cased source kinds
Some checks are pending
Security / Security check (push) Waiting to run
Some checks are pending
Security / Security check (push) Waiting to run
- every daemon file row gets a copy-to-clipboard action next to view/open so terminal users can grab the raw path - audit stat subtitle says 'n of m events verified' instead of the cryptic 'n/m chain' - capability source-kind breakdown renders display names (Bundle/MCP/System) instead of raw lowercase wire tokens Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
8d5d1d74bb
commit
b52590c7d3
1 changed files with 36 additions and 3 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import '../data/error_presentation.dart';
|
import '../data/error_presentation.dart';
|
||||||
import '../data/chain_log.dart';
|
import '../data/chain_log.dart';
|
||||||
|
|
@ -436,6 +437,19 @@ class _PathRow extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: ChainSpace.sm),
|
const SizedBox(width: ChainSpace.sm),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.copy_outlined, size: 14),
|
||||||
|
tooltip: l.buttonCopy,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onPressed: () async {
|
||||||
|
await Clipboard.setData(ClipboardData(text: path));
|
||||||
|
if (!context.mounted) return;
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text(l.aboutCopiedToast)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(width: ChainSpace.xs),
|
||||||
if (isLog || isConfig) ...[
|
if (isLog || isConfig) ...[
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
onPressed: () => isConfig
|
onPressed: () => isConfig
|
||||||
|
|
@ -715,12 +729,31 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format the per-source-kind capability count map as a
|
/// Format the per-source-kind capability count map as a
|
||||||
/// human-readable line like "6 bundle · 3 mcp · 1 system".
|
/// human-readable line like "6 Bundle · 3 MCP · 1 System".
|
||||||
/// Sorted alphabetically for deterministic rendering.
|
/// Sorted alphabetically for deterministic rendering. The hub
|
||||||
|
/// reports lowercase wire identifiers; render them as display
|
||||||
|
/// names so no raw English tokens leak into the localized UI.
|
||||||
String _sourceBreakdown(Map<String, int> bySource) {
|
String _sourceBreakdown(Map<String, int> bySource) {
|
||||||
final entries = bySource.entries.toList()
|
final entries = bySource.entries.toList()
|
||||||
..sort((a, b) => a.key.compareTo(b.key));
|
..sort((a, b) => a.key.compareTo(b.key));
|
||||||
return entries.map((e) => '${e.value} ${e.key}').join(' · ');
|
return entries
|
||||||
|
.map((e) => '${e.value} ${_sourceKindLabel(e.key)}')
|
||||||
|
.join(' · ');
|
||||||
|
}
|
||||||
|
|
||||||
|
String _sourceKindLabel(String kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case 'mcp':
|
||||||
|
return 'MCP';
|
||||||
|
case 'bundle':
|
||||||
|
return 'Bundle';
|
||||||
|
case 'system':
|
||||||
|
return 'System';
|
||||||
|
default:
|
||||||
|
return kind.isEmpty
|
||||||
|
? kind
|
||||||
|
: kind[0].toUpperCase() + kind.substring(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ModulesPanel extends StatelessWidget {
|
class _ModulesPanel extends StatelessWidget {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue