From 6d0282519d04441df63ee9af613ed2521faf0638 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 10 Aug 2021 14:33:08 +1000 Subject: [PATCH] API forms return the JSON data to the onSuccess function --- lib/api_form.dart | 60 ++++++++++++++++++++++++-------- lib/inventree/model.dart | 23 ++++++++++-- lib/widget/category_display.dart | 35 ++++++++++++++----- lib/widget/company_detail.dart | 4 ++- lib/widget/location_display.dart | 4 ++- lib/widget/part_detail.dart | 4 ++- lib/widget/part_notes.dart | 2 +- lib/widget/stock_detail.dart | 4 ++- lib/widget/stock_notes.dart | 2 +- 9 files changed, 107 insertions(+), 31 deletions(-) diff --git a/lib/api_form.dart b/lib/api_form.dart index 1b18b841..5cd97af5 100644 --- a/lib/api_form.dart +++ b/lib/api_form.dart @@ -7,6 +7,7 @@ import 'package:inventree/api.dart'; import 'package:inventree/app_colors.dart'; import 'package:inventree/inventree/part.dart'; import 'package:inventree/inventree/stock.dart'; +import 'package:inventree/widget/dialogs.dart'; import 'package:inventree/widget/fields.dart'; import 'package:inventree/l10.dart'; @@ -420,7 +421,7 @@ Map extractFields(APIResponse response) { * @param method is the HTTP method to use to send the form data to the server (e.g. POST / PATCH) */ -Future launchApiForm(BuildContext context, String title, String url, Map fields, {Map modelData = const {}, String method = "PATCH", Function? onSuccess, Function? onCancel}) async { +Future launchApiForm(BuildContext context, String title, String url, Map fields, {Map modelData = const {}, String method = "PATCH", Function(Map)? onSuccess, Function? onCancel}) async { var options = await InvenTreeAPI().options(url); @@ -503,6 +504,7 @@ Future launchApiForm(BuildContext context, String title, String url, Map fields; - Function? onSuccess; + Function(Map)? onSuccess; APIFormWidget( this.title, this.url, this.fields, + this.method, { Key? key, this.onSuccess, @@ -532,7 +538,7 @@ class APIFormWidget extends StatefulWidget { ) : super(key: key); @override - _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, onSuccess); + _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess); } @@ -545,11 +551,13 @@ class _APIFormWidgetState extends State { String url; + String method; + List fields; - Function? onSuccess; + Function(Map)? onSuccess; - _APIFormWidgetState(this.title, this.url, this.fields, this.onSuccess) : super(); + _APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess) : super(); List _buildForm() { @@ -584,30 +592,42 @@ class _APIFormWidgetState extends State { return widgets; } + Future _submit(Map data) async { + + if (method == "POST") { + return await InvenTreeAPI().post( + url, + body: data + ); + } else { + return await InvenTreeAPI().patch( + url, + body: data, + ); + } + + } + Future _save(BuildContext context) async { // Package up the form data - Map _data = {}; + Map data = {}; for (var field in fields) { dynamic value = field.value; if (value == null) { - _data[field.name] = ""; + data[field.name] = ""; } else { - _data[field.name] = value.toString(); + data[field.name] = value.toString(); } } - // TODO: Handle "POST" forms too!! - final response = await InvenTreeAPI().patch( - url, - body: _data, - ); + final response = await _submit(data); if (!response.isValid()) { - // TODO: Display an error message! + showServerError(L10().serverError, L10().responseInvalid); return; } @@ -625,7 +645,17 @@ class _APIFormWidgetState extends State { var successFunc = onSuccess; if (successFunc != null) { - successFunc(); + + // Ensure the response is a valid JSON structure + Map json = {}; + + if (response.data != null && response.data is Map) { + for (dynamic key in response.data.keys) { + json[key.toString()] = response.data[key]; + } + } + + successFunc(json); } return; case 400: diff --git a/lib/inventree/model.dart b/lib/inventree/model.dart index da264810..11476b7a 100644 --- a/lib/inventree/model.dart +++ b/lib/inventree/model.dart @@ -72,7 +72,25 @@ class InvenTreeModel { return {}; } - Future editForm(BuildContext context, String title, {Map fields=const {}, Function? onSuccess}) async { + Future createForm(BuildContext context, String title, {Map fields=const{}, Map data=const {}, Function(dynamic)? onSuccess}) async { + + if (fields.isEmpty) { + fields = formFields(); + } + + launchApiForm( + context, + title, + URL, + fields, + modelData: data, + onSuccess: onSuccess, + method: "POST", + ); + + } + + Future editForm(BuildContext context, String title, {Map fields=const {}, Function(dynamic)? onSuccess}) async { if (fields.isEmpty) { fields = formFields(); @@ -84,7 +102,8 @@ class InvenTreeModel { url, fields, modelData: jsondata, - onSuccess: onSuccess + onSuccess: onSuccess, + method: "PATCH" ); } diff --git a/lib/widget/category_display.dart b/lib/widget/category_display.dart index 9bea0a43..50fea627 100644 --- a/lib/widget/category_display.dart +++ b/lib/widget/category_display.dart @@ -67,7 +67,13 @@ class _CategoryDisplayState extends RefreshableState { return; } - _cat.editForm(context, L10().editCategory, onSuccess: refresh); + _cat.editForm( + context, + L10().editCategory, + onSuccess: (data) async { + refresh(); + } + ); } _CategoryDisplayState(this.category); @@ -211,14 +217,27 @@ class _CategoryDisplayState extends RefreshableState { int pk = category?.pk ?? -1; - launchApiForm( - context, - L10().categoryCreate, - InvenTreePartCategory().URL, - InvenTreePartCategory().formFields(), - modelData: { - "parent": (pk > 0) ? pk : null, + InvenTreePartCategory().createForm( + context, + L10().categoryCreate, + data: { + "parent": (pk > 0) ? pk : null, + }, + onSuccess: (data) async { + + if (data.containsKey("pk")) { + var new_cat = InvenTreePartCategory.fromJson(data); + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CategoryDisplayWidget(new_cat) + ) + ); + } else { + refresh(); } + } ); } diff --git a/lib/widget/company_detail.dart b/lib/widget/company_detail.dart index bccfaa1a..f44ae69d 100644 --- a/lib/widget/company_detail.dart +++ b/lib/widget/company_detail.dart @@ -79,7 +79,9 @@ class _CompanyDetailState extends RefreshableState { "currency": {}, }, modelData: company.jsondata, - onSuccess: refresh + onSuccess: (data) async { + refresh(); + } ); } diff --git a/lib/widget/location_display.dart b/lib/widget/location_display.dart index cab65a1f..7d7b15c9 100644 --- a/lib/widget/location_display.dart +++ b/lib/widget/location_display.dart @@ -94,7 +94,9 @@ class _LocationDisplayState extends RefreshableState { "parent": {}, }, modelData: _loc.jsondata, - onSuccess: refresh + onSuccess: (data) async { + refresh(); + } ); } diff --git a/lib/widget/part_detail.dart b/lib/widget/part_detail.dart index e50c04a5..bea6a92e 100644 --- a/lib/widget/part_detail.dart +++ b/lib/widget/part_detail.dart @@ -126,7 +126,9 @@ class _PartDisplayState extends RefreshableState { "virtual": {}, }, modelData: part.jsondata, - onSuccess: refresh, + onSuccess: (data) async { + refresh(); + }, ); } diff --git a/lib/widget/part_notes.dart b/lib/widget/part_notes.dart index 1abea016..d069b271 100644 --- a/lib/widget/part_notes.dart +++ b/lib/widget/part_notes.dart @@ -56,7 +56,7 @@ class _PartNotesState extends RefreshableState { } }, modelData: part.jsondata, - onSuccess: () async { + onSuccess: (data) async { refresh(); } ); diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart index 2f7e6103..f0e661b7 100644 --- a/lib/widget/stock_detail.dart +++ b/lib/widget/stock_detail.dart @@ -120,7 +120,9 @@ class _StockItemDisplayState extends RefreshableState { "link": {}, }, modelData: item.jsondata, - onSuccess: refresh + onSuccess: (data) async { + refresh(); + } ); } diff --git a/lib/widget/stock_notes.dart b/lib/widget/stock_notes.dart index 1034605e..60214600 100644 --- a/lib/widget/stock_notes.dart +++ b/lib/widget/stock_notes.dart @@ -56,7 +56,7 @@ class _StockNotesState extends RefreshableState { } }, modelData: item.jsondata, - onSuccess: () { + onSuccess: (data) async { refresh(); } );