mirror of
https://github.com/foss42/apidash.git
synced 2025-08-06 13:51:20 +08:00
Merge branch 'foss42:main' into main
This commit is contained in:
@ -23,3 +23,5 @@ final nameTextFieldFocusNodeProvider =
|
||||
});
|
||||
return focusNode;
|
||||
});
|
||||
|
||||
final searchQueryProvider = StateProvider<String>((ref) => '');
|
||||
|
@ -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(
|
||||
child: RequestList(),
|
||||
),
|
||||
@ -109,41 +141,61 @@ class _RequestListState extends ConsumerState<RequestList> {
|
||||
final requestItems = ref.watch(collectionStateNotifierProvider)!;
|
||||
final alwaysShowCollectionPaneScrollbar = ref.watch(settingsProvider
|
||||
.select((value) => value.alwaysShowCollectionPaneScrollbar));
|
||||
final filterQuery = ref.watch(searchQueryProvider).trim();
|
||||
|
||||
return Scrollbar(
|
||||
controller: controller,
|
||||
thumbVisibility: alwaysShowCollectionPaneScrollbar ? true : null,
|
||||
radius: const Radius.circular(12),
|
||||
child: ReorderableListView.builder(
|
||||
padding: kPe8,
|
||||
scrollController: controller,
|
||||
buildDefaultDragHandles: false,
|
||||
itemCount: requestSequence.length,
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
if (oldIndex < newIndex) {
|
||||
newIndex -= 1;
|
||||
}
|
||||
if (oldIndex != newIndex) {
|
||||
ref
|
||||
.read(collectionStateNotifierProvider.notifier)
|
||||
.reorder(oldIndex, newIndex);
|
||||
}
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
var id = requestSequence[index];
|
||||
return ReorderableDragStartListener(
|
||||
key: ValueKey(id),
|
||||
index: index,
|
||||
child: Padding(
|
||||
padding: kP1,
|
||||
child: RequestItem(
|
||||
id: id,
|
||||
requestModel: requestItems[id]!,
|
||||
),
|
||||
child: filterQuery.isEmpty
|
||||
? ReorderableListView.builder(
|
||||
padding: kPe8,
|
||||
scrollController: controller,
|
||||
buildDefaultDragHandles: false,
|
||||
itemCount: requestSequence.length,
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
if (oldIndex < newIndex) {
|
||||
newIndex -= 1;
|
||||
}
|
||||
if (oldIndex != newIndex) {
|
||||
ref
|
||||
.read(collectionStateNotifierProvider.notifier)
|
||||
.reorder(oldIndex, newIndex);
|
||||
}
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
var id = requestSequence[index];
|
||||
return ReorderableDragStartListener(
|
||||
key: ValueKey(id),
|
||||
index: index,
|
||||
child: Padding(
|
||||
padding: kP1,
|
||||
child: RequestItem(
|
||||
id: id,
|
||||
requestModel: requestItems[id]!,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
: 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(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +132,9 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
|
||||
onPressed: () async {
|
||||
var pickedResult = await pickFile();
|
||||
if (pickedResult != null &&
|
||||
pickedResult.files.isNotEmpty &&
|
||||
pickedResult.files.first.path != null) {
|
||||
pickedResult.path.isNotEmpty) {
|
||||
formRows[idx] = formRows[idx].copyWith(
|
||||
value: pickedResult.files.first.path!,
|
||||
value: pickedResult.path,
|
||||
);
|
||||
setState(() {});
|
||||
_onFieldChange(selectedId!);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:mime_dart/mime_dart.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
const uuid = Uuid();
|
||||
|
||||
@ -57,7 +57,7 @@ String getTempFileName() {
|
||||
return getNewUuid();
|
||||
}
|
||||
|
||||
Future<FilePickerResult?> pickFile() async {
|
||||
FilePickerResult? pickedResult = await FilePicker.platform.pickFiles();
|
||||
Future<XFile?> pickFile() async {
|
||||
XFile? pickedResult = await openFile();
|
||||
return pickedResult;
|
||||
}
|
||||
|
@ -94,14 +94,39 @@ class JsonSearchField extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
return RawTextField(
|
||||
controller: controller,
|
||||
onChanged: onChanged,
|
||||
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,
|
||||
border: InputBorder.none,
|
||||
hintText: 'Search..',
|
||||
hintText: hintText,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
80
pubspec.lock
80
pubspec.lock
@ -209,6 +209,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.2"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.4+1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -289,14 +297,70 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
file_picker:
|
||||
file_selector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: caa6bc229eab3e32eb2f37b53a5f9d22a6981474afd210c512a7546c1e1a04f6
|
||||
name: file_selector
|
||||
sha256: "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "1.0.3"
|
||||
file_selector_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_android
|
||||
sha256: "1cd66575f063b689e041aec836905ba7be18d76c9f0634d0d75daec825f67095"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0+7"
|
||||
file_selector_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_ios
|
||||
sha256: b015154e6d9fddbc4d08916794df170b44531798c8dd709a026df162d07ad81d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1+8"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_linux
|
||||
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.2+1"
|
||||
file_selector_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_macos
|
||||
sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+3"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
file_selector_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_web
|
||||
sha256: "619e431b224711a3869e30dbd7d516f5f5a4f04b265013a50912f39e1abc88c8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4+1"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -382,14 +446,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.21"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.17"
|
||||
flutter_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -49,13 +49,13 @@ dependencies:
|
||||
url: https://github.com/foss42/json_data_explorer.git
|
||||
ref: b7dde2f85dff4f482eed7eda4ef2a71344ef8b3a
|
||||
scrollable_positioned_list: ^0.3.8
|
||||
file_picker: ^6.2.0
|
||||
flutter_svg: ^2.0.10+1
|
||||
vector_graphics_compiler: ^1.1.9+1
|
||||
code_builder: ^4.10.0
|
||||
dart_style: ^2.3.6
|
||||
json_text_field: ^1.1.0
|
||||
csv: ^6.0.0
|
||||
file_selector: ^1.0.3
|
||||
|
||||
dependency_overrides:
|
||||
web: ^0.5.0
|
||||
|
@ -214,13 +214,13 @@ void main() {
|
||||
});
|
||||
|
||||
group("Testing selectedIdEditStateProvider", () {
|
||||
testWidgets(
|
||||
'selectedIdEditStateProvider should have an initial value of null',
|
||||
(tester) async {
|
||||
testWidgets('It should have an initial value of null', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
const ProviderScope(
|
||||
child: MaterialApp(
|
||||
home: CollectionPane(),
|
||||
home: Scaffold(
|
||||
body: CollectionPane(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -237,7 +237,9 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
const ProviderScope(
|
||||
child: MaterialApp(
|
||||
home: CollectionPane(),
|
||||
home: Scaffold(
|
||||
body: CollectionPane(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -267,7 +269,9 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
const ProviderScope(
|
||||
child: MaterialApp(
|
||||
home: CollectionPane(),
|
||||
home: Scaffold(
|
||||
body: CollectionPane(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -303,7 +307,9 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
const ProviderScope(
|
||||
child: MaterialApp(
|
||||
home: CollectionPane(),
|
||||
home: Scaffold(
|
||||
body: CollectionPane(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user