mirror of
https://github.com/inventree/inventree-app.git
synced 2025-07-01 11:20:41 +00:00
Format Code and Add Format Checks to CI (#643)
* Remove unused lib/generated/i18n.dart * Use `fvm dart format .` * Add contributing guidelines * Enforce dart format * Add `dart format off` directive to generated files
This commit is contained in:
@ -15,12 +15,10 @@ import "package:inventree/preferences.dart";
|
||||
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
|
||||
|
||||
/*
|
||||
* Abstract base widget class for rendering a PaginatedSearchState
|
||||
*/
|
||||
abstract class PaginatedSearchWidget extends StatefulWidget {
|
||||
|
||||
const PaginatedSearchWidget({this.filters = const {}, this.title = ""});
|
||||
|
||||
final String title;
|
||||
@ -30,12 +28,12 @@ abstract class PaginatedSearchWidget extends StatefulWidget {
|
||||
final Map<String, String> filters;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generic stateful widget for displaying paginated data retrieved via the API
|
||||
*/
|
||||
abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends State<T> with BaseWidgetProperties {
|
||||
|
||||
abstract class PaginatedSearchState<T extends PaginatedSearchWidget>
|
||||
extends State<T>
|
||||
with BaseWidgetProperties {
|
||||
static const _pageSize = 25;
|
||||
|
||||
bool showSearchWidget = false;
|
||||
@ -73,7 +71,6 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Construct the boolean filter options for this list
|
||||
Future<Map<String, String>> constructFilters() async {
|
||||
|
||||
Map<String, String> f = {};
|
||||
|
||||
for (String k in filterOptions.keys) {
|
||||
@ -95,7 +92,10 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Return the selected ordering "field" for this list widget
|
||||
Future<String> orderingField() async {
|
||||
dynamic field = await InvenTreeSettingsManager().getValue("${prefix}ordering_field", null);
|
||||
dynamic field = await InvenTreeSettingsManager().getValue(
|
||||
"${prefix}ordering_field",
|
||||
null,
|
||||
);
|
||||
|
||||
if (field != null && orderingOptions.containsKey(field.toString())) {
|
||||
// A valid ordering field has been found
|
||||
@ -110,7 +110,10 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Return the selected ordering "order" ("+" or "-") for this list widget
|
||||
Future<String> orderingOrder() async {
|
||||
dynamic order = await InvenTreeSettingsManager().getValue("${prefix}ordering_order", "+");
|
||||
dynamic order = await InvenTreeSettingsManager().getValue(
|
||||
"${prefix}ordering_order",
|
||||
"+",
|
||||
);
|
||||
|
||||
return order == "+" ? "+" : "-";
|
||||
}
|
||||
@ -137,10 +140,10 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
// Construct the 'ordering' options
|
||||
List<Map<String, dynamic>> _opts = [];
|
||||
|
||||
orderingOptions.forEach((k, v) => _opts.add({
|
||||
"value": k.toString(),
|
||||
"display_name": v.toString()
|
||||
}));
|
||||
orderingOptions.forEach(
|
||||
(k, v) =>
|
||||
_opts.add({"value": k.toString(), "display_name": v.toString()}),
|
||||
);
|
||||
|
||||
if (_field == null && _opts.isNotEmpty) {
|
||||
_field = _opts.first["value"];
|
||||
@ -160,16 +163,10 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
"required": true,
|
||||
"value": _order,
|
||||
"choices": [
|
||||
{
|
||||
"value": "+",
|
||||
"display_name": "Ascending",
|
||||
},
|
||||
{
|
||||
"value": "-",
|
||||
"display_name": "Descending",
|
||||
}
|
||||
]
|
||||
}
|
||||
{"value": "+", "display_name": "Ascending"},
|
||||
{"value": "-", "display_name": "Descending"},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// Add in selected filter options
|
||||
@ -219,7 +216,6 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
fields,
|
||||
icon: TablerIcons.circle_check,
|
||||
onSuccess: (Map<String, dynamic> data) async {
|
||||
|
||||
// Extract data from the processed form
|
||||
String f = (data["ordering_field"] ?? _field) as String;
|
||||
String o = (data["ordering_order"] ?? _order) as String;
|
||||
@ -235,7 +231,7 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Refresh data from the server
|
||||
_pagingController.refresh();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -245,7 +241,6 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
int resultCount = 0;
|
||||
|
||||
String resultsString() {
|
||||
|
||||
if (resultCount <= 0) {
|
||||
return noResultsText;
|
||||
} else {
|
||||
@ -260,7 +255,8 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
Timer? _debounceTimer;
|
||||
|
||||
// Pagination controller
|
||||
final PagingController<int, InvenTreeModel> _pagingController = PagingController(firstPageKey: 0);
|
||||
final PagingController<int, InvenTreeModel> _pagingController =
|
||||
PagingController(firstPageKey: 0);
|
||||
|
||||
void refresh() {
|
||||
_pagingController.refresh();
|
||||
@ -286,8 +282,11 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
* Each implementing class must override this function,
|
||||
* and return an InvenTreePageResponse object with the correct data format
|
||||
*/
|
||||
Future<InvenTreePageResponse?> requestPage(int limit, int offset, Map<String, String> params) async {
|
||||
|
||||
Future<InvenTreePageResponse?> requestPage(
|
||||
int limit,
|
||||
int offset,
|
||||
Map<String, String> params,
|
||||
) async {
|
||||
// Default implementation returns null - must be overridden
|
||||
return null;
|
||||
}
|
||||
@ -301,7 +300,6 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Include user search term
|
||||
if (searchTerm.isNotEmpty) {
|
||||
|
||||
String _search = searchTerm;
|
||||
|
||||
// Include original search in search test
|
||||
@ -329,11 +327,7 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
params.addAll(f);
|
||||
}
|
||||
|
||||
final page = await requestPage(
|
||||
_pageSize,
|
||||
pageKey,
|
||||
params
|
||||
);
|
||||
final page = await requestPage(_pageSize, pageKey, params);
|
||||
|
||||
// We may have disposed of the widget while the request was in progress
|
||||
// If this is the case, abort
|
||||
@ -350,7 +344,7 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
if (page != null) {
|
||||
for (var result in page.results) {
|
||||
items.add(result);
|
||||
items.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,16 +361,12 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
} catch (error, stackTrace) {
|
||||
_pagingController.error = error;
|
||||
|
||||
sentryReportError(
|
||||
"paginator.fetchPage",
|
||||
error, stackTrace,
|
||||
);
|
||||
sentryReportError("paginator.fetchPage", error, stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback function when the search term is updated
|
||||
void updateSearchTerm() {
|
||||
|
||||
if (searchTerm == searchController.text) {
|
||||
// No change
|
||||
return;
|
||||
@ -410,7 +400,6 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
// Function to construct a single paginated item
|
||||
// Must be overridden in an implementing subclass
|
||||
Widget buildItem(BuildContext context, InvenTreeModel item) {
|
||||
|
||||
// This method must be overridden by the child class
|
||||
return ListTile(
|
||||
title: Text("*** UNIMPLEMENTED ***"),
|
||||
@ -423,12 +412,8 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
String get noResultsText => L10().noResults;
|
||||
|
||||
@override
|
||||
Widget build (BuildContext context) {
|
||||
|
||||
List<Widget> children = [
|
||||
buildTitleWidget(context),
|
||||
Divider(),
|
||||
];
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> children = [buildTitleWidget(context), Divider()];
|
||||
|
||||
if (showSearchWidget) {
|
||||
children.add(buildSearchInput(context));
|
||||
@ -436,26 +421,26 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
children.add(
|
||||
Expanded(
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: <Widget>[
|
||||
PagedSliverList.separated(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<InvenTreeModel>(
|
||||
itemBuilder: (ctx, item, index) {
|
||||
return buildItem(ctx, item);
|
||||
},
|
||||
noItemsFoundIndicatorBuilder: (context) {
|
||||
return NoResultsWidget(noResultsText);
|
||||
}
|
||||
),
|
||||
separatorBuilder: (context, item) => const Divider(height: 1),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
child: CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: <Widget>[
|
||||
PagedSliverList.separated(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<InvenTreeModel>(
|
||||
itemBuilder: (ctx, item, index) {
|
||||
return buildItem(ctx, item);
|
||||
},
|
||||
noItemsFoundIndicatorBuilder: (context) {
|
||||
return NoResultsWidget(noResultsText);
|
||||
},
|
||||
),
|
||||
separatorBuilder: (context, item) => const Divider(height: 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return RefreshIndicator(
|
||||
@ -473,28 +458,34 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
* Build the title widget for this list
|
||||
*/
|
||||
Widget buildTitleWidget(BuildContext context) {
|
||||
|
||||
const double icon_size = 32;
|
||||
|
||||
List<Widget> _icons = [];
|
||||
|
||||
if (filterOptions.isNotEmpty || orderingOptions.isNotEmpty) {
|
||||
_icons.add(IconButton(
|
||||
onPressed: () async {
|
||||
_setOrderingOptions(context);
|
||||
},
|
||||
icon: Icon(Icons.filter_alt, size: icon_size)
|
||||
));
|
||||
_icons.add(
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
_setOrderingOptions(context);
|
||||
},
|
||||
icon: Icon(Icons.filter_alt, size: icon_size),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_icons.add(IconButton(
|
||||
_icons.add(
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
showSearchWidget = !showSearchWidget;
|
||||
});
|
||||
},
|
||||
icon: Icon(showSearchWidget ? Icons.zoom_out : Icons.search, size: icon_size)
|
||||
));
|
||||
icon: Icon(
|
||||
showSearchWidget ? Icons.zoom_out : Icons.search,
|
||||
size: icon_size,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// _icons.add(IconButton(
|
||||
// onPressed: () async {
|
||||
@ -506,20 +497,13 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
return ListTile(
|
||||
title: Text(
|
||||
widget.searchTitle,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text(
|
||||
"${L10().results}: ${resultCount}",
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic
|
||||
),
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _icons,
|
||||
style: TextStyle(fontStyle: FontStyle.italic),
|
||||
),
|
||||
trailing: Row(mainAxisSize: MainAxisSize.min, children: _icons),
|
||||
);
|
||||
}
|
||||
|
||||
@ -530,7 +514,9 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
return ListTile(
|
||||
trailing: GestureDetector(
|
||||
child: Icon(
|
||||
searchController.text.isEmpty ? TablerIcons.search : TablerIcons.backspace,
|
||||
searchController.text.isEmpty
|
||||
? TablerIcons.search
|
||||
: TablerIcons.backspace,
|
||||
color: searchController.text.isNotEmpty ? COLOR_DANGER : COLOR_ACTION,
|
||||
),
|
||||
onTap: () {
|
||||
@ -545,31 +531,22 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
onChanged: (value) {
|
||||
updateSearchTerm();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: L10().search,
|
||||
),
|
||||
)
|
||||
decoration: InputDecoration(hintText: L10().search),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class NoResultsWidget extends StatelessWidget {
|
||||
|
||||
const NoResultsWidget(this.description);
|
||||
|
||||
final String description;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return ListTile(
|
||||
title: Text(
|
||||
description,
|
||||
style: TextStyle(fontStyle: FontStyle.italic),
|
||||
),
|
||||
title: Text(description, style: TextStyle(fontStyle: FontStyle.italic)),
|
||||
leading: Icon(TablerIcons.exclamation_circle, color: COLOR_WARNING),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user