diff --git a/lib/screens/history/history_widgets/his_request_pane.dart b/lib/screens/history/history_widgets/his_request_pane.dart index 6378a871..a2ad35b2 100644 --- a/lib/screens/history/history_widgets/his_request_pane.dart +++ b/lib/screens/history/history_widgets/his_request_pane.dart @@ -53,7 +53,69 @@ class HistoryRequestPane extends ConsumerWidget { rows: headersMap, keyName: kNameHeader, ), - const SizedBox(), + const HisRequestBody(), + ], + ); + } +} + +class HisRequestBody extends ConsumerWidget { + const HisRequestBody({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final selectedHistoryModel = ref.watch(selectedHistoryRequestModelProvider); + final requestModel = selectedHistoryModel?.httpRequestModel; + final contentType = requestModel?.bodyContentType; + + return Column( + children: [ + kVSpacer5, + RichText( + text: TextSpan( + style: Theme.of(context).textTheme.labelLarge, + children: [ + const TextSpan( + text: "Content Type: ", + ), + TextSpan( + text: contentType?.name ?? "text", + style: Theme.of(context).textTheme.titleSmall?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + )), + ], + ), + ), + kVSpacer5, + Expanded( + child: switch (contentType) { + ContentType.formdata => Padding( + padding: kPh4, + child: + RequestFormDataTable(rows: requestModel?.formData ?? [])), + // TODO: Fix JsonTextFieldEditor & plug it here + ContentType.json => Padding( + padding: kPt5o10, + child: TextFieldEditor( + key: Key("${selectedHistoryModel?.historyId}-json-body"), + fieldKey: + "${selectedHistoryModel?.historyId}-json-body-viewer", + initialValue: requestModel?.body, + readOnly: true, + ), + ), + _ => Padding( + padding: kPt5o10, + child: TextFieldEditor( + key: Key("${selectedHistoryModel?.historyId}-body"), + fieldKey: "${selectedHistoryModel?.historyId}-body-viewer", + initialValue: requestModel?.body, + readOnly: true, + ), + ), + }, + ) ], ); } diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_form_data.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_form_data.dart index 5228c660..9b0bb123 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_form_data.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_form_data.dart @@ -124,17 +124,7 @@ class _FormDataBodyState extends ConsumerState { ), DataCell( formRows[index].type == FormDataType.file - ? 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), - ), - ), + ? FormDataFileButton( onPressed: () async { var pickedResult = await pickFile(); if (pickedResult != null && @@ -146,14 +136,7 @@ class _FormDataBodyState extends ConsumerState { _onFieldChange(selectedId!); } }, - label: Text( - (formRows[index].type == FormDataType.file && - formRows[index].value.isNotEmpty) - ? formRows[index].value.toString() - : kLabelSelectFile, - overflow: TextOverflow.ellipsis, - style: kFormDataButtonLabelTextStyle, - ), + initialValue: formRows[index].value, ) : CellField( keyId: "$selectedId-$index-form-v-$seed", diff --git a/lib/widgets/button_form_data_file.dart b/lib/widgets/button_form_data_file.dart new file mode 100644 index 00000000..262ea76b --- /dev/null +++ b/lib/widgets/button_form_data_file.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:apidash/consts.dart'; + +class FormDataFileButton extends StatelessWidget { + const FormDataFileButton({super.key, this.onPressed, this.initialValue}); + + final VoidCallback? onPressed; + final String? initialValue; + + @override + Widget build(BuildContext context) { + return 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: onPressed, + label: Text( + initialValue ?? kLabelSelectFile, + overflow: TextOverflow.ellipsis, + style: kFormDataButtonLabelTextStyle, + ), + ); + } +} diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 736ffd83..5bdd2f82 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -9,11 +9,13 @@ class TextFieldEditor extends StatefulWidget { required this.fieldKey, this.onChanged, this.initialValue, + this.readOnly = false, }); final String fieldKey; final Function(String)? onChanged; final String? initialValue; + final bool readOnly; @override State createState() => _TextFieldEditorState(); } @@ -69,6 +71,7 @@ class _TextFieldEditorState extends State { keyboardType: TextInputType.multiline, expands: true, maxLines: null, + readOnly: widget.readOnly, style: kCodeStyle, textAlignVertical: TextAlignVertical.top, onChanged: widget.onChanged, diff --git a/lib/widgets/table_request.dart b/lib/widgets/table_request.dart index 014f0c86..010aaa27 100644 --- a/lib/widgets/table_request.dart +++ b/lib/widgets/table_request.dart @@ -103,7 +103,6 @@ class RequestDataTable extends StatelessWidget { ), ), ), - kVSpacer40, ], ), ); diff --git a/lib/widgets/table_request_form.dart b/lib/widgets/table_request_form.dart new file mode 100644 index 00000000..a61c0cd7 --- /dev/null +++ b/lib/widgets/table_request_form.dart @@ -0,0 +1,119 @@ +import 'package:flutter/material.dart'; +import 'package:data_table_2/data_table_2.dart'; +import 'package:apidash/widgets/widgets.dart'; +import 'package:apidash/models/models.dart'; +import 'package:apidash/consts.dart'; + +class RequestFormDataTable extends StatelessWidget { + const RequestFormDataTable({ + super.key, + required this.rows, + this.keyName, + this.valueName, + }); + + final List rows; + final String? keyName; + final String? valueName; + + @override + Widget build(BuildContext context) { + final clrScheme = Theme.of(context).colorScheme; + + final List columns = [ + const DataColumn2( + label: Text(''), + fixedWidth: 8, + ), + DataColumn2( + label: Text(keyName ?? kNameField), + ), + const DataColumn2( + label: Text('='), + fixedWidth: 30, + ), + DataColumn2( + label: Text(valueName ?? kNameValue), + ), + const DataColumn2( + label: Text(''), + fixedWidth: 8, + ), + ]; + + final fieldDecoration = InputDecoration( + contentPadding: const EdgeInsets.only(bottom: 12), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: clrScheme.primary.withOpacity( + kHintOpacity, + ), + ), + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: clrScheme.surfaceContainerHighest, + ), + ), + ); + + final List dataRows = rows + .map( + (FormDataModel entry) => DataRow( + cells: [ + const DataCell(kHSpacer5), + DataCell( + ReadOnlyTextField( + initialValue: entry.name, + decoration: fieldDecoration, + ), + ), + const DataCell( + Text('='), + ), + DataCell( + entry.type == FormDataType.file + ? Tooltip( + message: entry.value, + child: FormDataFileButton( + onPressed: () {}, + initialValue: entry.value, + ), + ) + : ReadOnlyTextField( + initialValue: entry.value, + decoration: fieldDecoration, + ), + ), + const DataCell(kHSpacer5), + ], + ), + ) + .toList(); + + return Container( + margin: kP10, + child: Column( + children: [ + Expanded( + child: Theme( + data: Theme.of(context) + .copyWith(scrollbarTheme: kDataTableScrollbarTheme), + child: DataTable2( + columnSpacing: 12, + dividerThickness: 0, + horizontalMargin: 0, + headingRowHeight: 0, + dataRowHeight: kDataTableRowHeight, + bottomMargin: kDataTableBottomPadding, + isVerticalScrollBarVisible: true, + columns: columns, + rows: dataRows, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/widgets.dart b/lib/widgets/widgets.dart index db9b860c..5383916d 100644 --- a/lib/widgets/widgets.dart +++ b/lib/widgets/widgets.dart @@ -1,6 +1,7 @@ export 'button_clear_response.dart'; export 'button_copy.dart'; export 'button_discord.dart'; +export 'button_form_data_file.dart'; export 'button_group_filled.dart'; export 'button_repo.dart'; export 'button_save_download.dart'; @@ -51,6 +52,7 @@ export 'splitview_equal.dart'; export 'splitview_history.dart'; export 'tabbar_segmented.dart'; export 'table_map.dart'; +export 'table_request_form.dart'; export 'table_request.dart'; export 'tabs.dart'; export 'texts.dart';