mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-29 14:06:47 +00:00
Implementing a generic "ordering" option configuration for paginated list widget
This commit is contained in:
parent
9c4f6710ff
commit
c878f37ec2
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
|
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
|
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||||
|
|
||||||
import "package:inventree/api.dart";
|
import "package:inventree/api.dart";
|
||||||
|
import "package:inventree/api_form.dart";
|
||||||
import "package:inventree/helpers.dart";
|
import "package:inventree/helpers.dart";
|
||||||
import "package:inventree/inventree/bom.dart";
|
import "package:inventree/inventree/bom.dart";
|
||||||
import "package:inventree/l10.dart";
|
import "package:inventree/l10.dart";
|
||||||
@ -15,6 +16,7 @@ import "package:inventree/widget/part_detail.dart";
|
|||||||
import "package:inventree/widget/refreshable_state.dart";
|
import "package:inventree/widget/refreshable_state.dart";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Widget for displaying a list of BomItems for the specified 'parent' Part instance
|
* Widget for displaying a list of BomItems for the specified 'parent' Part instance
|
||||||
*/
|
*/
|
||||||
@ -30,7 +32,7 @@ class BomList extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class _BomListState extends RefreshableState<BomList> {
|
class _BomListState extends PaginatedState<BomList> {
|
||||||
|
|
||||||
_BomListState(this.parent);
|
_BomListState(this.parent);
|
||||||
|
|
||||||
@ -39,6 +41,15 @@ class _BomListState extends RefreshableState<BomList> {
|
|||||||
@override
|
@override
|
||||||
String getAppBarTitle(BuildContext context) => L10().billOfMaterials;
|
String getAppBarTitle(BuildContext context) => L10().billOfMaterials;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get prefix => "bom_";
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, String> get orderingOptions => {
|
||||||
|
"quantity": L10().quantity,
|
||||||
|
"part": L10().part,
|
||||||
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget getBody(BuildContext context) {
|
Widget getBody(BuildContext context) {
|
||||||
return PaginatedBomList({
|
return PaginatedBomList({
|
||||||
|
@ -3,9 +3,129 @@ import "package:flutter/material.dart";
|
|||||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||||
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
||||||
|
|
||||||
|
import "package:inventree/api_form.dart";
|
||||||
|
import "package:inventree/l10.dart";
|
||||||
|
|
||||||
import "package:inventree/inventree/model.dart";
|
import "package:inventree/inventree/model.dart";
|
||||||
import "package:inventree/inventree/sentry.dart";
|
import "package:inventree/inventree/sentry.dart";
|
||||||
import "package:inventree/l10.dart";
|
import "package:inventree/preferences.dart";
|
||||||
|
|
||||||
|
import "package:inventree/widget/refreshable_state.dart";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic widget class for displaying a "paginated list".
|
||||||
|
* Provides some basic functionality for adjusting ordering and filtering options
|
||||||
|
*/
|
||||||
|
abstract class PaginatedState<T extends StatefulWidget> extends RefreshableState<T> {
|
||||||
|
|
||||||
|
// Prefix for storing and loading pagination options
|
||||||
|
String get prefix => "prefix_";
|
||||||
|
|
||||||
|
// Ordering options for this paginated state (override in implementing class)
|
||||||
|
Map<String, String> get orderingOptions => {};
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Widget> getAppBarActions(BuildContext context) {
|
||||||
|
List<Widget> actions = [];
|
||||||
|
|
||||||
|
// If ordering options have been provided
|
||||||
|
if (orderingOptions.isNotEmpty) {
|
||||||
|
actions.add(IconButton(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.sort),
|
||||||
|
onPressed: () => _updateFilters(context),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the selected ordering "field" for this list widget
|
||||||
|
Future<String> orderingField() async {
|
||||||
|
dynamic field = await InvenTreeSettingsManager().getValue("${prefix}ordering_field", null);
|
||||||
|
|
||||||
|
if (field != null) {
|
||||||
|
return field.toString();
|
||||||
|
} else if (orderingOptions.isNotEmpty) {
|
||||||
|
// By default, return the first specified key
|
||||||
|
return orderingOptions.keys.first;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the selected ordering "order" ("+" or "-") for this list widget
|
||||||
|
Future<String> orderingOrder() async {
|
||||||
|
dynamic order = await InvenTreeSettingsManager().getValue("${prefix}ordering_order", "+");
|
||||||
|
|
||||||
|
return order == "+" ? "+" : "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the (configurable) filters for this paginated list
|
||||||
|
Future<void> _updateFilters(BuildContext context) async {
|
||||||
|
|
||||||
|
// Retrieve stored setting
|
||||||
|
dynamic _field = await orderingField();
|
||||||
|
dynamic _order = await orderingOrder();
|
||||||
|
|
||||||
|
// Construct the 'ordering' options
|
||||||
|
List<Map<String, dynamic>> _opts = [];
|
||||||
|
|
||||||
|
orderingOptions.forEach((k, v) => _opts.add({
|
||||||
|
"value": k.toString(),
|
||||||
|
"display_name": v.toString()
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (_field == null && _opts.isNotEmpty) {
|
||||||
|
_field = _opts.first["value"];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> fields = {
|
||||||
|
"ordering_field": {
|
||||||
|
"type": "choice",
|
||||||
|
"label": "Ordering Field",
|
||||||
|
"required": true,
|
||||||
|
"choices": _opts,
|
||||||
|
"value": _field,
|
||||||
|
},
|
||||||
|
"ordering_order": {
|
||||||
|
"type": "choice",
|
||||||
|
"label": "Ordering Direction",
|
||||||
|
"required": true,
|
||||||
|
"value": _order,
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"value": "+",
|
||||||
|
"display_name": "Ascending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "-",
|
||||||
|
"display_name": "Descending",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
"...filtering...",
|
||||||
|
"",
|
||||||
|
fields,
|
||||||
|
icon: FontAwesomeIcons.checkCircle,
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Save values to settings
|
||||||
|
await InvenTreeSettingsManager().setValue("${prefix}ordering_field", f);
|
||||||
|
await InvenTreeSettingsManager().setValue("${prefix}ordering_order", o);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class PaginatedSearchState<T extends StatefulWidget> extends State<T> {
|
class PaginatedSearchState<T extends StatefulWidget> extends State<T> {
|
||||||
@ -21,6 +141,10 @@ class PaginatedSearchState<T extends StatefulWidget> extends State<T> {
|
|||||||
|
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
|
|
||||||
|
// List of variables by which the list can be "ordered".
|
||||||
|
// Override in any implementing sub-class
|
||||||
|
List<String> orderingFilters = [];
|
||||||
|
|
||||||
// Text controller
|
// Text controller
|
||||||
final TextEditingController searchController = TextEditingController();
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user