mirror of
https://github.com/foss42/apidash.git
synced 2025-05-31 22:33:59 +08:00
fix: history body view
This commit is contained in:
@ -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,
|
||||
),
|
||||
),
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -124,17 +124,7 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
|
||||
),
|
||||
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<FormDataWidget> {
|
||||
_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",
|
||||
|
31
lib/widgets/button_form_data_file.dart
Normal file
31
lib/widgets/button_form_data_file.dart
Normal file
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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<TextFieldEditor> createState() => _TextFieldEditorState();
|
||||
}
|
||||
@ -69,6 +71,7 @@ class _TextFieldEditorState extends State<TextFieldEditor> {
|
||||
keyboardType: TextInputType.multiline,
|
||||
expands: true,
|
||||
maxLines: null,
|
||||
readOnly: widget.readOnly,
|
||||
style: kCodeStyle,
|
||||
textAlignVertical: TextAlignVertical.top,
|
||||
onChanged: widget.onChanged,
|
||||
|
@ -103,7 +103,6 @@ class RequestDataTable extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
kVSpacer40,
|
||||
],
|
||||
),
|
||||
);
|
||||
|
119
lib/widgets/table_request_form.dart
Normal file
119
lib/widgets/table_request_form.dart
Normal file
@ -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<FormDataModel> rows;
|
||||
final String? keyName;
|
||||
final String? valueName;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final clrScheme = Theme.of(context).colorScheme;
|
||||
|
||||
final List<DataColumn> 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<DataRow> dataRows = rows
|
||||
.map<DataRow>(
|
||||
(FormDataModel entry) => DataRow(
|
||||
cells: <DataCell>[
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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';
|
||||
|
Reference in New Issue
Block a user