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:
parent
67ccbf64b5
commit
6d0282519d
@ -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:
|
||||||
|
@ -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"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,9 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
|
|||||||
"currency": {},
|
"currency": {},
|
||||||
},
|
},
|
||||||
modelData: company.jsondata,
|
modelData: company.jsondata,
|
||||||
onSuccess: refresh
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,9 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
"parent": {},
|
"parent": {},
|
||||||
},
|
},
|
||||||
modelData: _loc.jsondata,
|
modelData: _loc.jsondata,
|
||||||
onSuccess: refresh
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,9 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
"virtual": {},
|
"virtual": {},
|
||||||
},
|
},
|
||||||
modelData: part.jsondata,
|
modelData: part.jsondata,
|
||||||
onSuccess: refresh,
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class _PartNotesState extends RefreshableState<PartNotesWidget> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
modelData: part.jsondata,
|
modelData: part.jsondata,
|
||||||
onSuccess: () async {
|
onSuccess: (data) async {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -120,7 +120,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
"link": {},
|
"link": {},
|
||||||
},
|
},
|
||||||
modelData: item.jsondata,
|
modelData: item.jsondata,
|
||||||
onSuccess: refresh
|
onSuccess: (data) async {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ class _StockNotesState extends RefreshableState<StockNotesWidget> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
modelData: item.jsondata,
|
modelData: item.jsondata,
|
||||||
onSuccess: () {
|
onSuccess: (data) async {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user