diff --git a/lib/consts.dart b/lib/consts.dart index e9e58830..b0ca77bd 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -3,7 +3,6 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:davi/davi.dart'; const kDiscordUrl = "https://bit.ly/heyfoss"; const kGitUrl = "https://github.com/foss42/apidash"; @@ -82,6 +81,8 @@ const kPh2 = EdgeInsets.symmetric(horizontal: 2); const kPt24o8 = EdgeInsets.only(top: 24, left: 8.0, right: 8.0, bottom: 8.0); const kPt5o10 = 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( horizontal: 20, ); @@ -128,19 +129,11 @@ const kTextButtonMinWidth = 44.0; const kRandMax = 100000; -const kTableThemeData = DaviThemeData( - columnDividerThickness: 1, - columnDividerColor: kColorTransparent, - row: RowThemeData( - dividerColor: kColorTransparent, - ), - decoration: BoxDecoration( - border: Border(), - ), - header: HeaderThemeData( - visible: false, - ), +const kDataTableScrollbarTheme = ScrollbarThemeData( + crossAxisMargin: -4, ); +const kDataTableBottomPadding = 12.0; +const kDataTableRowHeight = 36.0; const kIconRemoveDark = Icon( Icons.remove_circle, diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_body.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_body.dart index f667f6b5..085df3f2 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_body.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_body.dart @@ -21,7 +21,6 @@ class EditRequestBody extends ConsumerWidget { decoration: BoxDecoration( color: Theme.of(context).colorScheme.background, ), - margin: kPt5o10, child: Column( children: [ const SizedBox( @@ -38,27 +37,34 @@ class EditRequestBody extends ConsumerWidget { ), Expanded( child: switch (contentType) { - ContentType.formdata => const FormDataWidget(), + ContentType.formdata => + const Padding(padding: kPh4, child: FormDataWidget()), // TODO: Fix JsonTextFieldEditor & plug it here - ContentType.json => TextFieldEditor( - key: Key("$selectedId-json-body"), - fieldKey: "$selectedId-json-body-editor", - initialValue: requestModel?.requestBody, - onChanged: (String value) { - ref - .read(collectionStateNotifierProvider.notifier) - .update(selectedId, requestBody: value); - }, + ContentType.json => Padding( + padding: kPt5o10, + child: TextFieldEditor( + key: Key("$selectedId-json-body"), + fieldKey: "$selectedId-json-body-editor", + initialValue: requestModel?.requestBody, + onChanged: (String value) { + ref + .read(collectionStateNotifierProvider.notifier) + .update(selectedId, requestBody: value); + }, + ), ), - _ => TextFieldEditor( - key: Key("$selectedId-body"), - fieldKey: "$selectedId-body-editor", - initialValue: requestModel?.requestBody, - onChanged: (String value) { - ref - .read(collectionStateNotifierProvider.notifier) - .update(selectedId, requestBody: value); - }, + _ => Padding( + padding: kPt5o10, + child: TextFieldEditor( + key: Key("$selectedId-body"), + fieldKey: "$selectedId-body-editor", + initialValue: requestModel?.requestBody, + onChanged: (String value) { + ref + .read(collectionStateNotifierProvider.notifier) + .update(selectedId, requestBody: value); + }, + ), ), }, ) 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 582b19ed..54f0a73e 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 @@ -1,7 +1,7 @@ import 'dart:math'; import 'package:flutter/material.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/widgets/widgets.dart'; import 'package:apidash/models/models.dart'; @@ -40,32 +40,53 @@ class _FormDataBodyState extends ConsumerState { .select((value) => value?.requestFormDataList?.length)); var rF = ref.read(selectedRequestModelProvider)?.requestFormDataList; bool isFormDataEmpty = rF == null || rF.isEmpty; - List rows = (isFormDataEmpty) + formRows = isFormDataEmpty ? [ kFormDataEmptyModel, ] - : rF; - formRows = isFormDataEmpty ? rows : rows + [kFormDataEmptyModel]; + : rF + + [ + kFormDataEmptyModel, + ]; isAddingRow = false; - DaviModel daviModelRows = DaviModel( - rows: formRows, - columns: [ - DaviColumn( - cellPadding: kPv2, - name: kNameField, - grow: 4, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == formRows.length; - return Theme( - data: Theme.of(context), - child: FormDataField( - keyId: "$selectedId-$idx-form-v-$seed", - initialValue: formRows[idx].name, + List columns = const [ + DataColumn2( + label: Text(kNameField), + size: ColumnSize.M, + ), + DataColumn2( + label: Text('='), + fixedWidth: 20, + ), + DataColumn2( + label: Text(''), + fixedWidth: 70, + ), + DataColumn2( + label: Text(kNameValue), + size: ColumnSize.L, + ), + DataColumn2( + label: Text(''), + fixedWidth: 32, + ), + ]; + + List dataRows = List.generate( + formRows.length, + (index) { + bool isLast = index + 1 == formRows.length; + return DataRow( + key: ValueKey("$selectedId-$index-form-row-$seed"), + cells: [ + DataCell( + CellField( + keyId: "$selectedId-$index-form-k-$seed", + initialValue: formRows[index].name, hintText: kHintAddFieldName, onChanged: (value) { - formRows[idx] = formRows[idx].copyWith(name: value); + formRows[index] = formRows[index].copyWith(name: value); if (isLast && !isAddingRow) { isAddingRow = true; formRows.add(kFormDataEmptyModel); @@ -73,13 +94,25 @@ class _FormDataBodyState extends ConsumerState { _onFieldChange(selectedId!); }, colorScheme: Theme.of(context).colorScheme, - formDataType: formRows[idx].type, - onFormDataTypeChanged: (value) { - bool hasChanged = formRows[idx].type != value; - formRows[idx] = formRows[idx].copyWith( + ), + ), + DataCell( + Center( + child: Text( + "=", + style: kCodeStyle, + ), + ), + ), + DataCell( + DropdownButtonFormData( + formDataType: formRows[index].type, + onChanged: (value) { + bool hasChanged = formRows[index].type != value; + formRows[index] = formRows[index].copyWith( type: value ?? FormDataType.text, ); - formRows[idx] = formRows[idx].copyWith(value: ""); + formRows[index] = formRows[index].copyWith(value: ""); if (isLast && hasChanged) { formRows.add(kFormDataEmptyModel); } @@ -87,118 +120,83 @@ class _FormDataBodyState extends ConsumerState { _onFieldChange(selectedId!); }, ), - ); - }, - sortable: false, - ), - DaviColumn( - width: 40, - cellPadding: kPv2, - cellAlignment: Alignment.center, - cellBuilder: (_, row) { - return Text( - "=", - style: kCodeStyle, - ); - }, - ), - DaviColumn( - name: kNameValue, - grow: 4, - cellPadding: kPv2, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == formRows.length; - return formRows[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.path.isNotEmpty) { - formRows[idx] = formRows[idx].copyWith( - value: pickedResult.path, - ); - setState(() {}); - _onFieldChange(selectedId!); - } - }, - label: Text( - (formRows[idx].type == FormDataType.file && - formRows[idx].value.isNotEmpty) - ? formRows[idx].value.toString() - : kLabelSelectFile, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - style: kFormDataButtonLabelTextStyle, - ), - ), - ), + ), + 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), ), - ], + ), + onPressed: () async { + var pickedResult = await pickFile(); + if (pickedResult != null && + pickedResult.path.isNotEmpty) { + formRows[index] = formRows[index].copyWith( + value: pickedResult.path, + ); + setState(() {}); + _onFieldChange(selectedId!); + } + }, + label: Text( + (formRows[index].type == FormDataType.file && + formRows[index].value.isNotEmpty) + ? formRows[index].value.toString() + : kLabelSelectFile, + overflow: TextOverflow.ellipsis, + style: kFormDataButtonLabelTextStyle, + ), + ) + : CellField( + keyId: "$selectedId-$index-form-v-$seed", + initialValue: formRows[index].value, + hintText: kHintAddValue, + onChanged: (value) { + formRows[index] = + formRows[index].copyWith(value: value); + if (isLast && !isAddingRow) { + isAddingRow = true; + formRows.add(kFormDataEmptyModel); + } + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, ), - ) - : CellField( - keyId: "$selectedId-$idx-form-v-$seed", - initialValue: formRows[idx].value, - hintText: kHintAddValue, - onChanged: (value) { - formRows[idx] = formRows[idx].copyWith(value: value); - if (isLast && !isAddingRow) { - isAddingRow = true; - formRows.add(kFormDataEmptyModel); - } - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - sortable: false, - ), - DaviColumn( - pinStatus: PinStatus.none, - width: 30, - cellBuilder: (_, row) { - bool isLast = row.index + 1 == formRows.length; - return InkWell( - onTap: isLast - ? null - : () { - seed = random.nextInt(kRandMax); - if (formRows.length == 2) { - setState(() { - formRows = [kFormDataEmptyModel]; - }); - } else { - formRows.removeAt(row.index); - } - _onFieldChange(selectedId!); - }, - child: Theme.of(context).brightness == Brightness.dark - ? kIconRemoveDark - : kIconRemoveLight, - ); - }, - ), - ], + ), + DataCell( + InkWell( + onTap: isLast + ? null + : () { + seed = random.nextInt(kRandMax); + if (formRows.length == 2) { + setState(() { + formRows = [ + kFormDataEmptyModel, + ]; + }); + } else { + formRows.removeAt(index); + } + _onFieldChange(selectedId!); + }, + child: Theme.of(context).brightness == Brightness.dark + ? kIconRemoveDark + : kIconRemoveLight, + ), + ), + ], + ); + }, ); + return Stack( children: [ Container( @@ -210,19 +208,30 @@ class _FormDataBodyState extends ConsumerState { child: Column( children: [ Expanded( - child: DaviTheme( - data: kTableThemeData, - child: Davi(daviModelRows), + 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, + ), ), ), - kVSpacer20, + kVSpacer40, ], ), ), Align( alignment: Alignment.bottomCenter, child: Padding( - padding: const EdgeInsets.only(bottom: 5), + padding: kPb15, child: ElevatedButton.icon( onPressed: () { formRows.add(kFormDataEmptyModel); diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart index ee5c574c..ab8efec3 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_headers.dart @@ -1,7 +1,7 @@ import 'dart:math'; import 'package:flutter/material.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/widgets/widgets.dart'; import 'package:apidash/models/models.dart'; @@ -43,133 +43,133 @@ class EditRequestHeadersState extends ConsumerState { .select((value) => value?.requestHeaders?.length)); var rH = ref.read(selectedRequestModelProvider)?.requestHeaders; bool isHeadersEmpty = rH == null || rH.isEmpty; - List rows = (isHeadersEmpty) + headerRows = isHeadersEmpty ? [ kNameValueEmptyModel, ] - : rH; - headerRows = isHeadersEmpty ? rows : rows + [kNameValueEmptyModel]; + : rH + [kNameValueEmptyModel]; isRowEnabledList = ref.read(selectedRequestModelProvider)?.isHeaderEnabledList ?? List.filled(rH?.length ?? 0, true, growable: true); isRowEnabledList.add(false); isAddingRow = false; - DaviModel model = DaviModel( - rows: headerRows, - columns: [ - DaviColumn( - name: kNameCheckbox, - width: 30, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == headerRows.length; - return CheckBox( - keyId: "$selectedId-$idx-headers-c-$seed", - value: isRowEnabledList[idx], - onChanged: isLast - ? null - : (value) { - setState(() { - isRowEnabledList[idx] = value!; - }); - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - ), - DaviColumn( - name: kNameHeader, - width: 70, - grow: 1, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == headerRows.length; - return HeaderField( - keyId: "$selectedId-$idx-headers-k-$seed", - initialValue: headerRows[idx].name, - hintText: kHintAddName, - onChanged: (value) { - headerRows[idx] = headerRows[idx].copyWith(name: value); - if (isLast && !isAddingRow) { - isAddingRow = true; - isRowEnabledList[idx] = true; - headerRows.add(kNameValueEmptyModel); - isRowEnabledList.add(false); - } - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - sortable: false, - ), - DaviColumn( - width: 30, - cellBuilder: (_, row) { - return Text( - "=", - style: kCodeStyle, - ); - }, - ), - DaviColumn( - name: kNameValue, - grow: 1, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == headerRows.length; - return CellField( - keyId: "$selectedId-$idx-headers-v-$seed", - initialValue: headerRows[idx].value, - hintText: kHintAddValue, - onChanged: (value) { - headerRows[idx] = headerRows[idx].copyWith(value: value); - if (isLast && !isAddingRow) { - isAddingRow = true; - isRowEnabledList[idx] = true; - headerRows.add(kNameValueEmptyModel); - isRowEnabledList.add(false); - } - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - sortable: false, - ), - DaviColumn( - pinStatus: PinStatus.none, - width: 30, - cellBuilder: (_, row) { - bool isLast = row.index + 1 == headerRows.length; - return InkWell( - onTap: isLast - ? null - : () { - seed = random.nextInt(kRandMax); - if (headerRows.length == 2) { + List columns = const [ + DataColumn2( + label: Text(kNameCheckbox), + fixedWidth: 30, + ), + DataColumn2( + label: Text(kNameHeader), + ), + DataColumn2( + label: Text('='), + fixedWidth: 30, + ), + DataColumn2( + label: Text(kNameValue), + ), + DataColumn2( + label: Text(''), + fixedWidth: 32, + ), + ]; + + List dataRows = List.generate( + headerRows.length, + (index) { + bool isLast = index + 1 == headerRows.length; + return DataRow( + key: ValueKey("$selectedId-$index-headers-row-$seed"), + cells: [ + DataCell( + CheckBox( + keyId: "$selectedId-$index-headers-c-$seed", + value: isRowEnabledList[index], + onChanged: isLast + ? null + : (value) { setState(() { - headerRows = [ - kNameValueEmptyModel, - ]; - isRowEnabledList = [false]; + isRowEnabledList[index] = value!; }); - } else { - headerRows.removeAt(row.index); - isRowEnabledList.removeAt(row.index); - } - _onFieldChange(selectedId!); - }, - child: Theme.of(context).brightness == Brightness.dark - ? kIconRemoveDark - : kIconRemoveLight, - ); - }, - ), - ], + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + HeaderField( + keyId: "$selectedId-$index-headers-k-$seed", + initialValue: headerRows[index].name, + hintText: kHintAddName, + onChanged: (value) { + headerRows[index] = headerRows[index].copyWith(name: value); + if (isLast && !isAddingRow) { + isAddingRow = true; + isRowEnabledList[index] = true; + headerRows.add(kNameValueEmptyModel); + isRowEnabledList.add(false); + } + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + Center( + child: Text( + "=", + style: kCodeStyle, + ), + ), + ), + DataCell( + CellField( + keyId: "$selectedId-$index-headers-v-$seed", + initialValue: headerRows[index].value, + hintText: kHintAddValue, + onChanged: (value) { + headerRows[index] = headerRows[index].copyWith(value: value); + if (isLast && !isAddingRow) { + isAddingRow = true; + isRowEnabledList[index] = true; + headerRows.add(kNameValueEmptyModel); + isRowEnabledList.add(false); + } + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + InkWell( + onTap: isLast + ? null + : () { + seed = random.nextInt(kRandMax); + if (headerRows.length == 2) { + setState(() { + headerRows = [ + kNameValueEmptyModel, + ]; + isRowEnabledList = [false]; + }); + } else { + headerRows.removeAt(index); + isRowEnabledList.removeAt(index); + } + _onFieldChange(selectedId!); + }, + child: Theme.of(context).brightness == Brightness.dark + ? kIconRemoveDark + : kIconRemoveLight, + ), + ), + ], + ); + }, ); + return Stack( children: [ Container( @@ -181,9 +181,20 @@ class EditRequestHeadersState extends ConsumerState { child: Column( children: [ Expanded( - child: DaviTheme( - data: kTableThemeData, - child: Davi(model), + 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, + ), ), ), kVSpacer40, diff --git a/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart b/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart index 47dca1a6..4b048c0a 100644 --- a/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart +++ b/lib/screens/home_page/editor_pane/details_card/request_pane/request_params.dart @@ -1,11 +1,11 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:davi/davi.dart'; import 'package:apidash/providers/providers.dart'; import 'package:apidash/widgets/widgets.dart'; import 'package:apidash/models/models.dart'; import 'package:apidash/consts.dart'; +import 'package:data_table_2/data_table_2.dart'; class EditRequestURLParams extends ConsumerStatefulWidget { const EditRequestURLParams({super.key}); @@ -43,133 +43,133 @@ class EditRequestURLParamsState extends ConsumerState { .select((value) => value?.requestParams?.length)); var rP = ref.read(selectedRequestModelProvider)?.requestParams; bool isParamsEmpty = rP == null || rP.isEmpty; - List rows = (isParamsEmpty) + paramRows = isParamsEmpty ? [ kNameValueEmptyModel, ] - : rP; - paramRows = isParamsEmpty ? rows : rows + [kNameValueEmptyModel]; + : rP + [kNameValueEmptyModel]; isRowEnabledList = ref.read(selectedRequestModelProvider)?.isParamEnabledList ?? List.filled(rP?.length ?? 0, true, growable: true); isRowEnabledList.add(false); isAddingRow = false; - DaviModel model = DaviModel( - rows: paramRows, - columns: [ - DaviColumn( - name: kNameCheckbox, - width: 30, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == paramRows.length; - return CheckBox( - keyId: "$selectedId-$idx-params-c-$seed", - value: isRowEnabledList[idx], - onChanged: isLast - ? null - : (value) { - setState(() { - isRowEnabledList[idx] = value!; - }); - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - ), - DaviColumn( - name: kNameURLParam, - width: 70, - grow: 1, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == paramRows.length; - return CellField( - keyId: "$selectedId-$idx-params-k-$seed", - initialValue: paramRows[idx].name, - hintText: kHintAddURLParam, - onChanged: (value) { - paramRows[idx] = paramRows[idx].copyWith(name: value); - if (isLast && !isAddingRow) { - isAddingRow = true; - isRowEnabledList[idx] = true; - paramRows.add(kNameValueEmptyModel); - isRowEnabledList.add(false); - } - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - sortable: false, - ), - DaviColumn( - width: 30, - cellBuilder: (_, row) { - return Text( - "=", - style: kCodeStyle, - ); - }, - ), - DaviColumn( - name: kNameValue, - grow: 1, - cellBuilder: (_, row) { - int idx = row.index; - bool isLast = idx + 1 == paramRows.length; - return CellField( - keyId: "$selectedId-$idx-params-v-$seed", - initialValue: paramRows[idx].value, - hintText: kHintAddValue, - onChanged: (value) { - paramRows[idx] = paramRows[idx].copyWith(value: value); - if (isLast && !isAddingRow) { - isAddingRow = true; - isRowEnabledList[idx] = true; - paramRows.add(kNameValueEmptyModel); - isRowEnabledList.add(false); - } - _onFieldChange(selectedId!); - }, - colorScheme: Theme.of(context).colorScheme, - ); - }, - sortable: false, - ), - DaviColumn( - pinStatus: PinStatus.none, - width: 30, - cellBuilder: (_, row) { - bool isLast = row.index + 1 == paramRows.length; - return InkWell( - onTap: isLast - ? null - : () { - seed = random.nextInt(kRandMax); - if (paramRows.length == 2) { + List columns = const [ + DataColumn2( + label: Text(kNameCheckbox), + fixedWidth: 30, + ), + DataColumn2( + label: Text(kNameURLParam), + ), + DataColumn2( + label: Text('='), + fixedWidth: 30, + ), + DataColumn2( + label: Text(kNameValue), + ), + DataColumn2( + label: Text(''), + fixedWidth: 32, + ), + ]; + + List dataRows = List.generate( + paramRows.length, + (index) { + bool isLast = index + 1 == paramRows.length; + return DataRow( + key: ValueKey("$selectedId-$index-params-row-$seed"), + cells: [ + DataCell( + CheckBox( + keyId: "$selectedId-$index-params-c-$seed", + value: isRowEnabledList[index], + onChanged: isLast + ? null + : (value) { setState(() { - paramRows = [ - kNameValueEmptyModel, - ]; - isRowEnabledList = [false]; + isRowEnabledList[index] = value!; }); - } else { - paramRows.removeAt(row.index); - isRowEnabledList.removeAt(row.index); - } - _onFieldChange(selectedId!); - }, - child: Theme.of(context).brightness == Brightness.dark - ? kIconRemoveDark - : kIconRemoveLight, - ); - }, - ), - ], + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + CellField( + keyId: "$selectedId-$index-params-k-$seed", + initialValue: paramRows[index].name, + hintText: kHintAddURLParam, + onChanged: (value) { + paramRows[index] = paramRows[index].copyWith(name: value); + if (isLast && !isAddingRow) { + isAddingRow = true; + isRowEnabledList[index] = true; + paramRows.add(kNameValueEmptyModel); + isRowEnabledList.add(false); + } + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + Center( + child: Text( + "=", + style: kCodeStyle, + ), + ), + ), + DataCell( + CellField( + keyId: "$selectedId-$index-params-v-$seed", + initialValue: paramRows[index].value, + hintText: kHintAddValue, + onChanged: (value) { + paramRows[index] = paramRows[index].copyWith(value: value); + if (isLast && !isAddingRow) { + isAddingRow = true; + isRowEnabledList[index] = true; + paramRows.add(kNameValueEmptyModel); + isRowEnabledList.add(false); + } + _onFieldChange(selectedId!); + }, + colorScheme: Theme.of(context).colorScheme, + ), + ), + DataCell( + InkWell( + onTap: isLast + ? null + : () { + seed = random.nextInt(kRandMax); + if (paramRows.length == 2) { + setState(() { + paramRows = [ + kNameValueEmptyModel, + ]; + isRowEnabledList = [false]; + }); + } else { + paramRows.removeAt(index); + isRowEnabledList.removeAt(index); + } + _onFieldChange(selectedId!); + }, + child: Theme.of(context).brightness == Brightness.dark + ? kIconRemoveDark + : kIconRemoveLight, + ), + ), + ], + ); + }, ); + return Stack( children: [ Container( @@ -179,11 +179,23 @@ class EditRequestURLParamsState extends ConsumerState { ), margin: kP10, child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( - child: DaviTheme( - data: kTableThemeData, - child: Davi(model), + 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, + ), ), ), kVSpacer40, diff --git a/lib/widgets/form_data_field.dart b/lib/widgets/form_data_field.dart deleted file mode 100644 index 29f210c4..00000000 --- a/lib/widgets/form_data_field.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:apidash/consts.dart'; -import 'package:flutter/material.dart'; -import 'dropdowns.dart'; - -class FormDataField extends StatefulWidget { - const FormDataField({ - super.key, - required this.keyId, - this.initialValue, - this.hintText, - this.onChanged, - this.colorScheme, - this.formDataType, - this.onFormDataTypeChanged, - }); - - final String keyId; - final String? initialValue; - final String? hintText; - final void Function(String)? onChanged; - final ColorScheme? colorScheme; - final FormDataType? formDataType; - final void Function(FormDataType?)? onFormDataTypeChanged; - - @override - State createState() => _FormDataFieldState(); -} - -class _FormDataFieldState extends State { - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - var colorScheme = widget.colorScheme ?? Theme.of(context).colorScheme; - return Row( - children: [ - Expanded( - flex: 1, - child: TextFormField( - initialValue: widget.initialValue, - key: Key(widget.keyId), - style: kCodeStyle.copyWith( - color: colorScheme.onSurface, - ), - decoration: InputDecoration( - hintStyle: kCodeStyle.copyWith( - color: colorScheme.outline.withOpacity( - kHintOpacity, - ), - ), - hintText: widget.hintText, - contentPadding: const EdgeInsets.only(bottom: 16), - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: colorScheme.primary.withOpacity( - kHintOpacity, - ), - ), - ), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: colorScheme.surfaceVariant, - ), - ), - suffixIcon: DropdownButtonFormData( - formDataType: widget.formDataType, - onChanged: (p0) { - if (widget.onFormDataTypeChanged != null) { - widget.onFormDataTypeChanged!(p0); - } - }, - ), - ), - onChanged: widget.onChanged, - ), - ), - ], - ); - } -} diff --git a/lib/widgets/headerfield.dart b/lib/widgets/headerfield.dart index 5bce6c8f..3d60caac 100644 --- a/lib/widgets/headerfield.dart +++ b/lib/widgets/headerfield.dart @@ -76,11 +76,14 @@ class _HeaderFieldState extends State { onChanged: widget.onChanged, controller: controller, focusNode: focusNode, - style: kCodeStyle.copyWith(color: colorScheme.onSurface), + style: kCodeStyle.copyWith( + color: colorScheme.onSurface, + ), decoration: InputDecoration( hintStyle: kCodeStyle.copyWith( color: colorScheme.outline.withOpacity(kHintOpacity)), hintText: widget.hintText, + contentPadding: const EdgeInsets.only(bottom: 12), focusedBorder: UnderlineInputBorder( borderSide: BorderSide( color: colorScheme.primary.withOpacity( diff --git a/lib/widgets/request_widgets.dart b/lib/widgets/request_widgets.dart index 7375a3b4..747cc8f4 100644 --- a/lib/widgets/request_widgets.dart +++ b/lib/widgets/request_widgets.dart @@ -93,6 +93,7 @@ class _RequestPaneState extends State ), ], ), + kVSpacer5, Expanded( child: TabBarView( controller: _controller, diff --git a/lib/widgets/textfields.dart b/lib/widgets/textfields.dart index 35d3437f..671be6ba 100644 --- a/lib/widgets/textfields.dart +++ b/lib/widgets/textfields.dart @@ -68,6 +68,7 @@ class CellField extends StatelessWidget { ), ), hintText: hintText, + contentPadding: const EdgeInsets.only(bottom: 12), focusedBorder: UnderlineInputBorder( borderSide: BorderSide( color: clrScheme.primary.withOpacity( diff --git a/lib/widgets/widgets.dart b/lib/widgets/widgets.dart index e4e842fb..4d249939 100644 --- a/lib/widgets/widgets.dart +++ b/lib/widgets/widgets.dart @@ -7,7 +7,6 @@ export 'dropdowns.dart'; export 'editor_json.dart'; export 'editor.dart'; export 'error_message.dart'; -export 'form_data_field.dart'; export 'headerfield.dart'; export 'intro_message.dart'; export 'json_previewer.dart'; diff --git a/pubspec.lock b/pubspec.lock index dfb8e077..d6235dec 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,14 +49,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.18" - axis_layout: - dependency: transitive - description: - name: axis_layout - sha256: "9ba44f279f39121065d811e72da892de86f5613d68eb0b295f60d021ea8f2a59" - url: "https://pub.dev" - source: hosted - version: "1.0.1" barcode: dependency: transitive description: @@ -249,14 +241,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.6" - davi: + data_table_2: dependency: "direct main" description: - name: davi - sha256: "4105870281c4c33e8e017e21e212b96fd2637b4c1a35b2a56f14aaa4acdf6f0d" + name: data_table_2 + sha256: fdb0551f103f1daf837bddfde14619fd9e683408833a618c9afabeb533fce88c url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "2.5.11" eventify: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 3cd9281e..528cda82 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,6 @@ dependencies: flutter_riverpod: ^2.5.1 riverpod: ^2.5.1 uuid: ^4.3.3 - davi: ^3.4.1 http: ^1.2.1 http_parser: ^4.0.2 collection: ^1.17.2 @@ -58,6 +57,7 @@ dependencies: dart_style: ^2.3.6 json_text_field: ^1.1.0 csv: ^6.0.0 + data_table_2: ^2.5.11 file_selector: ^1.0.3 dependency_overrides: diff --git a/test/widgets/form_data_field_test.dart b/test/widgets/form_data_field_test.dart deleted file mode 100644 index b5748370..00000000 --- a/test/widgets/form_data_field_test.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:apidash/widgets/form_data_field.dart'; - -void main() { - testWidgets('Testing for Form Data Widget', (tester) async { - await tester.pumpWidget( - const MaterialApp( - title: 'Form Data Field Widget', - home: Scaffold( - body: FormDataField( - keyId: "1", - initialValue: "Test Field", - ), - ), - ), - ); - - expect(find.text("Test Field"), findsOneWidget); - }); -}