diff --git a/lib/features/mongodb/mongo_aggregation_workspace.dart b/lib/features/mongodb/mongo_aggregation_workspace.dart index d869a85b..570be097 100644 --- a/lib/features/mongodb/mongo_aggregation_workspace.dart +++ b/lib/features/mongodb/mongo_aggregation_workspace.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/features/mongodb/mongo_aggregation_stage.dart'; import 'package:querya_desktop/features/mongodb/mongo_documents_json_view.dart'; import 'package:querya_desktop/features/mongodb/mongo_documents_table_view.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Workspace for visually and interactively building, running, and inspecting /// MongoDB Aggregation Pipelines step-by-step. @@ -270,12 +271,11 @@ class _MongoAggregationWorkspaceState mainAxisSize: material.MainAxisSize.min, children: [ if (widget.onBack != null) ...[ - OutlineButton( + QueryaButton.secondary( + label: 'Back to Documents', + icon: material.Icons.arrow_back_rounded, onPressed: widget.onBack, - size: ButtonSize.small, - leading: const material.Icon(material.Icons.arrow_back_rounded, - size: 14), - child: const Text('Back to Documents'), + size: QueryaControlSize.sm, ), const Gap(12), ], @@ -301,30 +301,26 @@ class _MongoAggregationWorkspaceState ), ], const Gap(16), - OutlineButton( + QueryaButton.secondary( + label: 'Add Stage', + icon: material.Icons.add_rounded, onPressed: () => _addStage(), - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.add_rounded, size: 14), - child: const Text('Add Stage'), + size: QueryaControlSize.sm, ), const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Export Code', + icon: material.Icons.code_rounded, onPressed: _showExportDialog, - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.code_rounded, size: 14), - child: const Text('Export Code'), + size: QueryaControlSize.sm, ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: _executing ? 'Running...' : 'Run Pipeline', + icon: material.Icons.play_arrow_rounded, + loading: _executing, onPressed: _executing ? null : () => _runPipeline(), - size: ButtonSize.small, - leading: _executing - ? const QueryaSpinner(size: QueryaSpinnerSize.sm) - : const material.Icon(material.Icons.play_arrow_rounded, - size: 16), - child: Text(_executing ? 'Running...' : 'Run Pipeline'), + size: QueryaControlSize.sm, ), ], ), @@ -357,14 +353,11 @@ class _MongoAggregationWorkspaceState itemBuilder: (context, index) { if (index == _stages.length) { return material.Center( - child: OutlineButton( + child: QueryaButton.secondary( + label: 'Add Next Stage', + icon: material.Icons.add_circle_outline_rounded, onPressed: () => _addStage(), - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.add_circle_outline_rounded, - size: 14, - ), - child: const Text('Add Next Stage'), + size: QueryaControlSize.sm, ), ); } @@ -685,14 +678,11 @@ class _StageCardState extends material.State<_StageCard> { // Footer actions: run up to here material.Row( children: [ - GhostButton( + QueryaButton.ghost( + label: 'Run up to here', + icon: material.Icons.play_circle_outline_rounded, onPressed: stage.isEnabled ? widget.onRunUpToHere : null, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.play_circle_outline_rounded, - size: 14, - ), - child: const Text('Run up to here'), + size: QueryaControlSize.sm, ), const Gap(8), material.Expanded( @@ -830,11 +820,14 @@ class _ExportDialogState extends material.State<_ExportDialog> { ], ), actions: [ - OutlineButton( + QueryaButton.ghost( + label: 'Close', onPressed: () => material.Navigator.of(context).pop(), - child: const Text('Close'), + size: QueryaControlSize.md, ), - PrimaryButton( + QueryaButton.primary( + label: 'Copy to Clipboard', + icon: material.Icons.copy_rounded, onPressed: () async { await Clipboard.setData(ClipboardData(text: code)); if (context.mounted) { @@ -846,8 +839,7 @@ class _ExportDialogState extends material.State<_ExportDialog> { material.Navigator.of(context).pop(); } }, - leading: const material.Icon(material.Icons.copy_rounded, size: 16), - child: const Text('Copy to Clipboard'), + size: QueryaControlSize.md, ), ], ); diff --git a/lib/features/mongodb/mongo_collections_view.dart b/lib/features/mongodb/mongo_collections_view.dart index 0c4078d2..ef983d2e 100644 --- a/lib/features/mongodb/mongo_collections_view.dart +++ b/lib/features/mongodb/mongo_collections_view.dart @@ -9,6 +9,7 @@ import 'package:querya_desktop/core/database/mongodb_service.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Displays the list of collections in a MongoDB database. class MongoCollectionsView extends material.StatefulWidget { @@ -239,11 +240,11 @@ class _MongoCollectionsViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -305,14 +306,11 @@ class _MongoCollectionsViewState extends material.State { ), ), if (widget.onOpenQueryConsole != null) ...[ - OutlineButton( + QueryaButton.secondary( + label: 'MQL Console', + icon: material.Icons.terminal_rounded, onPressed: widget.onOpenQueryConsole, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.terminal_rounded, - size: 14, - ), - child: const Text('MQL Console'), + size: QueryaControlSize.sm, ), const Gap(8), ], @@ -324,12 +322,11 @@ class _MongoCollectionsViewState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'Create', + icon: material.Icons.add_rounded, onPressed: _createCollection, - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.add_rounded, size: 16), - child: const Text('Create'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_document_editor.dart b/lib/features/mongodb/mongo_document_editor.dart index 400a0110..5a9310c8 100644 --- a/lib/features/mongodb/mongo_document_editor.dart +++ b/lib/features/mongodb/mongo_document_editor.dart @@ -12,6 +12,7 @@ import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Full-screen JSON editor for a single MongoDB document. class MongoDocumentEditor extends material.StatefulWidget { @@ -281,33 +282,28 @@ class _MongoDocumentEditorState extends material.State { child: Text(idStr).semiBold().small(), ), // Format button - OutlineButton( + QueryaButton.secondary( + label: 'Format', + icon: material.Icons.format_align_left_rounded, onPressed: _format, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.format_align_left_rounded, - size: 14), - child: const Text('Format'), + size: QueryaControlSize.sm, ), const Gap(8), // Save button - PrimaryButton( + QueryaButton.primary( + label: _saving ? 'Saving...' : 'Save', + icon: material.Icons.save_rounded, + loading: _saving, onPressed: _saving ? null : _save, - size: ButtonSize.small, - leading: _saving - ? const QueryaSpinner(size: QueryaSpinnerSize.sm) - : const material.Icon(material.Icons.save_rounded, - size: 14), - child: Text(_saving ? 'Saving...' : 'Save'), + size: QueryaControlSize.sm, ), const Gap(8), // Delete button - DestructiveButton( + QueryaButton.destructive( + label: 'Delete', + icon: material.Icons.delete_rounded, onPressed: _deleting ? null : _delete, - size: ButtonSize.small, - leading: const material.Icon(material.Icons.delete_rounded, - size: 14), - child: const Text('Delete'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_document_tree_view.dart b/lib/features/mongodb/mongo_document_tree_view.dart index 052826cf..b1733359 100644 --- a/lib/features/mongodb/mongo_document_tree_view.dart +++ b/lib/features/mongodb/mongo_document_tree_view.dart @@ -7,6 +7,8 @@ import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/features/mongodb/mongo_field_codec.dart'; import 'package:querya_desktop/shared/widgets/app_toast.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; +import 'package:querya_desktop/shared/widgets/querya_button.dart'; /// Appends a key or list index to a JavaScript / JSON Path expression. /// @@ -188,38 +190,30 @@ class _MongoDocumentTreeViewState extends State { ), const Gap(8), if (_searchQuery.isNotEmpty) - GhostButton( + QueryaButton.icon( + icon: material.Icons.close_rounded, + tooltip: 'Clear search', + size: QueryaControlSize.sm, onPressed: () { _searchController.clear(); setState(() { _searchQuery = ''; }); }, - size: ButtonSize.small, - child: const material.Icon( - material.Icons.close_rounded, - size: 14, - ), ), const Spacer(), - OutlineButton( + QueryaButton.secondary( + label: 'Expand All', + icon: material.Icons.unfold_more_rounded, onPressed: _expandAll, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.unfold_more_rounded, - size: 14, - ), - child: const Text('Expand All'), + size: QueryaControlSize.sm, ), const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Collapse All', + icon: material.Icons.unfold_less_rounded, onPressed: _collapseAll, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.unfold_less_rounded, - size: 14, - ), - child: const Text('Collapse All'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_documents_table_view.dart b/lib/features/mongodb/mongo_documents_table_view.dart index 665650c9..b5dfcddd 100644 --- a/lib/features/mongodb/mongo_documents_table_view.dart +++ b/lib/features/mongodb/mongo_documents_table_view.dart @@ -5,6 +5,8 @@ import 'package:querya_desktop/features/mongodb/mongo_ejson.dart'; import 'package:querya_desktop/features/workspace/result_grid_view.dart'; import 'package:querya_desktop/shared/widgets/app_toast.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; +import 'package:querya_desktop/shared/widgets/querya_button.dart'; /// Precomputed column and cell model for [MongoDocumentsTableView]. class MongoTableGridData { @@ -201,36 +203,27 @@ class _MongoDocumentsTableViewState extends State { ], const Spacer(), if (widget.onDocumentTap != null) ...[ - OutlineButton( + QueryaButton.secondary( + label: 'View Document', + icon: material.Icons.open_in_new_rounded, onPressed: () => widget.onDocumentTap!(selectedDoc), - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.open_in_new_rounded, - size: 13, - ), - child: const Text('View Document'), + size: QueryaControlSize.sm, ), const Gap(6), ], - OutlineButton( + QueryaButton.secondary( + label: 'Copy JSON', + icon: material.Icons.copy_rounded, onPressed: () => _copySelectedDocJson(selectedDoc), - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.copy_rounded, - size: 13, - ), - child: const Text('Copy JSON'), + size: QueryaControlSize.sm, ), if (widget.onDeleteDocument != null) ...[ const Gap(6), - DestructiveButton( + QueryaButton.destructive( + label: 'Delete', + icon: material.Icons.delete_outline_rounded, onPressed: () => widget.onDeleteDocument!(selectedDoc), - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.delete_outline_rounded, - size: 13, - ), - child: const Text('Delete'), + size: QueryaControlSize.sm, ), ], ] else ...[ diff --git a/lib/features/mongodb/mongo_documents_view.dart b/lib/features/mongodb/mongo_documents_view.dart index e8c3ca91..5a86bcfb 100644 --- a/lib/features/mongodb/mongo_documents_view.dart +++ b/lib/features/mongodb/mongo_documents_view.dart @@ -15,6 +15,7 @@ import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart' import 'package:querya_desktop/features/workspace/grid_cell_popover_inspector.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _defaultLimit = 25; @@ -466,16 +467,16 @@ class _MongoDocumentsViewState extends material.State { ), ), const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Apply', onPressed: _applyFilter, - size: ButtonSize.small, - child: const Text('Apply'), + size: QueryaControlSize.sm, ), const Gap(4), - GhostButton( + QueryaButton.ghost( + label: 'Clear', onPressed: _clearFilter, - size: ButtonSize.small, - child: const Text('Clear'), + size: QueryaControlSize.sm, ), const Gap(12), // View Mode Switcher @@ -532,46 +533,37 @@ class _MongoDocumentsViewState extends material.State { ), if (widget.onOpenAggregation != null) ...[ const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Aggregation', + icon: material.Icons.auto_awesome_motion_rounded, onPressed: widget.onOpenAggregation, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.auto_awesome_motion_rounded, - size: 14, - ), - child: const Text('Aggregation'), + size: QueryaControlSize.sm, ), ], if (widget.onOpenIndexes != null) ...[ const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Indexes', + icon: material.Icons.layers_outlined, onPressed: widget.onOpenIndexes, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.layers_outlined, - size: 14, - ), - child: const Text('Indexes'), + size: QueryaControlSize.sm, ), ], if (widget.onOpenQueryConsole != null) ...[ const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Console', + icon: material.Icons.terminal_rounded, onPressed: widget.onOpenQueryConsole, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.terminal_rounded, - size: 14, - ), - child: const Text('Console'), + size: QueryaControlSize.sm, ), ], const Gap(12), - PrimaryButton( + QueryaButton.primary( + label: 'Add Document', + icon: material.Icons.add_rounded, onPressed: _addDocument, - size: ButtonSize.small, - leading: const material.Icon(material.Icons.add_rounded, size: 16), - child: const Text('Add Document'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_indexes_view.dart b/lib/features/mongodb/mongo_indexes_view.dart index dbdda5f8..dfd13f04 100644 --- a/lib/features/mongodb/mongo_indexes_view.dart +++ b/lib/features/mongodb/mongo_indexes_view.dart @@ -6,6 +6,7 @@ import 'package:querya_desktop/core/database/mongodb_service.dart'; import 'package:querya_desktop/features/mongodb/mongo_create_index_dialog.dart'; import 'package:querya_desktop/features/mongodb/mongo_index_info.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Interactive view for managing, inspecting, creating, and dropping /// MongoDB collection indexes with disk size metrics. @@ -215,10 +216,10 @@ class _MongoIndexesViewState extends material.State { ), ), ), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', onPressed: _load, - size: ButtonSize.small, - child: const Text('Retry'), + size: QueryaControlSize.sm, ), ], ), @@ -271,12 +272,11 @@ class _MongoIndexesViewState extends material.State { mainAxisSize: material.MainAxisSize.min, children: [ if (widget.onBack != null) ...[ - OutlineButton( + QueryaButton.secondary( + label: 'Back to Documents', + icon: material.Icons.arrow_back_rounded, onPressed: widget.onBack, - size: ButtonSize.small, - leading: const material.Icon(material.Icons.arrow_back_rounded, - size: 14), - child: const Text('Back to Documents'), + size: QueryaControlSize.sm, ), const Gap(12), ], @@ -309,12 +309,11 @@ class _MongoIndexesViewState extends material.State { onPressed: _load, ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'Create Index', + icon: material.Icons.add_rounded, onPressed: _openCreateIndexDialog, - size: ButtonSize.small, - leading: - const material.Icon(material.Icons.add_rounded, size: 14), - child: const Text('Create Index'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_query_workspace.dart b/lib/features/mongodb/mongo_query_workspace.dart index 626b1ccb..fdce9a4e 100644 --- a/lib/features/mongodb/mongo_query_workspace.dart +++ b/lib/features/mongodb/mongo_query_workspace.dart @@ -11,6 +11,7 @@ import 'package:querya_desktop/features/mongodb/mongo_documents_table_view.dart' import 'package:querya_desktop/features/mongodb/mongo_query_executor.dart'; import 'package:querya_desktop/features/mongodb/mql_parser.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; enum _ResultViewMode { grid, @@ -266,9 +267,10 @@ class _MongoQueryWorkspaceState extends material.State { }, ), actions: [ - OutlineButton( + QueryaButton.ghost( + label: 'Close', onPressed: () => material.Navigator.of(ctx).pop(), - child: const Text('Close'), + size: QueryaControlSize.md, ), ], ); @@ -352,14 +354,11 @@ class _MongoQueryWorkspaceState extends material.State { mainAxisSize: material.MainAxisSize.min, children: [ if (widget.onBack != null) ...[ - OutlineButton( + QueryaButton.secondary( + label: 'Back to Documents', + icon: material.Icons.arrow_back_rounded, onPressed: widget.onBack, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.arrow_back_rounded, - size: 14, - ), - child: const Text('Back to Documents'), + size: QueryaControlSize.sm, ), const Gap(12), ], @@ -382,13 +381,12 @@ class _MongoQueryWorkspaceState extends material.State { ), const Gap(8), // Run Query button - PrimaryButton( + QueryaButton.primary( + label: 'Run Query (Ctrl+Enter)', + icon: material.Icons.play_arrow_rounded, + loading: _activeTab.isLoading, onPressed: _activeTab.isLoading ? null : _executeActiveTab, - size: ButtonSize.small, - leading: _activeTab.isLoading - ? const QueryaSpinner(size: QueryaSpinnerSize.sm) - : const material.Icon(material.Icons.play_arrow_rounded, size: 16), - child: const Text('Run Query (Ctrl+Enter)'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/mongodb/mongo_stats_view.dart b/lib/features/mongodb/mongo_stats_view.dart index 23d4af9c..d70b82df 100644 --- a/lib/features/mongodb/mongo_stats_view.dart +++ b/lib/features/mongodb/mongo_stats_view.dart @@ -9,6 +9,7 @@ import 'package:querya_desktop/core/database/mongodb_service.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _defaultAutoRefresh = Duration(seconds: 3); const _summaryChipHeight = 88.0; @@ -258,11 +259,11 @@ class _MongoStatsViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -285,11 +286,11 @@ class _MongoStatsViewState extends material.State { const Gap(8), const Text('serverStatus returned no data.').muted().small(), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: _load, - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -415,38 +416,33 @@ class _MongoStatsViewState extends material.State { children: [ if (widget.lastSelectedMongoCollection != null && widget.onRestoreLastSelectedObject != null) - OutlineButton( + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedMongoCollection}', + icon: material.Icons.table_chart_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.table_chart_outlined, - size: 18, - ), - child: Text('Return to ${widget.lastSelectedMongoCollection}'), + size: QueryaControlSize.md, ) else if (widget.lastSelectedMongoDb != null && widget.onRestoreLastSelectedObject != null) - OutlineButton( + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedMongoDb}', + icon: material.Icons.folder_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.folder_outlined, - size: 18, - ), - child: Text('Return to ${widget.lastSelectedMongoDb}'), + size: QueryaControlSize.md, ), if (widget.onBack != null) - OutlineButton( + QueryaButton.secondary( + label: 'Explorer', + icon: material.Icons.grid_view_rounded, onPressed: widget.onBack, - leading: const material.Icon(material.Icons.grid_view_rounded, - size: 18), - child: const Text('Explorer'), + size: QueryaControlSize.md, ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh now', + icon: material.Icons.refresh_rounded, + loading: _manualRefreshing, onPressed: _manualRefreshing ? null : _refreshNow, - leading: _manualRefreshing - ? const QueryaSpinner(size: QueryaSpinnerSize.sm) - : const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Refresh now'), + size: QueryaControlSize.md, ), material.SizedBox( width: 132, diff --git a/lib/features/redis/editors/redis_list_editor.dart b/lib/features/redis/editors/redis_list_editor.dart index 7496912c..c14b3459 100644 --- a/lib/features/redis/editors/redis_list_editor.dart +++ b/lib/features/redis/editors/redis_list_editor.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart' as material; import 'package:querya_desktop/core/database/redis_bulk.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Editor for a Redis list: RPUSH add bar plus an indexed item list with /// in-place edit (LSET) and remove (LREM). @@ -79,15 +80,15 @@ class _RedisListEditorState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'RPUSH', onPressed: () { final v = _valueController.text; if (v.isEmpty) return; widget.onPush(v); _valueController.clear(); }, - size: ButtonSize.small, - child: const Text('RPUSH'), + size: QueryaControlSize.sm, ), ], ), @@ -168,15 +169,17 @@ class RedisEditListDialogContentState ], ), actions: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.md, ), - PrimaryButton( + QueryaButton.primary( + label: 'Save', onPressed: () { Navigator.of(context).pop(_controller.text); }, - child: const Text('Save'), + size: QueryaControlSize.md, ), ], ); diff --git a/lib/features/redis/redis_cli_workspace.dart b/lib/features/redis/redis_cli_workspace.dart index 3e07177a..8109de68 100644 --- a/lib/features/redis/redis_cli_workspace.dart +++ b/lib/features/redis/redis_cli_workspace.dart @@ -9,6 +9,7 @@ import 'package:querya_desktop/core/database/redis_connection.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Known Redis commands for auto-completion. const List kRedisCommands = [ @@ -627,29 +628,23 @@ class _RedisCliWorkspaceState extends material.State { ), ), const Spacer(), - OutlineButton( + QueryaButton.secondary( + label: 'Clear', + icon: material.Icons.cleaning_services_rounded, onPressed: () { setState(() { _entries.clear(); }); }, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.cleaning_services_rounded, - size: 13, - ), - child: const Text('Clear'), + size: QueryaControlSize.sm, ), if (widget.onBack != null) ...[ const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Close CLI', + icon: material.Icons.close_rounded, onPressed: widget.onBack, - size: ButtonSize.small, - leading: const material.Icon( - material.Icons.close_rounded, - size: 14, - ), - child: const Text('Close CLI'), + size: QueryaControlSize.sm, ), ], ], @@ -771,16 +766,12 @@ class _RedisCliWorkspaceState extends material.State { ), ), const Gap(8), - PrimaryButton( + QueryaButton.primary( + label: 'Run', + icon: material.Icons.play_arrow_rounded, + loading: _executing, onPressed: _executing ? null : _submitCommand, - size: ButtonSize.small, - leading: _executing - ? const QueryaSpinner(size: QueryaSpinnerSize.sm) - : const material.Icon( - material.Icons.play_arrow_rounded, - size: 16, - ), - child: const Text('Run'), + size: QueryaControlSize.sm, ), ], ), diff --git a/lib/features/redis/redis_key_editor.dart b/lib/features/redis/redis_key_editor.dart index 9e188d78..8ba2d83f 100644 --- a/lib/features/redis/redis_key_editor.dart +++ b/lib/features/redis/redis_key_editor.dart @@ -10,6 +10,7 @@ import 'package:querya_desktop/features/redis/editors/redis_zset_editor.dart'; import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; /// Viewer / editor for a single Redis key. Type-aware: string, hash, /// list, set, zset. Stream / module / unknown types are not GET/SET. @@ -241,12 +242,10 @@ class _RedisKeyEditorState extends material.State { return material.Padding( padding: const material.EdgeInsets.only(top: 12), child: material.Center( - child: OutlineButton( + child: QueryaButton.secondary( + label: _loadingMore ? 'Loading...' : 'Load more ($_loadedCount / $_collectionTotal)', onPressed: _loadingMore ? null : () => _loadMore(), - size: ButtonSize.small, - child: _loadingMore - ? const Text('Loading...') - : Text('Load more ($_loadedCount / $_collectionTotal)'), + size: QueryaControlSize.sm, ), ), ); @@ -1048,11 +1047,13 @@ class _RedisTtlDialogContentState ], ), actions: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.md, ), - PrimaryButton( + QueryaButton.primary( + label: 'Apply', onPressed: () { final val = int.tryParse(_controller.text.trim()); if (val != null) { @@ -1060,7 +1061,7 @@ class _RedisTtlDialogContentState } Navigator.of(context).pop(); }, - child: const Text('Apply'), + size: QueryaControlSize.md, ), ], ); @@ -1112,18 +1113,20 @@ class _RedisRenameDialogContentState ], ), actions: [ - GhostButton( + QueryaButton.ghost( + label: 'Cancel', onPressed: () => Navigator.of(context).pop(), - child: const Text('Cancel'), + size: QueryaControlSize.md, ), - PrimaryButton( + QueryaButton.primary( + label: 'Rename', onPressed: () { final val = _controller.text.trim(); if (val.isNotEmpty) { Navigator.of(context).pop(val); } }, - child: const Text('Rename'), + size: QueryaControlSize.md, ), ], ); diff --git a/lib/features/redis/redis_keys_view.dart b/lib/features/redis/redis_keys_view.dart index d870a4b9..687e5d47 100644 --- a/lib/features/redis/redis_keys_view.dart +++ b/lib/features/redis/redis_keys_view.dart @@ -8,6 +8,7 @@ import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; import 'redis_key_tree_engine.dart'; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; export 'redis_key_tree_engine.dart' show RedisKeyInfo; @@ -317,12 +318,10 @@ class _RedisKeysViewState extends material.State { .muted(), if (_hasMore) ...[ const Gap(16), - OutlineButton( + QueryaButton.secondary( + label: _loadingMore ? 'Scanning...' : 'Continue scanning', onPressed: _loadingMore ? null : _loadMore, - size: ButtonSize.small, - child: _loadingMore - ? const Text('Scanning...') - : const Text('Continue scanning'), + size: QueryaControlSize.sm, ), ], ], @@ -340,12 +339,10 @@ class _RedisKeysViewState extends material.State { return material.Padding( padding: const material.EdgeInsets.only(top: 12), child: material.Center( - child: OutlineButton( + child: QueryaButton.secondary( + label: _loadingMore ? 'Loading...' : 'Load more (${_keys.length} / $_dbSize)', onPressed: _loadingMore ? null : _loadMore, - size: ButtonSize.small, - child: _loadingMore - ? const Text('Loading...') - : Text('Load more (${_keys.length} / $_dbSize)'), + size: QueryaControlSize.sm, ), ), ); @@ -377,12 +374,10 @@ class _RedisKeysViewState extends material.State { return material.Padding( padding: const material.EdgeInsets.only(top: 12), child: material.Center( - child: OutlineButton( + child: QueryaButton.secondary( + label: _loadingMore ? 'Loading...' : 'Load more (${_keys.length} / $_dbSize)', onPressed: _loadingMore ? null : _loadMore, - size: ButtonSize.small, - child: _loadingMore - ? const Text('Loading...') - : Text('Load more (${_keys.length} / $_dbSize)'), + size: QueryaControlSize.sm, ), ), ); @@ -470,16 +465,16 @@ class _RedisKeysViewState extends material.State { ), ), const Gap(8), - OutlineButton( + QueryaButton.secondary( + label: 'Search', onPressed: _applyFilter, - size: ButtonSize.small, - child: const Text('Search'), + size: QueryaControlSize.sm, ), const Gap(4), - GhostButton( + QueryaButton.ghost( + label: 'Clear', onPressed: _clearFilter, - size: ButtonSize.small, - child: const Text('Clear'), + size: QueryaControlSize.sm, ), material.Container( height: 20, @@ -567,30 +562,25 @@ class _RedisKeysViewState extends material.State { ], ), const Gap(4), - material.Tooltip( - message: _expandedFolders.isEmpty + QueryaButton.icon( + icon: _expandedFolders.isEmpty + ? material.Icons.unfold_more_rounded + : material.Icons.unfold_less_rounded, + tooltip: _expandedFolders.isEmpty ? 'Expand all folders' : 'Collapse all folders', - child: GhostButton( - size: ButtonSize.small, - onPressed: () { - setState(() { - if (_expandedFolders.isEmpty) { - final tree = _buildTree(); - _expandedFolders.addAll( - _collectAllFolderPrefixes(tree.rootFolders)); - } else { - _expandedFolders.clear(); - } - }); - }, - child: material.Icon( - _expandedFolders.isEmpty - ? material.Icons.unfold_more_rounded - : material.Icons.unfold_less_rounded, - size: 16, - ), - ), + size: QueryaControlSize.sm, + onPressed: () { + setState(() { + if (_expandedFolders.isEmpty) { + final tree = _buildTree(); + _expandedFolders.addAll( + _collectAllFolderPrefixes(tree.rootFolders)); + } else { + _expandedFolders.clear(); + } + }); + }, ), ], ], diff --git a/lib/features/redis/redis_view.dart b/lib/features/redis/redis_view.dart index d1099191..74958325 100644 --- a/lib/features/redis/redis_view.dart +++ b/lib/features/redis/redis_view.dart @@ -10,6 +10,7 @@ import 'package:querya_desktop/core/database/redis_service.dart'; import 'package:querya_desktop/core/storage/local_db.dart'; import 'package:querya_desktop/shared/widgets/widgets.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/core/ui/querya_control_tokens.dart'; const _pollInterval = Duration(seconds: 3); const _summaryChipHeight = 88.0; @@ -268,11 +269,11 @@ class _RedisViewState extends material.State { style: material.TextStyle( color: cs.mutedForeground, fontSize: 13)), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: () => unawaited(_load(reconnect: true)), - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -297,11 +298,11 @@ class _RedisViewState extends material.State { const Gap(8), const Text('Redis INFO returned no data.').muted().small(), const Gap(24), - OutlineButton( + QueryaButton.secondary( + label: 'Retry', + icon: material.Icons.refresh_rounded, onPressed: () => unawaited(_load(reconnect: true)), - leading: const material.Icon(material.Icons.refresh_rounded, - size: 18), - child: const Text('Retry'), + size: QueryaControlSize.md, ), ], ), @@ -447,43 +448,39 @@ class _RedisViewState extends material.State { children: [ if (widget.lastSelectedRedisKey != null && widget.onRestoreLastSelectedObject != null) - OutlineButton( + QueryaButton.secondary( + label: 'Return to ${widget.lastSelectedRedisKey}', + icon: material.Icons.vpn_key_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.vpn_key_outlined, - size: 18, - ), - child: Text('Return to ${widget.lastSelectedRedisKey}'), + size: QueryaControlSize.md, ) else if (widget.lastSelectedRedisDb != null && widget.onRestoreLastSelectedObject != null) - OutlineButton( + QueryaButton.secondary( + label: 'Return to db${widget.lastSelectedRedisDb}', + icon: material.Icons.memory_outlined, onPressed: widget.onRestoreLastSelectedObject, - leading: const material.Icon( - material.Icons.memory_outlined, - size: 18, - ), - child: Text('Return to db${widget.lastSelectedRedisDb}'), + size: QueryaControlSize.md, ), if (widget.onBack != null) - OutlineButton( + QueryaButton.secondary( + label: 'Explorer', + icon: material.Icons.grid_view_rounded, onPressed: widget.onBack, - leading: const material.Icon(material.Icons.grid_view_rounded, - size: 18), - child: const Text('Explorer'), + size: QueryaControlSize.md, ), if (widget.onCli != null) - OutlineButton( + QueryaButton.secondary( + label: 'CLI Console', + icon: material.Icons.terminal_rounded, onPressed: widget.onCli, - leading: const material.Icon(material.Icons.terminal_rounded, - size: 18), - child: const Text('CLI Console'), + size: QueryaControlSize.md, ), - OutlineButton( + QueryaButton.secondary( + label: 'Refresh', + icon: material.Icons.refresh_rounded, onPressed: () => unawaited(_refresh()), - leading: - const material.Icon(material.Icons.refresh_rounded, size: 18), - child: const Text('Refresh'), + size: QueryaControlSize.md, ), ], ), diff --git a/test/e2e/04_nosql_workspaces/e2e_mongo_index_manager_test.dart b/test/e2e/04_nosql_workspaces/e2e_mongo_index_manager_test.dart index a155ae23..a9443e79 100644 --- a/test/e2e/04_nosql_workspaces/e2e_mongo_index_manager_test.dart +++ b/test/e2e/04_nosql_workspaces/e2e_mongo_index_manager_test.dart @@ -67,8 +67,7 @@ void main() { expect(find.text('Indexes: orders'), findsOneWidget); expect(find.text('2 indexes'), findsOneWidget); - // The toolbar button of the indexes view (still a shadcn PrimaryButton). - await tester.tap(find.widgetWithText(PrimaryButton, 'Create Index')); + await tester.tap(find.widgetWithText(QueryaButton, 'Create Index')); await tester.pumpAndSettle(); expect(find.text('Collection: orders'), findsOneWidget); diff --git a/test/features/mongodb/mongo_query_workspace_test.dart b/test/features/mongodb/mongo_query_workspace_test.dart index 1db26704..2c7793dc 100644 --- a/test/features/mongodb/mongo_query_workspace_test.dart +++ b/test/features/mongodb/mongo_query_workspace_test.dart @@ -123,7 +123,7 @@ void main() { await tester.pumpAndSettle(); // Click "Run Query" - await tester.tap(find.widgetWithText(PrimaryButton, 'Run Query (Ctrl+Enter)')); + await tester.tap(find.widgetWithText(QueryaButton, 'Run Query (Ctrl+Enter)')); await tester.pumpAndSettle(); expect(fakeExecutor.lastExecutedCommand, isNotNull); @@ -162,7 +162,7 @@ void main() { ); await tester.pumpAndSettle(); - await tester.tap(find.widgetWithText(PrimaryButton, 'Run Query (Ctrl+Enter)')); + await tester.tap(find.widgetWithText(QueryaButton, 'Run Query (Ctrl+Enter)')); await tester.pumpAndSettle(); expect(find.text('Query Error'), findsOneWidget); diff --git a/test/features/nosql/nosql_return_to_object_test.dart b/test/features/nosql/nosql_return_to_object_test.dart index 5b2b4de2..53c09f70 100644 --- a/test/features/nosql/nosql_return_to_object_test.dart +++ b/test/features/nosql/nosql_return_to_object_test.dart @@ -5,6 +5,7 @@ import 'package:querya_desktop/features/main_screen/main_screen_workspace_state. import 'package:querya_desktop/features/mongodb/mongo_stats_view.dart'; import 'package:querya_desktop/features/redis/redis_view.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart' as shadcn; +import 'package:querya_desktop/shared/widgets/querya_button.dart'; void main() { final createdAt = DateTime.utc(2025).toIso8601String(); @@ -75,7 +76,7 @@ void main() { ); final buttonFinder = find.widgetWithText( - shadcn.OutlineButton, + QueryaButton, 'Return to orders', ); expect(buttonFinder, findsOneWidget); @@ -102,7 +103,7 @@ void main() { ); final buttonFinder = find.widgetWithText( - shadcn.OutlineButton, + QueryaButton, 'Return to ecommerce', ); expect(buttonFinder, findsOneWidget); @@ -130,7 +131,7 @@ void main() { ); final buttonFinder = find.widgetWithText( - shadcn.OutlineButton, + QueryaButton, 'Return to cache:config:app', ); expect(buttonFinder, findsOneWidget); @@ -156,7 +157,7 @@ void main() { ); final buttonFinder = find.widgetWithText( - shadcn.OutlineButton, + QueryaButton, 'Return to db5', ); expect(buttonFinder, findsOneWidget);