mirror of
https://github.com/foss42/apidash.git
synced 2025-12-01 18:28:25 +08:00
feat: add search functionality to opeanapi operation picker dialog
This commit is contained in:
@@ -40,12 +40,24 @@ Future<List<OpenApiOperationItem>?> showOpenApiOperationPickerDialog({
|
|||||||
// Multi-select: default select all
|
// Multi-select: default select all
|
||||||
final selected = <int>{for (var i = 0; i < ops.length; i++) i};
|
final selected = <int>{for (var i = 0; i < ops.length; i++) i};
|
||||||
bool selectAll = ops.isNotEmpty;
|
bool selectAll = ops.isNotEmpty;
|
||||||
|
String searchQuery = '';
|
||||||
|
|
||||||
return showDialog<List<OpenApiOperationItem>>(
|
return showDialog<List<OpenApiOperationItem>>(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
builder: (ctx) {
|
builder: (ctx) {
|
||||||
return StatefulBuilder(builder: (ctx, setState) {
|
return StatefulBuilder(builder: (ctx, setState) {
|
||||||
|
// Filter operations based on search query
|
||||||
|
final filteredOps = <int>[];
|
||||||
|
for (int i = 0; i < ops.length; i++) {
|
||||||
|
final o = ops[i];
|
||||||
|
final label = '${o.method} ${o.path}'.toLowerCase();
|
||||||
|
if (searchQuery.isEmpty ||
|
||||||
|
label.contains(searchQuery.toLowerCase())) {
|
||||||
|
filteredOps.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text('Import from $title'),
|
title: Text('Import from $title'),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
@@ -54,13 +66,25 @@ Future<List<OpenApiOperationItem>?> showOpenApiOperationPickerDialog({
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
ExpansionTile(
|
// TODO: Create a Search field widget
|
||||||
initiallyExpanded: true,
|
|
||||||
title: const Text('Available routes'),
|
|
||||||
children: [
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.only(bottom: 16.0),
|
||||||
child: CheckboxListTile(
|
child: TextField(
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
searchQuery = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Search routes',
|
||||||
|
hintText: 'Type to filter routes...',
|
||||||
|
prefixIcon: Icon(Icons.search),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Select all checkbox
|
||||||
|
CheckboxListTile(
|
||||||
value: selectAll,
|
value: selectAll,
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -75,12 +99,12 @@ Future<List<OpenApiOperationItem>?> showOpenApiOperationPickerDialog({
|
|||||||
title: const Text('Select all'),
|
title: const Text('Select all'),
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
),
|
),
|
||||||
),
|
// Routes list
|
||||||
SizedBox(
|
Expanded(
|
||||||
height: 300,
|
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: ops.length,
|
itemCount: filteredOps.length,
|
||||||
itemBuilder: (c, i) {
|
itemBuilder: (c, index) {
|
||||||
|
final i = filteredOps[index];
|
||||||
final o = ops[i];
|
final o = ops[i];
|
||||||
final label = '${o.method} ${o.path}';
|
final label = '${o.method} ${o.path}';
|
||||||
final checked = selected.contains(i);
|
final checked = selected.contains(i);
|
||||||
@@ -104,8 +128,6 @@ Future<List<OpenApiOperationItem>?> showOpenApiOperationPickerDialog({
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|||||||
Reference in New Issue
Block a user