2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

API forms return the JSON data to the onSuccess function

This commit is contained in:
Oliver 2021-08-10 14:33:08 +10:00
parent 67ccbf64b5
commit 6d0282519d
9 changed files with 107 additions and 31 deletions

View File

@ -7,6 +7,7 @@ import 'package:inventree/api.dart';
import 'package:inventree/app_colors.dart'; import 'package:inventree/app_colors.dart';
import 'package:inventree/inventree/part.dart'; import 'package:inventree/inventree/part.dart';
import 'package:inventree/inventree/stock.dart'; import 'package:inventree/inventree/stock.dart';
import 'package:inventree/widget/dialogs.dart';
import 'package:inventree/widget/fields.dart'; import 'package:inventree/widget/fields.dart';
import 'package:inventree/l10.dart'; import 'package:inventree/l10.dart';
@ -420,7 +421,7 @@ 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) * @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, {Map<String, dynamic> modelData = const {}, String method = "PATCH", Function? onSuccess, Function? onCancel}) async { Future<void> launchApiForm(BuildContext context, String title, String url, Map<String, dynamic> fields, {Map<String, dynamic> modelData = const {}, String method = "PATCH", Function(Map<String, dynamic>)? onSuccess, Function? onCancel}) async {
var options = await InvenTreeAPI().options(url); var options = await InvenTreeAPI().options(url);
@ -503,6 +504,7 @@ Future<void> launchApiForm(BuildContext context, String title, String url, Map<S
title, title,
url, url,
formFields, formFields,
method,
onSuccess: onSuccess, onSuccess: onSuccess,
)) ))
); );
@ -517,14 +519,18 @@ class APIFormWidget extends StatefulWidget {
//! API URL //! API URL
final String url; final String url;
//! API method
final String method;
final List<APIFormField> fields; final List<APIFormField> fields;
Function? onSuccess; Function(Map<String, dynamic>)? onSuccess;
APIFormWidget( APIFormWidget(
this.title, this.title,
this.url, this.url,
this.fields, this.fields,
this.method,
{ {
Key? key, Key? key,
this.onSuccess, this.onSuccess,
@ -532,7 +538,7 @@ class APIFormWidget extends StatefulWidget {
) : super(key: key); ) : super(key: key);
@override @override
_APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, onSuccess); _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess);
} }
@ -545,11 +551,13 @@ class _APIFormWidgetState extends State<APIFormWidget> {
String url; String url;
String method;
List<APIFormField> fields; List<APIFormField> fields;
Function? onSuccess; Function(Map<String, dynamic>)? onSuccess;
_APIFormWidgetState(this.title, this.url, this.fields, this.onSuccess) : super(); _APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess) : super();
List<Widget> _buildForm() { List<Widget> _buildForm() {
@ -584,30 +592,42 @@ class _APIFormWidgetState extends State<APIFormWidget> {
return widgets; return widgets;
} }
Future<APIResponse> _submit(Map<String, String> data) async {
if (method == "POST") {
return await InvenTreeAPI().post(
url,
body: data
);
} else {
return await InvenTreeAPI().patch(
url,
body: data,
);
}
}
Future<void> _save(BuildContext context) async { Future<void> _save(BuildContext context) async {
// Package up the form data // Package up the form data
Map<String, String> _data = {}; Map<String, String> data = {};
for (var field in fields) { for (var field in fields) {
dynamic value = field.value; dynamic value = field.value;
if (value == null) { if (value == null) {
_data[field.name] = ""; data[field.name] = "";
} else { } else {
_data[field.name] = value.toString(); data[field.name] = value.toString();
} }
} }
// TODO: Handle "POST" forms too!! final response = await _submit(data);
final response = await InvenTreeAPI().patch(
url,
body: _data,
);
if (!response.isValid()) { if (!response.isValid()) {
// TODO: Display an error message! showServerError(L10().serverError, L10().responseInvalid);
return; return;
} }
@ -625,7 +645,17 @@ class _APIFormWidgetState extends State<APIFormWidget> {
var successFunc = onSuccess; var successFunc = onSuccess;
if (successFunc != null) { if (successFunc != null) {
successFunc();
// Ensure the response is a valid JSON structure
Map<String, dynamic> 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; return;
case 400: case 400:

View File

@ -72,7 +72,25 @@ class InvenTreeModel {
return {}; return {};
} }
Future<void> editForm(BuildContext context, String title, {Map<String, dynamic> fields=const {}, Function? onSuccess}) async { Future<void> createForm(BuildContext context, String title, {Map<String, dynamic> fields=const{}, Map<String, dynamic> data=const {}, Function(dynamic)? onSuccess}) async {
if (fields.isEmpty) {
fields = formFields();
}
launchApiForm(
context,
title,
URL,
fields,
modelData: data,
onSuccess: onSuccess,
method: "POST",
);
}
Future<void> editForm(BuildContext context, String title, {Map<String, dynamic> fields=const {}, Function(dynamic)? onSuccess}) async {
if (fields.isEmpty) { if (fields.isEmpty) {
fields = formFields(); fields = formFields();
@ -84,7 +102,8 @@ class InvenTreeModel {
url, url,
fields, fields,
modelData: jsondata, modelData: jsondata,
onSuccess: onSuccess onSuccess: onSuccess,
method: "PATCH"
); );
} }

View File

@ -67,7 +67,13 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
return; return;
} }
_cat.editForm(context, L10().editCategory, onSuccess: refresh); _cat.editForm(
context,
L10().editCategory,
onSuccess: (data) async {
refresh();
}
);
} }
_CategoryDisplayState(this.category); _CategoryDisplayState(this.category);
@ -211,14 +217,27 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
int pk = category?.pk ?? -1; int pk = category?.pk ?? -1;
launchApiForm( InvenTreePartCategory().createForm(
context, context,
L10().categoryCreate, L10().categoryCreate,
InvenTreePartCategory().URL, data: {
InvenTreePartCategory().formFields(), "parent": (pk > 0) ? pk : null,
modelData: { },
"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();
} }
}
); );
} }

View File

@ -79,7 +79,9 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
"currency": {}, "currency": {},
}, },
modelData: company.jsondata, modelData: company.jsondata,
onSuccess: refresh onSuccess: (data) async {
refresh();
}
); );
} }

View File

@ -94,7 +94,9 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
"parent": {}, "parent": {},
}, },
modelData: _loc.jsondata, modelData: _loc.jsondata,
onSuccess: refresh onSuccess: (data) async {
refresh();
}
); );
} }

View File

@ -126,7 +126,9 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
"virtual": {}, "virtual": {},
}, },
modelData: part.jsondata, modelData: part.jsondata,
onSuccess: refresh, onSuccess: (data) async {
refresh();
},
); );
} }

View File

@ -56,7 +56,7 @@ class _PartNotesState extends RefreshableState<PartNotesWidget> {
} }
}, },
modelData: part.jsondata, modelData: part.jsondata,
onSuccess: () async { onSuccess: (data) async {
refresh(); refresh();
} }
); );

View File

@ -120,7 +120,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
"link": {}, "link": {},
}, },
modelData: item.jsondata, modelData: item.jsondata,
onSuccess: refresh onSuccess: (data) async {
refresh();
}
); );
} }

View File

@ -56,7 +56,7 @@ class _StockNotesState extends RefreshableState<StockNotesWidget> {
} }
}, },
modelData: item.jsondata, modelData: item.jsondata,
onSuccess: () { onSuccess: (data) async {
refresh(); refresh();
} }
); );