diff --git a/lib/screens/home_page/collection_pane.dart b/lib/screens/home_page/collection_pane.dart index 7e2f806e..521fdad8 100644 --- a/lib/screens/home_page/collection_pane.dart +++ b/lib/screens/home_page/collection_pane.dart @@ -37,8 +37,14 @@ class CollectionPane extends ConsumerWidget { }, onImport: () { showImportDialog( - context, - (file) { + context: context, + importFormat: ref.watch(importFormatStateProvider), + onImportFormatChange: (format) { + if (format != null) { + ref.read(importFormatStateProvider.notifier).state = format; + } + }, + onFileDropped: (file) { final importFormatType = ref.read(importFormatStateProvider); file.readAsString().then((content) { kImporter diff --git a/lib/widgets/dialog_import.dart b/lib/widgets/dialog_import.dart index 0ad328ed..24b6b933 100644 --- a/lib/widgets/dialog_import.dart +++ b/lib/widgets/dialog_import.dart @@ -1,18 +1,37 @@ +import 'package:apidash/consts.dart'; import 'package:flutter/material.dart'; import 'package:file_selector/file_selector.dart'; import 'drag_and_drop_area.dart'; +import 'dropdown_import_format.dart'; -showImportDialog( - BuildContext context, - Function(XFile) onFileDropped, -) { +showImportDialog({ + required BuildContext context, + required ImportFormat importFormat, + Function(ImportFormat?)? onImportFormatChange, + Function(XFile)? onFileDropped, +}) { showDialog( context: context, builder: (context) { return AlertDialog( contentPadding: const EdgeInsets.all(12), - content: DragAndDropArea( - onFileDropped: onFileDropped, + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text("Import "), + DropdownButtonImportFormat( + importFormat: importFormat, + onChanged: onImportFormatChange, + ), + ], + ), + DragAndDropArea( + onFileDropped: onFileDropped, + ), + ], ), ); }, diff --git a/lib/widgets/drag_and_drop_area.dart b/lib/widgets/drag_and_drop_area.dart index fb2c7bf2..1babea8b 100644 --- a/lib/widgets/drag_and_drop_area.dart +++ b/lib/widgets/drag_and_drop_area.dart @@ -1,11 +1,16 @@ +import 'package:flutter/material.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:file_selector/file_selector.dart'; -import 'package:flutter/material.dart'; +import 'package:apidash/utils/utils.dart'; +import 'package:apidash/consts.dart'; class DragAndDropArea extends StatefulWidget { - final Function(XFile) onFileDropped; + final Function(XFile)? onFileDropped; - const DragAndDropArea({super.key, required this.onFileDropped}); + const DragAndDropArea({ + super.key, + this.onFileDropped, + }); @override State createState() => _DragAndDropAreaState(); @@ -22,7 +27,7 @@ class _DragAndDropAreaState extends State { setState(() { _list.addAll(detail.files); }); - widget.onFileDropped(detail.files[0]); + widget.onFileDropped?.call(detail.files[0]); }, onDragEntered: (detail) { setState(() { @@ -47,7 +52,41 @@ class _DragAndDropAreaState extends State { width: 600, height: 400, child: _list.isEmpty - ? const Center(child: Text("Select or drop the file here")) + ? Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 150, + child: ElevatedButton.icon( + icon: const Icon( + Icons.snippet_folder_rounded, + size: 20, + ), + style: ElevatedButton.styleFrom( + minimumSize: const Size.fromHeight(kDataTableRowHeight), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + onPressed: () async { + var pickedResult = await pickFile(); + if (pickedResult != null && + pickedResult.path.isNotEmpty) { + widget.onFileDropped?.call(pickedResult); + } + }, + label: const Text( + kLabelSelectFile, + overflow: TextOverflow.ellipsis, + style: kFormDataButtonLabelTextStyle, + ), + ), + ), + kVSpacer10, + const Text("Select or drop the file here"), + ], + )) : Text(_list.map((e) => e.path).join("\n")), ), ); diff --git a/lib/widgets/dropdown_import_format.dart b/lib/widgets/dropdown_import_format.dart new file mode 100644 index 00000000..277b92b6 --- /dev/null +++ b/lib/widgets/dropdown_import_format.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:apidash/consts.dart'; + +class DropdownButtonImportFormat extends StatelessWidget { + const DropdownButtonImportFormat({ + super.key, + required this.importFormat, + this.onChanged, + }); + + final ImportFormat importFormat; + final void Function(ImportFormat?)? onChanged; + + @override + Widget build(BuildContext context) { + final surfaceColor = Theme.of(context).colorScheme.surface; + return DropdownButton( + isExpanded: false, + focusColor: surfaceColor, + value: importFormat, + icon: const Icon( + Icons.unfold_more_rounded, + size: 16, + ), + elevation: 4, + style: kCodeStyle.copyWith( + color: Theme.of(context).colorScheme.primary, + ), + underline: Container( + height: 0, + ), + onChanged: onChanged, + borderRadius: kBorderRadius12, + items: ImportFormat.values + .map>((ImportFormat value) { + return DropdownMenuItem( + value: value, + child: Padding( + padding: kPs8, + child: Text( + value.label, + style: kTextStyleButton, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + ); + }).toList(), + ); + } +} diff --git a/lib/widgets/widgets.dart b/lib/widgets/widgets.dart index cfc23ea1..b22ef4e8 100644 --- a/lib/widgets/widgets.dart +++ b/lib/widgets/widgets.dart @@ -18,6 +18,7 @@ export 'dropdown_codegen.dart'; export 'dropdown_content_type.dart'; export 'dropdown_formdata.dart'; export 'dropdown_http_method.dart'; +export 'dropdown_import_format.dart'; export 'editor_json.dart'; export 'editor.dart'; export 'error_message.dart'; diff --git a/test/widgets/drag_and_drop_area_test.dart b/test/widgets/drag_and_drop_area_test.dart index 75c5cc94..ca791386 100644 --- a/test/widgets/drag_and_drop_area_test.dart +++ b/test/widgets/drag_and_drop_area_test.dart @@ -32,7 +32,7 @@ void main() { // Since we can't actually perform drag-and-drop in a unit test, // we'll call the onDragDone callback directly - dragAndDropArea.onFileDropped(testFile); + dragAndDropArea.onFileDropped?.call(testFile); await tester.pump(); @@ -42,4 +42,3 @@ void main() { expect(droppedFile?.path, 'test.curl'); }); } -