mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-31 13:25:40 +00:00 
			
		
		
		
	API_Form: Allow customizable icon
- Also fixes for API search
This commit is contained in:
		| @@ -559,7 +559,16 @@ Map<String, dynamic> extractFields(APIResponse response) { | ||||
|  * @param method is the HTTP method to use to send the form data to the server (e.g. POST / PATCH) | ||||
|  */ | ||||
|  | ||||
| Future<void> launchApiForm(BuildContext context, String title, String url, Map<String, dynamic> fields, {String fileField = "", Map<String, dynamic> modelData = const {}, String method = "PATCH", Function(Map<String, dynamic>)? onSuccess, Function? onCancel}) async { | ||||
| Future<void> launchApiForm( | ||||
|     BuildContext context, String title, String url, Map<String, dynamic> fields, | ||||
|     { | ||||
|       String fileField = "", | ||||
|       Map<String, dynamic> modelData = const {}, | ||||
|       String method = "PATCH", | ||||
|       Function(Map<String, dynamic>)? onSuccess, | ||||
|       Function? onCancel, | ||||
|       IconData icon = FontAwesomeIcons.save, | ||||
|     }) async { | ||||
|  | ||||
|   var options = await InvenTreeAPI().options(url); | ||||
|  | ||||
| @@ -641,12 +650,13 @@ Future<void> launchApiForm(BuildContext context, String title, String url, Map<S | ||||
|   Navigator.push( | ||||
|     context, | ||||
|     MaterialPageRoute(builder: (context) => APIFormWidget( | ||||
|         title, | ||||
|         url, | ||||
|         formFields, | ||||
|         method, | ||||
|         onSuccess: onSuccess, | ||||
|         fileField: fileField, | ||||
|       title, | ||||
|       url, | ||||
|       formFields, | ||||
|       method, | ||||
|       onSuccess: onSuccess, | ||||
|       fileField: fileField, | ||||
|       icon: icon, | ||||
|     )) | ||||
|   ); | ||||
| } | ||||
| @@ -663,6 +673,7 @@ class APIFormWidget extends StatefulWidget { | ||||
|         Key? key, | ||||
|         this.onSuccess, | ||||
|         this.fileField = "", | ||||
|         this.icon = FontAwesomeIcons.save, | ||||
|       } | ||||
|       ) : super(key: key); | ||||
|  | ||||
| @@ -677,29 +688,34 @@ class APIFormWidget extends StatefulWidget { | ||||
|  | ||||
|   final String fileField; | ||||
|  | ||||
|   // Icon | ||||
|   final IconData icon; | ||||
|  | ||||
|   final List<APIFormField> fields; | ||||
|  | ||||
|   final Function(Map<String, dynamic>)? onSuccess; | ||||
|  | ||||
|   @override | ||||
|   _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess, fileField); | ||||
|   _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess, fileField, icon); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| class _APIFormWidgetState extends State<APIFormWidget> { | ||||
|  | ||||
|   _APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess, this.fileField) : super(); | ||||
|   _APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess, this.fileField, this.icon) : super(); | ||||
|  | ||||
|   final _formKey = GlobalKey<FormState>(); | ||||
|  | ||||
|   String title; | ||||
|   final String title; | ||||
|  | ||||
|   String url; | ||||
|   final String url; | ||||
|  | ||||
|   String method; | ||||
|   final String method; | ||||
|  | ||||
|   String fileField; | ||||
|   final String fileField; | ||||
|  | ||||
|   final IconData icon; | ||||
|  | ||||
|   List<APIFormField> fields; | ||||
|  | ||||
| @@ -878,6 +894,12 @@ class _APIFormWidgetState extends State<APIFormWidget> { | ||||
|           field.data["errors"] = response.data[field.name]; | ||||
|         } | ||||
|         break; | ||||
|       case 405: | ||||
|         showSnackIcon( | ||||
|           L10().response405, | ||||
|           success: false, | ||||
|         ); | ||||
|         break; | ||||
|       // TODO: Other status codes? | ||||
|     } | ||||
|  | ||||
| @@ -895,7 +917,7 @@ class _APIFormWidgetState extends State<APIFormWidget> { | ||||
|         title: Text(title), | ||||
|         actions: [ | ||||
|           IconButton( | ||||
|             icon: FaIcon(FontAwesomeIcons.save), | ||||
|             icon: FaIcon(icon), | ||||
|             onPressed: () { | ||||
|  | ||||
|               if (_formKey.currentState!.validate()) { | ||||
|   | ||||
| @@ -118,7 +118,7 @@ class InvenTreeModel { | ||||
|   Map<String, dynamic> jsondata = {}; | ||||
|  | ||||
|   // Accessor for the API | ||||
|   InvenTreeAPI api = InvenTreeAPI(); | ||||
|   InvenTreeAPI get api => InvenTreeAPI(); | ||||
|  | ||||
|   int get pk => (jsondata["pk"] ?? -1) as int; | ||||
|  | ||||
| @@ -167,11 +167,19 @@ class InvenTreeModel { | ||||
|   String get url => "${URL}/${pk}/".replaceAll("//", "/"); | ||||
|  | ||||
|   // Search this Model type in the database | ||||
|   Future<List<InvenTreeModel>> search(BuildContext context, String searchTerm, {Map<String, String> filters = const {}}) async { | ||||
|   Future<List<InvenTreeModel>> search(String searchTerm, {Map<String, String> filters = const {}, int offset = 0, int limit = 25}) async { | ||||
|  | ||||
|     filters["search"] = searchTerm; | ||||
|     Map<String, String> searchFilters = {}; | ||||
|  | ||||
|     final results = list(filters: filters); | ||||
|     for (String key in filters.keys) { | ||||
|       searchFilters[key] = filters[key] ?? ""; | ||||
|     } | ||||
|  | ||||
|     searchFilters["search"] = searchTerm; | ||||
|     searchFilters["offset"] = "${offset}"; | ||||
|     searchFilters["limit"] = "${limit}"; | ||||
|  | ||||
|     final results = list(filters: searchFilters); | ||||
|  | ||||
|     return results; | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,8 @@ class InvenTreePurchaseOrder extends InvenTreeModel { | ||||
|   @override | ||||
|   String get URL => "order/po/"; | ||||
|  | ||||
|   String get receive_url => "${url}receive/"; | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> formFields() { | ||||
|     return { | ||||
|   | ||||
| @@ -71,7 +71,7 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart?> { | ||||
|  | ||||
|     _filters["cascade"] = "true"; | ||||
|  | ||||
|     final results = await InvenTreePart().search(context, query, filters: _filters); | ||||
|     final results = await InvenTreePart().search(query, filters: _filters); | ||||
|  | ||||
|     partResults.clear(); | ||||
|  | ||||
| @@ -260,8 +260,7 @@ class StockSearchDelegate extends SearchDelegate<InvenTreeStockItem?> { | ||||
|     // Enable cascading part search by default | ||||
|     _filters["cascade"] = "true"; | ||||
|  | ||||
|     final results = await InvenTreeStockItem().search( | ||||
|         context, query, filters: _filters); | ||||
|     final results = await InvenTreeStockItem().search(query, filters: _filters); | ||||
|  | ||||
|     itemResults.clear(); | ||||
|  | ||||
|   | ||||
| @@ -327,13 +327,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> { | ||||
|             }, | ||||
|             onFind: (String filter) async { | ||||
|  | ||||
|               Map<String, String> _filters = { | ||||
|                 "search": filter, | ||||
|                 "offset": "0", | ||||
|                 "limit": "25" | ||||
|               }; | ||||
|  | ||||
|               final List<InvenTreeModel> results = await InvenTreeStockLocation().list(filters: _filters); | ||||
|               final results = await InvenTreeStockLocation().search(filter); | ||||
|  | ||||
|               List<dynamic> items = []; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user