feat: drag scrolling

This commit is contained in:
DenserMeerkat
2024-03-15 03:16:47 +05:30
parent 02c4d92c95
commit fa6dc8e352
11 changed files with 462 additions and 404 deletions

View File

@ -70,6 +70,8 @@ const kP10 = EdgeInsets.all(10);
const kPt24o8 = EdgeInsets.only(top: 24, left: 8.0, right: 8.0, bottom: 8.0); const kPt24o8 = EdgeInsets.only(top: 24, left: 8.0, right: 8.0, bottom: 8.0);
const kPt5o10 = const kPt5o10 =
EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 10.0); EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 10.0);
const kPh4 = EdgeInsets.symmetric(horizontal: 4);
const kPh8 = EdgeInsets.symmetric(horizontal: 8);
const kPh20 = EdgeInsets.symmetric( const kPh20 = EdgeInsets.symmetric(
horizontal: 20, horizontal: 20,
); );
@ -113,6 +115,11 @@ const kTextButtonMinWidth = 44.0;
const kRandMax = 100000; const kRandMax = 100000;
const kDataTableScrollbarTheme = ScrollbarThemeData(
crossAxisMargin: -4,
);
const kDataTableBottomPadding = 80.0;
const kDataRowHeight = 36.0;
const kTableThemeData = DaviThemeData( const kTableThemeData = DaviThemeData(
columnDividerThickness: 1, columnDividerThickness: 1,
columnDividerColor: kColorTransparent, columnDividerColor: kColorTransparent,
@ -279,7 +286,6 @@ enum CodegenLanguage {
rustUreq("Rust (ureq)", "rust", "rs"), rustUreq("Rust (ureq)", "rust", "rs"),
juliaHttp("Julia (HTTP)", "julia", "jl"); juliaHttp("Julia (HTTP)", "julia", "jl");
const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext);
final String label; final String label;
final String codeHighlightLang; final String codeHighlightLang;

View File

@ -21,7 +21,6 @@ class EditRequestBody extends ConsumerWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background, color: Theme.of(context).colorScheme.background,
), ),
margin: kPt5o10,
child: Column( child: Column(
children: [ children: [
const SizedBox( const SizedBox(
@ -38,27 +37,34 @@ class EditRequestBody extends ConsumerWidget {
), ),
Expanded( Expanded(
child: switch (contentType) { child: switch (contentType) {
ContentType.formdata => const FormDataWidget(), ContentType.formdata =>
const Padding(padding: kPh4, child: FormDataWidget()),
// TODO: Fix JsonTextFieldEditor & plug it here // TODO: Fix JsonTextFieldEditor & plug it here
ContentType.json => TextFieldEditor( ContentType.json => Padding(
key: Key("$selectedId-json-body"), padding: kPt5o10,
fieldKey: "$selectedId-json-body-editor", child: TextFieldEditor(
initialValue: requestModel?.requestBody, key: Key("$selectedId-json-body"),
onChanged: (String value) { fieldKey: "$selectedId-json-body-editor",
ref initialValue: requestModel?.requestBody,
.read(collectionStateNotifierProvider.notifier) onChanged: (String value) {
.update(selectedId, requestBody: value); ref
}, .read(collectionStateNotifierProvider.notifier)
.update(selectedId, requestBody: value);
},
),
), ),
_ => TextFieldEditor( _ => Padding(
key: Key("$selectedId-body"), padding: kPt5o10,
fieldKey: "$selectedId-body-editor", child: TextFieldEditor(
initialValue: requestModel?.requestBody, key: Key("$selectedId-body"),
onChanged: (String value) { fieldKey: "$selectedId-body-editor",
ref initialValue: requestModel?.requestBody,
.read(collectionStateNotifierProvider.notifier) onChanged: (String value) {
.update(selectedId, requestBody: value); ref
}, .read(collectionStateNotifierProvider.notifier)
.update(selectedId, requestBody: value);
},
),
), ),
}, },
) )

View File

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
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:davi/davi.dart'; import 'package:data_table_2/data_table_2.dart';
import 'package:apidash/providers/providers.dart'; import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/models/models.dart'; import 'package:apidash/models/models.dart';
@ -31,144 +31,23 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
rows = rows =
formRows == null || formRows.isEmpty ? [kFormDataEmptyModel] : formRows; formRows == null || formRows.isEmpty ? [kFormDataEmptyModel] : formRows;
DaviModel<FormDataModel> daviModelRows = DaviModel<FormDataModel>( List<DataColumn> columns = const [
rows: rows, DataColumn2(
columns: [ label: Text('Key'),
DaviColumn( ),
cellPadding: kpsV5, DataColumn2(
name: 'Key', label: Text('='),
grow: 4, fixedWidth: 30,
cellBuilder: (_, row) { ),
int idx = row.index; DataColumn2(
return Theme( label: Text('Value'),
data: Theme.of(context), ),
child: FormDataField( DataColumn2(
keyId: "$selectedId-$idx-form-v-$seed", label: Text('Remove'),
initialValue: rows[idx].name, fixedWidth: 32,
hintText: " Add Key", ),
onChanged: (value) { ];
rows[idx] = rows[idx].copyWith(
name: value,
);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
formDataType: rows[idx].type,
onFormDataTypeChanged: (value) {
rows[idx] = rows[idx].copyWith(
type: value ?? FormDataType.text,
);
rows[idx] = rows[idx].copyWith(value: "");
setState(() {});
_onFieldChange(selectedId!);
},
),
);
},
sortable: false,
),
DaviColumn(
width: 40,
cellPadding: kpsV5,
cellAlignment: Alignment.center,
cellBuilder: (_, row) {
return Text(
"=",
style: kCodeStyle,
);
},
),
DaviColumn(
name: 'Value',
grow: 4,
cellPadding: kpsV5,
cellBuilder: (_, row) {
int idx = row.index;
return rows[idx].type == FormDataType.file
? Align(
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: Theme(
data: Theme.of(context),
child: ElevatedButton.icon(
icon: const Icon(
Icons.snippet_folder_rounded,
size: 20,
),
style: ButtonStyle(
shape: MaterialStatePropertyAll(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
onPressed: () async {
var pickedResult = await pickFile();
if (pickedResult != null &&
pickedResult.files.isNotEmpty &&
pickedResult.files.first.path != null) {
rows[idx] = rows[idx].copyWith(
value: pickedResult.files.first.path!,
);
setState(() {});
_onFieldChange(selectedId!);
}
},
label: Text(
(rows[idx].type == FormDataType.file &&
rows[idx].value.isNotEmpty)
? rows[idx].value.toString()
: "Select File",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: kFormDataButtonLabelTextStyle,
),
),
),
),
],
),
)
: CellField(
keyId: "$selectedId-$idx-form-v-$seed",
initialValue: rows[idx].value,
hintText: " Add Value",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
);
},
sortable: false,
),
DaviColumn(
pinStatus: PinStatus.none,
width: 30,
cellBuilder: (_, row) {
return InkWell(
child: Theme.of(context).brightness == Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [kFormDataEmptyModel];
});
} else {
rows.removeAt(row.index);
}
_onFieldChange(selectedId!);
setState(() {});
},
);
},
),
],
);
return Stack( return Stack(
children: [ children: [
Container( Container(
@ -180,9 +59,160 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
child: DaviTheme( child: Theme(
data: kTableThemeData, data: Theme.of(context)
child: Davi<FormDataModel>(daviModelRows), .copyWith(scrollbarTheme: kDataTableScrollbarTheme),
child: DataTable2(
columnSpacing: 12,
dividerThickness: 0,
horizontalMargin: 0,
headingRowHeight: 0,
dataRowHeight: kDataRowHeight,
bottomMargin: kDataTableBottomPadding,
isVerticalScrollBarVisible: true,
columns: columns,
rows: List<DataRow>.generate(
rows.length,
(index) {
return DataRow(
key: ValueKey("$selectedId-$index-form-row-$seed"),
cells: <DataCell>[
DataCell(
Theme(
data: Theme.of(context),
child: FormDataField(
keyId: "$selectedId-$index-form-v-$seed",
initialValue: rows[index].name,
hintText: "Add Key",
onChanged: (value) {
rows[index] = rows[index].copyWith(
name: value,
);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
formDataType: rows[index].type,
onFormDataTypeChanged: (value) {
rows[index] = rows[index].copyWith(
type: value ?? FormDataType.text,
);
rows[index] =
rows[index].copyWith(value: "");
setState(() {});
_onFieldChange(selectedId!);
},
),
),
),
DataCell(
Text(
"=",
style: kCodeStyle,
),
),
DataCell(
rows[index].type == FormDataType.file
? Align(
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: Theme(
data: Theme.of(context),
child: ElevatedButton.icon(
icon: const Icon(
Icons.snippet_folder_rounded,
size: 20,
),
style: ButtonStyle(
shape:
MaterialStatePropertyAll(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
6),
),
),
),
onPressed: () async {
var pickedResult =
await pickFile();
if (pickedResult != null &&
pickedResult
.files.isNotEmpty &&
pickedResult.files.first
.path !=
null) {
rows[index] =
rows[index].copyWith(
value: pickedResult
.files.first.path!,
);
setState(() {});
_onFieldChange(selectedId!);
}
},
label: Text(
(rows[index].type ==
FormDataType
.file &&
rows[index]
.value
.isNotEmpty)
? rows[index]
.value
.toString()
: "Select File",
textAlign: TextAlign.center,
overflow:
TextOverflow.ellipsis,
style:
kFormDataButtonLabelTextStyle,
),
),
),
),
],
),
)
: CellField(
keyId: "$selectedId-$index-form-v-$seed",
initialValue: rows[index].value,
hintText: "Add Value",
onChanged: (value) {
rows[index] =
rows[index].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme:
Theme.of(context).colorScheme,
),
),
DataCell(
InkWell(
child: Theme.of(context).brightness ==
Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [kFormDataEmptyModel];
});
} else {
rows.removeAt(index);
}
_onFieldChange(selectedId!);
setState(() {});
},
),
),
],
);
},
),
),
), ),
), ),
], ],

View File

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
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:davi/davi.dart'; import 'package:data_table_2/data_table_2.dart';
import 'package:apidash/providers/providers.dart'; import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/models/models.dart'; import 'package:apidash/models/models.dart';
@ -49,101 +49,27 @@ class EditRequestHeadersState extends ConsumerState<EditRequestHeaders> {
ref.read(selectedRequestModelProvider)?.isHeaderEnabledList ?? ref.read(selectedRequestModelProvider)?.isHeaderEnabledList ??
List.filled(rows.length, true, growable: true); List.filled(rows.length, true, growable: true);
DaviModel<NameValueModel> model = DaviModel<NameValueModel>( List<DataColumn> columns = const [
rows: rows, DataColumn2(
columns: [ label: Text('Checkbox'),
DaviColumn( fixedWidth: 30,
name: 'Checkbox', ),
width: 30, DataColumn2(
cellBuilder: (_, row) { label: Text('Header Name'),
int idx = row.index; ),
return CheckBox( DataColumn2(
keyId: "$selectedId-$idx-headers-c-$seed", label: Text('='),
value: isRowEnabledList[idx], fixedWidth: 30,
onChanged: (value) { ),
setState(() { DataColumn2(
isRowEnabledList[idx] = value!; label: Text('Header Value'),
}); ),
_onFieldChange(selectedId!); DataColumn2(
}, label: Text('Remove'),
colorScheme: Theme.of(context).colorScheme, fixedWidth: 32,
); ),
}, ];
),
DaviColumn(
name: 'Header Name',
width: 70,
grow: 1,
cellBuilder: (_, row) {
int idx = row.index;
return HeaderField(
keyId: "$selectedId-$idx-headers-k-$seed",
initialValue: rows[idx].name,
hintText: "Add Header Name",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(name: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
);
},
sortable: false,
),
DaviColumn(
width: 30,
cellBuilder: (_, row) {
return Text(
"=",
style: kCodeStyle,
);
},
),
DaviColumn(
name: 'Header Value',
grow: 1,
cellBuilder: (_, row) {
int idx = row.index;
return CellField(
keyId: "$selectedId-$idx-headers-v-$seed",
initialValue: rows[idx].value,
hintText: " Add Header Value",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
);
},
sortable: false,
),
DaviColumn(
pinStatus: PinStatus.none,
width: 30,
cellBuilder: (_, row) {
return InkWell(
child: Theme.of(context).brightness == Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [
kNameValueEmptyModel,
];
isRowEnabledList = [true];
});
} else {
rows.removeAt(row.index);
isRowEnabledList.removeAt(row.index);
}
_onFieldChange(selectedId!);
},
);
},
),
],
);
return Stack( return Stack(
children: [ children: [
Container( Container(
@ -155,9 +81,97 @@ class EditRequestHeadersState extends ConsumerState<EditRequestHeaders> {
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
child: DaviTheme( child: Theme(
data: kTableThemeData, data: Theme.of(context)
child: Davi<NameValueModel>(model), .copyWith(scrollbarTheme: kDataTableScrollbarTheme),
child: DataTable2(
columnSpacing: 12,
dividerThickness: 0,
horizontalMargin: 0,
headingRowHeight: 0,
dataRowHeight: kDataRowHeight,
bottomMargin: kDataTableBottomPadding,
isVerticalScrollBarVisible: true,
columns: columns,
rows: List<DataRow>.generate(
rows.length,
(index) {
return DataRow(
key: ValueKey("$selectedId-$index-headers-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
keyId: "$selectedId-$index-headers-c-$seed",
value: isRowEnabledList[index],
onChanged: (value) {
setState(() {
isRowEnabledList[index] = value!;
});
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
HeaderField(
keyId: "$selectedId-$index-headers-k-$seed",
initialValue: rows[index].name,
hintText: "Add Header Name",
onChanged: (value) {
rows[index] =
rows[index].copyWith(name: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
Text(
"=",
style: kCodeStyle,
),
),
DataCell(
CellField(
keyId: "$selectedId-$index-headers-v-$seed",
initialValue: rows[index].value,
hintText: "Add Header Value",
onChanged: (value) {
rows[index] =
rows[index].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
InkWell(
child: Theme.of(context).brightness ==
Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [
kNameValueEmptyModel,
];
isRowEnabledList = [true];
});
} else {
rows.removeAt(index);
isRowEnabledList.removeAt(index);
}
_onFieldChange(selectedId!);
},
),
),
],
);
},
),
),
), ),
), ),
], ],

View File

@ -1,11 +1,11 @@
import 'dart:math'; import 'dart:math';
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:davi/davi.dart';
import 'package:apidash/providers/providers.dart'; import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/models/models.dart'; import 'package:apidash/models/models.dart';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import 'package:data_table_2/data_table_2.dart';
class EditRequestURLParams extends ConsumerStatefulWidget { class EditRequestURLParams extends ConsumerStatefulWidget {
const EditRequestURLParams({super.key}); const EditRequestURLParams({super.key});
@ -50,101 +50,26 @@ class EditRequestURLParamsState extends ConsumerState<EditRequestURLParams> {
ref.read(selectedRequestModelProvider)?.isParamEnabledList ?? ref.read(selectedRequestModelProvider)?.isParamEnabledList ??
List.filled(rows.length, true, growable: true); List.filled(rows.length, true, growable: true);
DaviModel<NameValueModel> model = DaviModel<NameValueModel>( List<DataColumn> columns = const [
rows: rows, DataColumn2(
columns: [ label: Text('Checkbox'),
DaviColumn( fixedWidth: 30,
name: 'Checkbox', ),
width: 30, DataColumn2(
cellBuilder: (_, row) { label: Text('URL Parameter'),
int idx = row.index; ),
return CheckBox( DataColumn2(
keyId: "$selectedId-$idx-params-c-$seed", label: Text('='),
value: isRowEnabledList[idx], fixedWidth: 30,
onChanged: (value) { ),
setState(() { DataColumn2(
isRowEnabledList[idx] = value!; label: Text('Parameter Value'),
}); ),
_onFieldChange(selectedId!); DataColumn2(
}, label: Text('Remove'),
colorScheme: Theme.of(context).colorScheme, fixedWidth: 32,
); ),
}, ];
),
DaviColumn(
name: 'URL Parameter',
width: 70,
grow: 1,
cellBuilder: (_, row) {
int idx = row.index;
return CellField(
keyId: "$selectedId-$idx-params-k-$seed",
initialValue: rows[idx].name,
hintText: "Add URL Parameter",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(name: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
);
},
sortable: false,
),
DaviColumn(
width: 30,
cellBuilder: (_, row) {
return Text(
"=",
style: kCodeStyle,
);
},
),
DaviColumn(
name: 'Value',
grow: 1,
cellBuilder: (_, row) {
int idx = row.index;
return CellField(
keyId: "$selectedId-$idx-params-v-$seed",
initialValue: rows[idx].value,
hintText: "Add Value",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
);
},
sortable: false,
),
DaviColumn(
pinStatus: PinStatus.none,
width: 30,
cellBuilder: (_, row) {
return InkWell(
child: Theme.of(context).brightness == Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [
kNameValueEmptyModel,
];
isRowEnabledList = [true];
});
} else {
rows.removeAt(row.index);
isRowEnabledList.removeAt(row.index);
}
_onFieldChange(selectedId!);
},
);
},
),
],
);
return Stack( return Stack(
children: [ children: [
Container( Container(
@ -154,11 +79,100 @@ class EditRequestURLParamsState extends ConsumerState<EditRequestURLParams> {
), ),
margin: kP10, margin: kP10,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Expanded( Expanded(
child: DaviTheme( child: Theme(
data: kTableThemeData, data: Theme.of(context)
child: Davi<NameValueModel>(model), .copyWith(scrollbarTheme: kDataTableScrollbarTheme),
child: DataTable2(
columnSpacing: 12,
dividerThickness: 0,
horizontalMargin: 0,
headingRowHeight: 0,
dataRowHeight: kDataRowHeight,
bottomMargin: kDataTableBottomPadding,
isVerticalScrollBarVisible: true,
columns: columns,
rows: List<DataRow>.generate(
rows.length,
(index) {
return DataRow(
key: ValueKey("$selectedId-$index-params-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
keyId: "$selectedId-$index-params-c-$seed",
value: isRowEnabledList[index],
onChanged: (value) {
setState(() {
isRowEnabledList[index] = value!;
});
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
CellField(
keyId: "$selectedId-$index-params-k-$seed",
initialValue: rows[index].name,
hintText: "Add URL Parameter",
onChanged: (value) {
rows[index] =
rows[index].copyWith(name: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
Text(
"=",
style: kCodeStyle,
),
),
DataCell(
CellField(
keyId: "$selectedId-$index-params-v-$seed",
initialValue: rows[index].value,
hintText: "Add Value",
onChanged: (value) {
rows[index] =
rows[index].copyWith(value: value);
_onFieldChange(selectedId!);
},
colorScheme: Theme.of(context).colorScheme,
),
),
DataCell(
InkWell(
child: Theme.of(context).brightness ==
Brightness.dark
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [
kNameValueEmptyModel,
];
isRowEnabledList = [true];
});
} else {
rows.removeAt(index);
isRowEnabledList.removeAt(index);
}
_onFieldChange(selectedId!);
},
),
),
],
);
},
),
),
), ),
), ),
], ],

View File

@ -52,7 +52,7 @@ class _FormDataFieldState extends State<FormDataField> {
), ),
), ),
hintText: widget.hintText, hintText: widget.hintText,
contentPadding: const EdgeInsets.only(bottom: 16), contentPadding: const EdgeInsets.only(bottom: 13),
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: colorScheme.primary.withOpacity( color: colorScheme.primary.withOpacity(

View File

@ -81,6 +81,7 @@ class _HeaderFieldState extends State<HeaderField> {
hintStyle: kCodeStyle.copyWith( hintStyle: kCodeStyle.copyWith(
color: colorScheme.outline.withOpacity(kHintOpacity)), color: colorScheme.outline.withOpacity(kHintOpacity)),
hintText: widget.hintText, hintText: widget.hintText,
contentPadding: const EdgeInsets.only(bottom: 12),
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: colorScheme.primary.withOpacity( color: colorScheme.primary.withOpacity(

View File

@ -95,6 +95,7 @@ class _RequestPaneState extends State<RequestPane>
), ),
], ],
), ),
kVSpacer5,
Expanded( Expanded(
child: TabBarView( child: TabBarView(
controller: _controller, controller: _controller,

View File

@ -68,6 +68,7 @@ class CellField extends StatelessWidget {
), ),
), ),
hintText: hintText, hintText: hintText,
contentPadding: const EdgeInsets.only(bottom: 12),
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: clrScheme.primary.withOpacity( color: clrScheme.primary.withOpacity(

View File

@ -233,6 +233,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.4" version: "2.3.4"
data_table_2:
dependency: "direct main"
description:
name: data_table_2
sha256: fdb0551f103f1daf837bddfde14619fd9e683408833a618c9afabeb533fce88c
url: "https://pub.dev"
source: hosted
version: "2.5.11"
davi: davi:
dependency: "direct main" dependency: "direct main"
description: description:
@ -508,10 +516,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.0"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -633,30 +641,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -693,26 +677,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.16+1" version: "0.12.16"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.5.0"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.11.0" version: "1.10.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -789,10 +773,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: path name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.8.3"
path_parsing: path_parsing:
dependency: transitive dependency: transitive
description: description:
@ -909,10 +893,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pointer_interceptor_web name: pointer_interceptor_web
sha256: a6237528b46c411d8d55cdfad8fcb3269fc4cbb26060b14bff94879165887d1e sha256: "9386e064097fd16419e935c23f08f35b58e6aaec155dd39bd6a003b88f9c14b4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.10.2" version: "0.10.1+2"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:
@ -1234,10 +1218,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.2.3"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
@ -1306,10 +1290,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: web name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.3.0"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
@ -1376,5 +1360,5 @@ packages:
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.3.0 <4.0.0" dart: ">=3.2.3 <4.0.0"
flutter: ">=3.19.0" flutter: ">=3.16.0"

View File

@ -56,6 +56,7 @@ dependencies:
dart_style: ^2.3.4 dart_style: ^2.3.4
json_text_field: ^1.1.0 json_text_field: ^1.1.0
csv: ^5.1.1 csv: ^5.1.1
data_table_2: ^2.5.11
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: