From ae1da0e697bde345706868f11172c73c3ef2c34a Mon Sep 17 00:00:00 2001 From: Manas Hejmadi Date: Sat, 9 Aug 2025 16:18:00 +0530 Subject: [PATCH] ResponseBody: isPartOfHistory added for conditional UI hiding --- .../history_widgets/his_response_pane.dart | 1 + lib/widgets/ai_toolgen_widgets.dart | 45 ++++++ lib/widgets/response_body.dart | 18 +++ lib/widgets/response_body_success.dart | 129 ++++++------------ 4 files changed, 108 insertions(+), 85 deletions(-) diff --git a/lib/screens/history/history_widgets/his_response_pane.dart b/lib/screens/history/history_widgets/his_response_pane.dart index 695c3785..b63b2d2a 100644 --- a/lib/screens/history/history_widgets/his_response_pane.dart +++ b/lib/screens/history/history_widgets/his_response_pane.dart @@ -35,6 +35,7 @@ class HistoryResponsePane extends ConsumerWidget { children: [ ResponseBody( selectedRequestModel: requestModel, + isPartOfHistory: true, ), ResponseHeaders( responseHeaders: historyHttpResponseModel?.headers ?? {}, diff --git a/lib/widgets/ai_toolgen_widgets.dart b/lib/widgets/ai_toolgen_widgets.dart index cd4e94a0..41537aa5 100644 --- a/lib/widgets/ai_toolgen_widgets.dart +++ b/lib/widgets/ai_toolgen_widgets.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:apidash/apitoolgen/request_consolidator.dart'; import 'package:apidash/apitoolgen/tool_templates.dart'; import 'package:apidash/consts.dart'; @@ -8,12 +10,15 @@ import 'package:apidash/widgets/ai_ui_desginer_widgets.dart'; import 'package:apidash/widgets/button_copy.dart'; import 'package:apidash/widgets/previewer_code.dart'; import 'package:apidash/widgets/widget_sending.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:apidash_design_system/tokens/tokens.dart'; import 'package:apidash_design_system/widgets/popup_menu.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:genai/agentic_engine/blueprint.dart'; +import '../providers/providers.dart'; + class GenerateToolDialog extends ConsumerStatefulWidget { final APIDashRequestDescription requestDesc; const GenerateToolDialog({ @@ -21,6 +26,46 @@ class GenerateToolDialog extends ConsumerStatefulWidget { required this.requestDesc, }); + static show(BuildContext context, WidgetRef ref) { + final requestModel = ref.watch(selectedRequestModelProvider + .select((value) => value?.httpRequestModel)); + final responseModel = ref.watch(selectedRequestModelProvider + .select((value) => value?.httpResponseModel)); + + if (requestModel == null) return; + if (responseModel == null) return; + + String? bodyTXT; + Map? bodyJSON; + List? bodyFormData; + + if (requestModel.bodyContentType == ContentType.formdata) { + bodyFormData = requestModel.formDataMapList; + } else if (requestModel.bodyContentType == ContentType.json) { + bodyJSON = jsonDecode(requestModel.body.toString()); + } else { + bodyTXT = requestModel.body!; + } + + final reqDesModel = APIDashRequestDescription( + endpoint: requestModel.url, + method: requestModel.method.name.toUpperCase(), + responseType: responseModel.contentType.toString(), + headers: requestModel.headersMap, + response: responseModel.body, + formData: bodyFormData, + bodyTXT: bodyTXT, + bodyJSON: bodyJSON, + ); + + showCustomDialog( + context, + GenerateToolDialog( + requestDesc: reqDesModel, + ), + ); + } + @override ConsumerState createState() => _GenerateToolDialogState(); } diff --git a/lib/widgets/response_body.dart b/lib/widgets/response_body.dart index f1c866e9..c3d134bf 100644 --- a/lib/widgets/response_body.dart +++ b/lib/widgets/response_body.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:apidash_core/apidash_core.dart'; import 'package:apidash/models/models.dart'; @@ -10,9 +12,11 @@ class ResponseBody extends StatelessWidget { const ResponseBody({ super.key, this.selectedRequestModel, + this.isPartOfHistory = false, }); final RequestModel? selectedRequestModel; + final bool isPartOfHistory; @override Widget build(BuildContext context) { @@ -60,6 +64,19 @@ class ResponseBody extends StatelessWidget { options.remove(ResponseBodyView.code); } + if (responseModel.sseOutput?.isNotEmpty ?? false) { + return ResponseBodySuccess( + key: Key("${selectedRequestModel!.id}-response"), + mediaType: MediaType('text', 'event-stream'), + options: [ResponseBodyView.sse, ResponseBodyView.raw], + bytes: utf8.encode((responseModel.sseOutput!).toString()), + body: jsonEncode(responseModel.sseOutput!), + formattedBody: responseModel.sseOutput!.join('\n'), + aiRequestModel: selectedRequestModel?.aiRequestModel, + isPartOfHistory: isPartOfHistory, + ); + } + return ResponseBodySuccess( key: Key("${selectedRequestModel!.id}-response"), mediaType: mediaType, @@ -71,6 +88,7 @@ class ResponseBody extends StatelessWidget { sseOutput: responseModel.sseOutput, isAIResponse: selectedRequestModel?.apiType == APIType.ai, aiRequestModel: selectedRequestModel?.aiRequestModel, + isPartOfHistory: isPartOfHistory, ); } } diff --git a/lib/widgets/response_body_success.dart b/lib/widgets/response_body_success.dart index 01f39143..67d47777 100644 --- a/lib/widgets/response_body_success.dart +++ b/lib/widgets/response_body_success.dart @@ -28,6 +28,7 @@ class ResponseBodySuccess extends ConsumerStatefulWidget { this.sseOutput, this.isAIResponse = false, this.aiRequestModel, + this.isPartOfHistory = false, }); final MediaType mediaType; final List options; @@ -38,6 +39,7 @@ class ResponseBodySuccess extends ConsumerStatefulWidget { final String? highlightLanguage; final bool isAIResponse; final AIRequestModel? aiRequestModel; + final bool isPartOfHistory; @override ConsumerState createState() => @@ -71,96 +73,53 @@ class _ResponseBodySuccessState extends ConsumerState { padding: kP10, child: Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - FilledButton.tonalIcon( - style: FilledButton.styleFrom( - padding: kPh12, - minimumSize: const Size(44, 44), - ), - onPressed: () async { - final requestModel = ref.watch( - selectedRequestModelProvider - .select((value) => value?.httpRequestModel)); - final responseModel = ref.watch( - selectedRequestModelProvider - .select((value) => value?.httpResponseModel)); - - if (requestModel == null) return; - if (responseModel == null) { - print("AA"); - return; - } - - String? bodyTXT; - Map? bodyJSON; - List? bodyFormData; - - if (requestModel.bodyContentType == - ContentType.formdata) { - bodyFormData = requestModel.formDataMapList; - } else if (requestModel.bodyContentType == - ContentType.json) { - bodyJSON = jsonDecode(requestModel.body.toString()); - } else { - bodyTXT = requestModel.body!; - } - - final reqDesModel = APIDashRequestDescription( - endpoint: requestModel.url, - method: requestModel.method.name.toUpperCase(), - responseType: responseModel.contentType.toString(), - headers: requestModel.headersMap, - response: responseModel.body, - formData: bodyFormData, - bodyTXT: bodyTXT, - bodyJSON: bodyJSON, - ); - - print("GT2"); - showCustomDialog( - context, - GenerateToolDialog( - requestDesc: reqDesModel, + if (!widget.isPartOfHistory) + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FilledButton.tonalIcon( + style: FilledButton.styleFrom( + padding: kPh12, + minimumSize: const Size(44, 44), + ), + onPressed: () async { + GenerateToolDialog.show(context, ref); + }, + icon: Icon( + Icons.token_outlined, + ), + label: const SizedBox( + child: Text( + "Generate Tool", ), - ); - }, - icon: Icon( - Icons.token_outlined, - ), - label: const SizedBox( - child: Text( - "Generate Tool", ), ), - ), - kHSpacer10, - FilledButton.tonalIcon( - style: FilledButton.styleFrom( - padding: kPh12, - minimumSize: const Size(44, 44), - ), - onPressed: () { - final model = ref.watch(selectedRequestModelProvider - .select((value) => value?.httpResponseModel)); - showCustomDialog( - context, - GenerateUIDialog(content: model?.formattedBody ?? ""), - ); - }, - icon: Icon( - Icons.generating_tokens, - ), - label: const SizedBox( - child: Text( - kLabelGenerateUI, + kHSpacer10, + FilledButton.tonalIcon( + style: FilledButton.styleFrom( + padding: kPh12, + minimumSize: const Size(44, 44), + ), + onPressed: () { + final model = ref.watch(selectedRequestModelProvider + .select((value) => value?.httpResponseModel)); + showCustomDialog( + context, + GenerateUIDialog(content: model?.formattedBody ?? ""), + ); + }, + icon: Icon( + Icons.generating_tokens, + ), + label: const SizedBox( + child: Text( + kLabelGenerateUI, + ), ), ), - ), - kHSpacer10, - ], - ), + kHSpacer10, + ], + ), kVSpacer10, Row( children: [