Merge pull request #347 from sudhar08/feat-Add-a-search/filter-for-collection-pane-#305-

feat: Add a search/filter for collection pane
This commit is contained in:
Ankit Mahato
2024-03-24 03:23:44 +05:30
committed by GitHub
4 changed files with 125 additions and 40 deletions

View File

@ -23,3 +23,5 @@ final nameTextFieldFocusNodeProvider =
}); });
return focusNode; return focusNode;
}); });
final searchQueryProvider = StateProvider<String>((ref) => '');

View File

@ -69,7 +69,39 @@ class CollectionPane extends ConsumerWidget {
], ],
), ),
), ),
kVSpacer8, kVSpacer10,
Container(
height: 30,
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: kBorderRadius8,
border: Border.all(
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
child: Row(
children: [
kHSpacer5,
Icon(
Icons.filter_alt,
size: 18,
color: Theme.of(context).colorScheme.secondary,
),
kHSpacer5,
Expanded(
child: RawTextField(
style: Theme.of(context).textTheme.bodyMedium,
hintText: "Filter by name or URL",
onChanged: (value) {
ref.read(searchQueryProvider.notifier).state =
value.toLowerCase();
},
),
),
],
),
),
kVSpacer10,
const Expanded( const Expanded(
child: RequestList(), child: RequestList(),
), ),
@ -109,12 +141,14 @@ class _RequestListState extends ConsumerState<RequestList> {
final requestItems = ref.watch(collectionStateNotifierProvider)!; final requestItems = ref.watch(collectionStateNotifierProvider)!;
final alwaysShowCollectionPaneScrollbar = ref.watch(settingsProvider final alwaysShowCollectionPaneScrollbar = ref.watch(settingsProvider
.select((value) => value.alwaysShowCollectionPaneScrollbar)); .select((value) => value.alwaysShowCollectionPaneScrollbar));
final filterQuery = ref.watch(searchQueryProvider).trim();
return Scrollbar( return Scrollbar(
controller: controller, controller: controller,
thumbVisibility: alwaysShowCollectionPaneScrollbar ? true : null, thumbVisibility: alwaysShowCollectionPaneScrollbar ? true : null,
radius: const Radius.circular(12), radius: const Radius.circular(12),
child: ReorderableListView.builder( child: filterQuery.isEmpty
? ReorderableListView.builder(
padding: kPe8, padding: kPe8,
scrollController: controller, scrollController: controller,
buildDefaultDragHandles: false, buildDefaultDragHandles: false,
@ -143,6 +177,24 @@ class _RequestListState extends ConsumerState<RequestList> {
), ),
); );
}, },
)
: ListView(
padding: kPe8,
controller: controller,
children: requestSequence.map((id) {
var item = requestItems[id]!;
if (item.url.toLowerCase().contains(filterQuery) ||
item.name.toLowerCase().contains(filterQuery)) {
return Padding(
padding: kP1,
child: RequestItem(
id: id,
requestModel: item,
),
);
}
return const SizedBox();
}).toList(),
), ),
); );
} }

View File

@ -94,14 +94,39 @@ class JsonSearchField extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextField( return RawTextField(
controller: controller, controller: controller,
onChanged: onChanged, onChanged: onChanged,
style: kCodeStyle, style: kCodeStyle,
decoration: const InputDecoration( hintText: 'Search..',
);
}
}
class RawTextField extends StatelessWidget {
const RawTextField({
super.key,
this.onChanged,
this.controller,
this.hintText,
this.style,
});
final void Function(String)? onChanged;
final TextEditingController? controller;
final String? hintText;
final TextStyle? style;
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
onChanged: onChanged,
style: style,
decoration: InputDecoration(
isDense: true, isDense: true,
border: InputBorder.none, border: InputBorder.none,
hintText: 'Search..', hintText: hintText,
), ),
); );
} }

View File

@ -214,13 +214,13 @@ void main() {
}); });
group("Testing selectedIdEditStateProvider", () { group("Testing selectedIdEditStateProvider", () {
testWidgets( testWidgets('It should have an initial value of null', (tester) async {
'selectedIdEditStateProvider should have an initial value of null',
(tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const ProviderScope( const ProviderScope(
child: MaterialApp( child: MaterialApp(
home: CollectionPane(), home: Scaffold(
body: CollectionPane(),
),
), ),
), ),
); );
@ -237,7 +237,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
const ProviderScope( const ProviderScope(
child: MaterialApp( child: MaterialApp(
home: CollectionPane(), home: Scaffold(
body: CollectionPane(),
),
), ),
), ),
); );
@ -267,7 +269,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
const ProviderScope( const ProviderScope(
child: MaterialApp( child: MaterialApp(
home: CollectionPane(), home: Scaffold(
body: CollectionPane(),
),
), ),
), ),
); );
@ -303,7 +307,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
const ProviderScope( const ProviderScope(
child: MaterialApp( child: MaterialApp(
home: CollectionPane(), home: Scaffold(
body: CollectionPane(),
),
), ),
), ),
); );