Skip to content

Commit fb3986f

Browse files
authored
[Property Editor] Add filters for set and default values (#9083)
1 parent a77b33e commit fb3986f

File tree

3 files changed

+95
-4
lines changed

3 files changed

+95
-4
lines changed

packages/devtools_app/lib/src/shared/ui/filter.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ mixin FilterControllerMixin<T> on DisposableController
193193
/// the filter state.
194194
class FilterDialog<T> extends StatefulWidget {
195195
FilterDialog({super.key, required this.controller})
196-
: assert(controller.queryFilterArgs.isNotEmpty),
197-
settingFilterValuesAtOpen = List.generate(
196+
: settingFilterValuesAtOpen = List.generate(
198197
controller.activeFilter.value.settingFilters.length,
199198
(index) =>
200199
controller.activeFilter.value.settingFilters[index].setting.value,
@@ -288,7 +287,7 @@ class _ToggleFilterElement extends StatelessWidget {
288287
child: Row(
289288
children: [
290289
NotifierCheckbox(notifier: filter.setting),
291-
Text(filter.name),
290+
Expanded(child: Text(filter.name)),
292291
],
293292
),
294293
);

packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_controller.dart

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ class PropertyEditorController extends DisposableController
6868

6969
static const _checkConnectionInterval = Duration(minutes: 1);
7070

71+
static const _setPropertiesFilterId = 'set-properties-filter';
72+
73+
@visibleForTesting
74+
static final propertyFilters = <SettingFilter<EditableProperty, Object>>[
75+
ToggleFilter<EditableProperty>(
76+
id: _setPropertiesFilterId,
77+
name: 'Only include properties that are set in the code.',
78+
includeCallback: (property) => property.hasArgument,
79+
defaultValue: false,
80+
),
81+
];
82+
7183
@override
7284
void init() {
7385
super.init();
@@ -124,11 +136,17 @@ class PropertyEditorController extends DisposableController
124136
super.dispose();
125137
}
126138

139+
/// The setting filters available for the Property Editor.
140+
@override
141+
SettingFilters<EditableProperty> createSettingFilters() => propertyFilters;
142+
127143
@override
128144
void filterData(Filter<EditableProperty> filter) {
129145
super.filterData(filter);
130146
final filtered = (_editableWidgetData.value?.properties ?? []).where(
131-
(property) => property.matchesQuery(filter.queryFilter.query),
147+
(property) =>
148+
property.matchesQuery(filter.queryFilter.query) &&
149+
!_filteredOutBySettings(property, filter: filter),
132150
);
133151
filteredData
134152
..clear()
@@ -220,6 +238,13 @@ class PropertyEditorController extends DisposableController
220238
});
221239
}
222240

241+
bool _filteredOutBySettings(
242+
EditableProperty property, {
243+
required Filter filter,
244+
}) => filter.settingFilters.any(
245+
(settingFilter) => !settingFilter.includeData(property),
246+
);
247+
223248
@visibleForTesting
224249
void initForTestsOnly({
225250
EditableArgumentsResult? editableArgsResult,

packages/devtools_app/test/standalone_ui/ide_shared/property_editor/property_editor_test.dart

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,16 @@ void main() {
439439
});
440440

441441
group('filtering editable arguments', () {
442+
void resetFilters() {
443+
for (final filter in controller.settingFilters) {
444+
filter.setting.value = filter.defaultValue;
445+
}
446+
}
447+
448+
tearDown(() {
449+
resetFilters();
450+
});
451+
442452
testWidgets('can filter by name', (tester) async {
443453
// Load the property editor.
444454
await tester.pumpWidget(wrap(propertyEditor));
@@ -525,6 +535,36 @@ void main() {
525535
expect(widthInput, findsNothing);
526536
expect(heightInput, findsNothing);
527537
});
538+
539+
testWidgets('can filter for only set values', (tester) async {
540+
// Load the property editor.
541+
await tester.pumpWidget(wrap(propertyEditor));
542+
543+
// Change the editable args.
544+
controller.initForTestsOnly(editableArgsResult: result1);
545+
await tester.pumpAndSettle();
546+
547+
final titleInput = _findTextFormField('String? title');
548+
final widthInput = _findTextFormField('double width');
549+
final heightInput = _findTextFormField('double? height');
550+
551+
// Verify all inputs are visible.
552+
expect(_findNoPropertiesMessage, findsNothing);
553+
expect(titleInput, findsOneWidget);
554+
expect(widthInput, findsOneWidget);
555+
expect(heightInput, findsOneWidget);
556+
557+
// Filter for only set vaues.
558+
await _setFilter(
559+
'Only include properties that are set in the code.',
560+
tester: tester,
561+
);
562+
563+
// Verify only the "title" and "width" properties are visible.
564+
expect(heightInput, findsNothing);
565+
expect(titleInput, findsOneWidget);
566+
expect(widthInput, findsOneWidget);
567+
});
528568
});
529569

530570
group('editing arguments', () {
@@ -952,6 +992,33 @@ final _findNoPropertiesMessage = find.text(
952992
'No widget properties at current cursor location.',
953993
);
954994

995+
Future<void> _setFilter(
996+
String filterSettingText, {
997+
required WidgetTester tester,
998+
}) async {
999+
// Click the filter button.
1000+
final filterButtonFinder = find.byType(DevToolsFilterButton);
1001+
await tester.tap(filterButtonFinder);
1002+
await tester.pumpAndSettle();
1003+
1004+
// Find the checkbox for the filter and click it.
1005+
final rowFinder = find.ancestor(
1006+
of: find.textContaining(filterSettingText),
1007+
matching: find.byType(Row),
1008+
);
1009+
final checkboxFinder = find.descendant(
1010+
of: rowFinder,
1011+
matching: find.byType(NotifierCheckbox),
1012+
);
1013+
await tester.tap(checkboxFinder);
1014+
await tester.pumpAndSettle();
1015+
1016+
// Click "Apply" to apply the filter and close the dialog.
1017+
final applyFilterButtonFinder = find.byType(DialogApplyButton);
1018+
await tester.tap(applyFilterButtonFinder);
1019+
await tester.pumpAndSettle();
1020+
}
1021+
9551022
Finder _findFilterField() => find.descendant(
9561023
of: find.byType(StandaloneFilterField<EditableProperty>),
9571024
matching: find.byType(TextField),

0 commit comments

Comments
 (0)