From a91e1e0aecb5b5cc3a4aa9cf5f23e36e31d68cd5 Mon Sep 17 00:00:00 2001 From: Udhay-Adithya Date: Mon, 23 Jun 2025 22:48:03 +0530 Subject: [PATCH] feat: add scripts tab to request history --- .../history_widgets/his_request_pane.dart | 10 +++ .../history_widgets/his_scripts_tab.dart | 80 +++++++++++++++++++ lib/widgets/scripts_editor_pane.dart | 8 +- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 lib/screens/history/history_widgets/his_scripts_tab.dart diff --git a/lib/screens/history/history_widgets/his_request_pane.dart b/lib/screens/history/history_widgets/his_request_pane.dart index f1435063..eaa7faff 100644 --- a/lib/screens/history/history_widgets/his_request_pane.dart +++ b/lib/screens/history/history_widgets/his_request_pane.dart @@ -1,3 +1,4 @@ +import 'package:apidash/screens/history/history_widgets/his_scripts_tab.dart'; import 'package:apidash_core/apidash_core.dart'; import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; @@ -38,6 +39,12 @@ class HistoryRequestPane extends ConsumerWidget { .select((value) => value?.httpRequestModel.hasQuery)) ?? false; + final scriptsLength = ref.watch(selectedHistoryRequestModelProvider + .select((value) => value?.preRequestScript.length)) ?? + ref.watch(selectedRequestModelProvider + .select((value) => value?.postRequestScript.length)) ?? + 0; + return switch (apiType) { APIType.rest => RequestPane( key: const Key("history-request-pane-rest"), @@ -52,11 +59,13 @@ class HistoryRequestPane extends ConsumerWidget { paramLength > 0, headerLength > 0, hasBody, + scriptsLength > 0 ], tabLabels: const [ kLabelURLParams, kLabelHeaders, kLabelBody, + kLabelScripts, ], children: [ RequestDataTable( @@ -68,6 +77,7 @@ class HistoryRequestPane extends ConsumerWidget { keyName: kNameHeader, ), const HisRequestBody(), + const HistoryScriptsTab(), ], ), APIType.graphql => RequestPane( diff --git a/lib/screens/history/history_widgets/his_scripts_tab.dart b/lib/screens/history/history_widgets/his_scripts_tab.dart new file mode 100644 index 00000000..cf5e01ea --- /dev/null +++ b/lib/screens/history/history_widgets/his_scripts_tab.dart @@ -0,0 +1,80 @@ +import 'package:apidash/widgets/scripts_editor_pane.dart'; +import 'package:apidash_design_system/apidash_design_system.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_code_editor/flutter_code_editor.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:highlight/languages/javascript.dart'; +import 'package:apidash/providers/providers.dart'; + +class HistoryScriptsTab extends ConsumerStatefulWidget { + const HistoryScriptsTab({super.key}); + + @override + ConsumerState createState() => _ScriptsCodePaneState(); +} + +class _ScriptsCodePaneState extends ConsumerState { + int _selectedTabIndex = 0; + @override + Widget build(BuildContext context) { + final hisRequestModel = ref.read(selectedHistoryRequestModelProvider); + + final preReqCodeController = CodeController( + text: hisRequestModel?.preRequestScript, + language: javascript, + ); + + final postResCodeController = CodeController( + text: hisRequestModel?.postRequestScript, + language: javascript, + ); + + preReqCodeController.addListener(() { + ref.read(collectionStateNotifierProvider.notifier).update( + preRequestScript: preReqCodeController.text, + ); + }); + + postResCodeController.addListener(() { + ref.read(collectionStateNotifierProvider.notifier).update( + postRequestScript: postResCodeController.text, + ); + }); + + final tabs = [(0, "Pre Request"), (1, "Post Response")]; + final content = [ + ScriptsEditorPane( + controller: preReqCodeController, + readOnly: true, + ), + ScriptsEditorPane( + controller: postResCodeController, + readOnly: true, + ), + ]; + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: ADDropdownButton( + value: _selectedTabIndex, + values: tabs, + onChanged: (int? newValue) { + if (newValue != null) { + setState(() { + _selectedTabIndex = newValue; + }); + } + }, + ), + ), + Expanded( + child: content[_selectedTabIndex], + ), + ], + ); + } +} diff --git a/lib/widgets/scripts_editor_pane.dart b/lib/widgets/scripts_editor_pane.dart index a772d8a1..e640b3cd 100644 --- a/lib/widgets/scripts_editor_pane.dart +++ b/lib/widgets/scripts_editor_pane.dart @@ -6,8 +6,13 @@ import 'package:flutter_highlight/themes/xcode.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class ScriptsEditorPane extends ConsumerStatefulWidget { + final bool readOnly; final CodeController controller; - const ScriptsEditorPane({super.key, required this.controller}); + const ScriptsEditorPane({ + super.key, + required this.controller, + this.readOnly = false, + }); @override ConsumerState createState() => _ScriptsEditorPaneState(); @@ -28,6 +33,7 @@ class _ScriptsEditorPaneState extends ConsumerState { ), child: SingleChildScrollView( child: CodeField( + readOnly: widget.readOnly, smartDashesType: SmartDashesType.enabled, smartQuotesType: SmartQuotesType.enabled, background: Theme.of(context).colorScheme.surfaceContainerLowest,