ResponseBody: isPartOfHistory added for conditional UI hiding

This commit is contained in:
Manas Hejmadi
2025-08-09 16:18:00 +05:30
parent c6c0391b66
commit ae1da0e697
4 changed files with 108 additions and 85 deletions

View File

@@ -35,6 +35,7 @@ class HistoryResponsePane extends ConsumerWidget {
children: [ children: [
ResponseBody( ResponseBody(
selectedRequestModel: requestModel, selectedRequestModel: requestModel,
isPartOfHistory: true,
), ),
ResponseHeaders( ResponseHeaders(
responseHeaders: historyHttpResponseModel?.headers ?? {}, responseHeaders: historyHttpResponseModel?.headers ?? {},

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:apidash/apitoolgen/request_consolidator.dart'; import 'package:apidash/apitoolgen/request_consolidator.dart';
import 'package:apidash/apitoolgen/tool_templates.dart'; import 'package:apidash/apitoolgen/tool_templates.dart';
import 'package:apidash/consts.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/button_copy.dart';
import 'package:apidash/widgets/previewer_code.dart'; import 'package:apidash/widgets/previewer_code.dart';
import 'package:apidash/widgets/widget_sending.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/tokens/tokens.dart';
import 'package:apidash_design_system/widgets/popup_menu.dart'; import 'package:apidash_design_system/widgets/popup_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:genai/agentic_engine/blueprint.dart'; import 'package:genai/agentic_engine/blueprint.dart';
import '../providers/providers.dart';
class GenerateToolDialog extends ConsumerStatefulWidget { class GenerateToolDialog extends ConsumerStatefulWidget {
final APIDashRequestDescription requestDesc; final APIDashRequestDescription requestDesc;
const GenerateToolDialog({ const GenerateToolDialog({
@@ -21,6 +26,46 @@ class GenerateToolDialog extends ConsumerStatefulWidget {
required this.requestDesc, 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<Map>? 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 @override
ConsumerState<GenerateToolDialog> createState() => _GenerateToolDialogState(); ConsumerState<GenerateToolDialog> createState() => _GenerateToolDialogState();
} }

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:apidash_core/apidash_core.dart'; import 'package:apidash_core/apidash_core.dart';
import 'package:apidash/models/models.dart'; import 'package:apidash/models/models.dart';
@@ -10,9 +12,11 @@ class ResponseBody extends StatelessWidget {
const ResponseBody({ const ResponseBody({
super.key, super.key,
this.selectedRequestModel, this.selectedRequestModel,
this.isPartOfHistory = false,
}); });
final RequestModel? selectedRequestModel; final RequestModel? selectedRequestModel;
final bool isPartOfHistory;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -60,6 +64,19 @@ class ResponseBody extends StatelessWidget {
options.remove(ResponseBodyView.code); 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( return ResponseBodySuccess(
key: Key("${selectedRequestModel!.id}-response"), key: Key("${selectedRequestModel!.id}-response"),
mediaType: mediaType, mediaType: mediaType,
@@ -71,6 +88,7 @@ class ResponseBody extends StatelessWidget {
sseOutput: responseModel.sseOutput, sseOutput: responseModel.sseOutput,
isAIResponse: selectedRequestModel?.apiType == APIType.ai, isAIResponse: selectedRequestModel?.apiType == APIType.ai,
aiRequestModel: selectedRequestModel?.aiRequestModel, aiRequestModel: selectedRequestModel?.aiRequestModel,
isPartOfHistory: isPartOfHistory,
); );
} }
} }

View File

@@ -28,6 +28,7 @@ class ResponseBodySuccess extends ConsumerStatefulWidget {
this.sseOutput, this.sseOutput,
this.isAIResponse = false, this.isAIResponse = false,
this.aiRequestModel, this.aiRequestModel,
this.isPartOfHistory = false,
}); });
final MediaType mediaType; final MediaType mediaType;
final List<ResponseBodyView> options; final List<ResponseBodyView> options;
@@ -38,6 +39,7 @@ class ResponseBodySuccess extends ConsumerStatefulWidget {
final String? highlightLanguage; final String? highlightLanguage;
final bool isAIResponse; final bool isAIResponse;
final AIRequestModel? aiRequestModel; final AIRequestModel? aiRequestModel;
final bool isPartOfHistory;
@override @override
ConsumerState<ResponseBodySuccess> createState() => ConsumerState<ResponseBodySuccess> createState() =>
@@ -71,96 +73,53 @@ class _ResponseBodySuccessState extends ConsumerState<ResponseBodySuccess> {
padding: kP10, padding: kP10,
child: Column( child: Column(
children: [ children: [
Row( if (!widget.isPartOfHistory)
mainAxisAlignment: MainAxisAlignment.end, Row(
children: [ mainAxisAlignment: MainAxisAlignment.end,
FilledButton.tonalIcon( children: [
style: FilledButton.styleFrom( FilledButton.tonalIcon(
padding: kPh12, style: FilledButton.styleFrom(
minimumSize: const Size(44, 44), padding: kPh12,
), minimumSize: const Size(44, 44),
onPressed: () async { ),
final requestModel = ref.watch( onPressed: () async {
selectedRequestModelProvider GenerateToolDialog.show(context, ref);
.select((value) => value?.httpRequestModel)); },
final responseModel = ref.watch( icon: Icon(
selectedRequestModelProvider Icons.token_outlined,
.select((value) => value?.httpResponseModel)); ),
label: const SizedBox(
if (requestModel == null) return; child: Text(
if (responseModel == null) { "Generate Tool",
print("AA");
return;
}
String? bodyTXT;
Map? bodyJSON;
List<Map>? 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,
), ),
);
},
icon: Icon(
Icons.token_outlined,
),
label: const SizedBox(
child: Text(
"Generate Tool",
), ),
), ),
), kHSpacer10,
kHSpacer10, FilledButton.tonalIcon(
FilledButton.tonalIcon( style: FilledButton.styleFrom(
style: FilledButton.styleFrom( padding: kPh12,
padding: kPh12, minimumSize: const Size(44, 44),
minimumSize: const Size(44, 44), ),
), onPressed: () {
onPressed: () { final model = ref.watch(selectedRequestModelProvider
final model = ref.watch(selectedRequestModelProvider .select((value) => value?.httpResponseModel));
.select((value) => value?.httpResponseModel)); showCustomDialog(
showCustomDialog( context,
context, GenerateUIDialog(content: model?.formattedBody ?? ""),
GenerateUIDialog(content: model?.formattedBody ?? ""), );
); },
}, icon: Icon(
icon: Icon( Icons.generating_tokens,
Icons.generating_tokens, ),
), label: const SizedBox(
label: const SizedBox( child: Text(
child: Text( kLabelGenerateUI,
kLabelGenerateUI, ),
), ),
), ),
), kHSpacer10,
kHSpacer10, ],
], ),
),
kVSpacer10, kVSpacer10,
Row( Row(
children: [ children: [