mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-31 21:35:42 +00:00 
			
		
		
		
	Implementing a generic "ordering" option configuration for paginated list widget
This commit is contained in:
		| @@ -1,8 +1,9 @@ | ||||
|  | ||||
|  | ||||
| import "package:flutter/material.dart"; | ||||
| import "package:font_awesome_flutter/font_awesome_flutter.dart"; | ||||
|  | ||||
| import "package:inventree/api.dart"; | ||||
| import "package:inventree/api_form.dart"; | ||||
| import "package:inventree/helpers.dart"; | ||||
| import "package:inventree/inventree/bom.dart"; | ||||
| import "package:inventree/l10.dart"; | ||||
| @@ -15,6 +16,7 @@ import "package:inventree/widget/part_detail.dart"; | ||||
| import "package:inventree/widget/refreshable_state.dart"; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * 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); | ||||
|  | ||||
| @@ -39,6 +41,15 @@ class _BomListState extends RefreshableState<BomList> { | ||||
|   @override | ||||
|   String getAppBarTitle(BuildContext context) => L10().billOfMaterials; | ||||
|  | ||||
|   @override | ||||
|   String get prefix => "bom_"; | ||||
|  | ||||
|   @override | ||||
|   Map<String, String> get orderingOptions => { | ||||
|     "quantity": L10().quantity, | ||||
|     "part": L10().part, | ||||
|   }; | ||||
|  | ||||
|   @override | ||||
|   Widget getBody(BuildContext context) { | ||||
|     return PaginatedBomList({ | ||||
|   | ||||
| @@ -3,9 +3,129 @@ import "package:flutter/material.dart"; | ||||
| import "package:font_awesome_flutter/font_awesome_flutter.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/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> { | ||||
| @@ -21,6 +141,10 @@ class PaginatedSearchState<T extends StatefulWidget> extends State<T> { | ||||
|  | ||||
|   int resultCount = 0; | ||||
|  | ||||
|   // List of variables by which the list can be "ordered". | ||||
|   // Override in any implementing sub-class | ||||
|   List<String> orderingFilters = []; | ||||
|  | ||||
|   // Text controller | ||||
|   final TextEditingController searchController = TextEditingController(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user