Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions lib/features/mongodb/mongo_document_tree_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:convert';
import 'package:flutter/material.dart' as material;
import 'package:flutter/services.dart';
import 'package:mongo_dart/mongo_dart.dart' show ObjectId;
import 'package:querya_desktop/core/theme/querya_semantic_palette.dart';
import 'package:querya_desktop/core/theme/querya_theme_scope.dart';
import 'package:querya_desktop/core/theme/querya_typography.dart';
import 'package:querya_desktop/features/mongodb/mongo_ejson.dart';
import 'package:querya_desktop/features/mongodb/mongo_field_codec.dart';
Expand Down Expand Up @@ -599,7 +601,8 @@ class _MongoDocumentTreeViewState extends State<MongoDocumentTreeView> {
}) {
final keyLabel = keyOrIndex is int ? '[$keyOrIndex]' : keyOrIndex.toString();
final valueDisplay = _formatLeafDisplay(value);
final valueColor = _leafValueColor(value, cs);
final palette = context.semanticPalette;
final valueColor = _leafValueColor(value, cs, palette);
final typeName = _leafTypeName(value);

final isMatch = _searchQuery.isNotEmpty &&
Expand Down Expand Up @@ -705,13 +708,17 @@ class _MongoDocumentTreeViewState extends State<MongoDocumentTreeView> {
return value.toString();
}

Color _leafValueColor(Object? value, ColorScheme cs) {
if (value == null) return cs.mutedForeground;
if (value is String) return const Color(0xFF22C55E); // Green
if (value is num) return const Color(0xFF3B82F6); // Blue
if (value is bool) return const Color(0xFFF97316); // Orange
if (value is ObjectId) return cs.primary; // Primary / Purple
if (value is DateTime) return const Color(0xFF06B6D4); // Cyan
Color _leafValueColor(
Object? value,
ColorScheme cs,
QueryaSemanticPalette palette,
) {
if (value == null) return palette.muted;
if (value is String) return palette.type1;
if (value is num) return palette.type2;
if (value is bool) return palette.type3;
if (value is ObjectId) return cs.primary;
if (value is DateTime) return palette.type4;
return cs.foreground;
}

Expand Down
8 changes: 2 additions & 6 deletions lib/features/workspace/destructive_query_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,7 @@ class _DestructiveQueryDialogState
child: material.Container(
padding: const material.EdgeInsets.all(12),
decoration: material.BoxDecoration(
color: isDark
? const material.Color(0xFF141416)
: const material.Color(0xFFF4F4F6),
color: context.workbench.editorBackground,
borderRadius: material.BorderRadius.circular(8),
border: material.Border.all(
color: cs.border.withValues(alpha: 0.6),
Expand All @@ -279,9 +277,7 @@ class _DestructiveQueryDialogState
QueryaTypography.monoFontFamilyFallback,
fontSize: 12.5,
height: 1.45,
color: isDark
? const material.Color(0xFFE2E8F0)
: const material.Color(0xFF1E293B),
color: cs.foreground,
),
),
),
Expand Down
8 changes: 2 additions & 6 deletions lib/features/workspace/dml_preview_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> {
child: material.Container(
padding: const material.EdgeInsets.all(12),
decoration: material.BoxDecoration(
color: isDark
? const material.Color(0xFF141416)
: const material.Color(0xFFF4F4F6),
color: context.workbench.editorBackground,
borderRadius: material.BorderRadius.circular(8),
border: material.Border.all(
color: cs.border.withValues(alpha: 0.6),
Expand All @@ -276,9 +274,7 @@ class _DmlPreviewDialogState extends material.State<_DmlPreviewDialog> {
QueryaTypography.monoFontFamilyFallback,
fontSize: 12.5,
height: 1.45,
color: isDark
? const material.Color(0xFFE2E8F0)
: const material.Color(0xFF1E293B),
color: cs.foreground,
),
),
),
Expand Down
51 changes: 51 additions & 0 deletions test/features/mongodb/mongo_documents_view_modes_test.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'package:flutter/material.dart' as material;
import 'package:flutter_test/flutter_test.dart';
import 'package:mongo_dart/mongo_dart.dart' show ObjectId;
import 'package:querya_desktop/core/editor/querya_code_editor.dart';
import 'package:querya_desktop/core/editor/querya_highlight_controller.dart';
import 'package:querya_desktop/core/editor/syntax_highlight_service.dart';
import 'package:querya_desktop/core/theme/querya_semantic_palette.dart';
import 'package:querya_desktop/core/theme/querya_theme.dart';
import 'package:querya_desktop/features/mongodb/mongo_document_tree_view.dart';
import 'package:querya_desktop/features/mongodb/mongo_documents_json_view.dart';
import 'package:querya_desktop/features/mongodb/mongo_documents_table_view.dart';
Expand Down Expand Up @@ -193,6 +196,54 @@ void main() {
await tester.pumpAndSettle();
expect(find.text('address'), findsOneWidget);
});

testWidgets('colors leaf values using semantic palette tokens (#1644)',
(tester) async {
final id = ObjectId.fromHexString('507f1f77bcf86cd799439011');
final date = DateTime.utc(2026, 1, 1);
final docs = [
{
'_id': id,
'strField': 'hello',
'numField': 42,
'boolField': true,
'dateField': date,
'nullField': null,
},
];

const theme = QueryaTheme.darkDefault;
final palette = QueryaSemanticPalette.fromTheme(theme);

await tester.pumpWidget(
queryaThemeTestShell(
data: theme,
child: MongoDocumentTreeView(
documents: docs,
),
),
);
await tester.pumpAndSettle();

final strText = tester.widget<material.Text>(find.text('"hello"'));
expect(strText.style?.color, palette.type1);

final numText = tester.widget<material.Text>(find.text('42'));
expect(numText.style?.color, palette.type2);

final boolText = tester.widget<material.Text>(find.text('true'));
expect(boolText.style?.color, palette.type3);

final nullText = tester.widget<material.Text>(
find.byWidgetPredicate(
(w) =>
w is material.Text &&
w.data == 'null' &&
w.style?.fontStyle == material.FontStyle.italic,
),
);
expect(nullText.style?.color, palette.muted);
});
});

group('MongoDocumentsJsonView widget', () {
Expand Down
55 changes: 55 additions & 0 deletions test/features/workspace/destructive_query_dialog_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart' as material;
import 'package:flutter_test/flutter_test.dart';
import 'package:querya_desktop/core/database/destructive_sql_detector.dart';
import 'package:querya_desktop/core/theme/querya_theme.dart';
import 'package:querya_desktop/features/workspace/destructive_query_dialog.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart' hide TextExtension;

Expand Down Expand Up @@ -275,5 +276,59 @@ void main() {
await tester.pumpAndSettle();
expect(confirmed, isTrue);
});

testWidgets(
'SQL preview uses workbench editorBackground and foreground (#1644)',
(tester) async {
await tester.binding.setSurfaceSize(const Size(800, 700));
final inspection =
DestructiveSqlDetector.inspect('DROP TABLE legacy_users;');

material.Widget buildDialog(QueryaTheme theme) => queryaThemeTestShell(
data: theme,
child: material.Builder(
builder: (context) => material.ElevatedButton(
onPressed: () => showDestructiveQueryDialog(
context: context,
result: inspection,
sql: 'DROP TABLE legacy_users;',
),
child: const material.Text('Open'),
),
),
);

// Light theme verification
await tester.pumpWidget(buildDialog(QueryaTheme.lightDefault));
await tester.tap(find.text('Open'));
await tester.pumpAndSettle();

final selectableTextFinder = find.widgetWithText(
material.SelectableText,
'DROP TABLE legacy_users;',
);
expect(selectableTextFinder, findsOneWidget);

final container = tester.widget<material.Container>(
find
.ancestor(
of: selectableTextFinder,
matching: find.byType(material.Container),
)
.first,
);
final deco = container.decoration! as material.BoxDecoration;
expect(
deco.color,
QueryaTheme.lightDefault.workbench.editorBackground,
);

final selectableText =
tester.widget<material.SelectableText>(selectableTextFinder);
expect(
selectableText.style?.color,
QueryaTheme.lightDefault.colorScheme.foreground,
);
});
});
}
43 changes: 42 additions & 1 deletion test/features/workspace/dml_preview_dialog_test.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import 'package:flutter/material.dart' as material;
import 'package:flutter_test/flutter_test.dart';
import 'package:querya_desktop/core/database/table_mutation_engine.dart';
import 'package:querya_desktop/core/theme/querya_theme.dart';
import 'package:querya_desktop/features/workspace/dml_preview_dialog.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart' hide TextExtension;

import '../../support/querya_theme_test_shell.dart';

void main() {
material.Widget buildTestDialog({required TableMutationPlan plan, void Function(bool?)? onResult}) {
material.Widget buildTestDialog({
required TableMutationPlan plan,
void Function(bool?)? onResult,
QueryaTheme data = QueryaTheme.darkDefault,
}) {
return queryaThemeTestShell(
data: data,
child: material.Material(
child: material.Builder(
builder: (context) {
Expand Down Expand Up @@ -123,5 +129,40 @@ void main() {

expect(find.textContaining('No Primary Key detected'), findsOneWidget);
});

testWidgets(
'SQL preview uses workbench editorBackground and foreground (#1644)',
(tester) async {
await tester.pumpWidget(buildTestDialog(
plan: samplePlan,
data: QueryaTheme.lightDefault,
));
await tester.tap(find.text('Open Dialog'));
await tester.pumpAndSettle();

final selectableTextFinder = find.byType(material.SelectableText);
expect(selectableTextFinder, findsOneWidget);

final container = tester.widget<material.Container>(
find
.ancestor(
of: selectableTextFinder,
matching: find.byType(material.Container),
)
.first,
);
final deco = container.decoration! as material.BoxDecoration;
expect(
deco.color,
QueryaTheme.lightDefault.workbench.editorBackground,
);

final selectableText =
tester.widget<material.SelectableText>(selectableTextFinder);
expect(
selectableText.style?.color,
QueryaTheme.lightDefault.colorScheme.foreground,
);
});
});
}
Loading