mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 13:36:50 +00:00
Add ability to edit Part object
This commit is contained in:
parent
8374691d8c
commit
16cdae42ed
@ -270,12 +270,10 @@ class InvenTreeAPI {
|
|||||||
|
|
||||||
print("PATCH: " + _url);
|
print("PATCH: " + _url);
|
||||||
|
|
||||||
final response = await http.patch(_url,
|
return http.patch(_url,
|
||||||
headers: _headers,
|
headers: _headers,
|
||||||
body: _body,
|
body: _body,
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a POST request
|
// Perform a POST request
|
||||||
|
@ -126,6 +126,45 @@ class InvenTreeModel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POST data to update the model
|
||||||
|
Future<bool> update(BuildContext context, {Map<String, String> values}) async {
|
||||||
|
|
||||||
|
var addr = path.join(URL, pk.toString());
|
||||||
|
|
||||||
|
if (!addr.endsWith("/")) {
|
||||||
|
addr += "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
showProgressDialog(context, "Updating ${NAME}", "Sending data to server");
|
||||||
|
|
||||||
|
var response = await api.patch(addr, body: values)
|
||||||
|
.timeout(Duration(seconds: 10))
|
||||||
|
.catchError((e) {
|
||||||
|
|
||||||
|
hideProgressDialog(context);
|
||||||
|
|
||||||
|
if (e is TimeoutException) {
|
||||||
|
showErrorDialog(context, "Timeout", "No response from server");
|
||||||
|
} else {
|
||||||
|
showErrorDialog(context, "Error", e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response == null) return false;
|
||||||
|
|
||||||
|
hideProgressDialog(context);
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
print("Error updating ${NAME}: Status code ${response.statusCode}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Return the detail view for the associated pk
|
// Return the detail view for the associated pk
|
||||||
Future<InvenTreeModel> get(BuildContext context, int pk, {Map<String, String> filters}) async {
|
Future<InvenTreeModel> get(BuildContext context, int pk, {Map<String, String> filters}) async {
|
||||||
|
|
||||||
|
@ -3,12 +3,13 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class QuantityField extends TextFormField {
|
class QuantityField extends TextFormField {
|
||||||
|
|
||||||
QuantityField({String label = "", String hint = "", double max = null, TextEditingController controller}) :
|
QuantityField({String label = "", String hint = "", String initial = "", double max = null, TextEditingController controller}) :
|
||||||
super(
|
super(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: label,
|
labelText: label,
|
||||||
hintText: hint,
|
hintText: hint,
|
||||||
),
|
),
|
||||||
|
initialValue: initial,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import 'package:InvenTree/inventree/part.dart';
|
import 'package:InvenTree/inventree/part.dart';
|
||||||
import 'package:InvenTree/widget/category_display.dart';
|
import 'package:InvenTree/widget/category_display.dart';
|
||||||
|
import 'package:InvenTree/widget/dialogs.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -24,6 +25,8 @@ class PartDetailWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||||
|
|
||||||
|
final _editPartKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String getAppBarTitle(BuildContext context) { return "Part"; }
|
String getAppBarTitle(BuildContext context) { return "Part"; }
|
||||||
|
|
||||||
@ -40,6 +43,85 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
await part.reload(context);
|
await part.reload(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _savePart(Map<String, String> values) async {
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
var response = await part.update(context, values: values);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _editPartDialog() {
|
||||||
|
|
||||||
|
// Values which can be edited
|
||||||
|
var _name;
|
||||||
|
var _description;
|
||||||
|
var _ipn;
|
||||||
|
var _revision;
|
||||||
|
|
||||||
|
showFormDialog(context, "Edit Part",
|
||||||
|
key: _editPartKey,
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
child: Text("Cancel"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FlatButton(
|
||||||
|
child: Text("Save"),
|
||||||
|
onPressed: () {
|
||||||
|
if (_editPartKey.currentState.validate()) {
|
||||||
|
_editPartKey.currentState.save();
|
||||||
|
|
||||||
|
_savePart({
|
||||||
|
"name": _name,
|
||||||
|
"description": _description,
|
||||||
|
"IPN": _ipn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fields: <Widget>[
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Part Name",
|
||||||
|
hintText: "Enter part name",
|
||||||
|
),
|
||||||
|
initialValue: part.name,
|
||||||
|
validator: (value) {
|
||||||
|
if (value.isEmpty) return "Name cannot be empty";
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onSaved: (value) => _name = value,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Part Description",
|
||||||
|
hintText: "Enter part description",
|
||||||
|
),
|
||||||
|
initialValue: part.description,
|
||||||
|
validator: (value) {
|
||||||
|
if (value.isEmpty) return "Description cannot be empty";
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onSaved: (value) => _description = value,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Internal Part Number",
|
||||||
|
hintText: "Enter internal part number",
|
||||||
|
),
|
||||||
|
initialValue: part.IPN,
|
||||||
|
onSaved: (value) => _ipn = value,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build a list of tiles to display under the part description
|
* Build a list of tiles to display under the part description
|
||||||
*/
|
*/
|
||||||
@ -58,7 +140,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
),
|
),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: FaIcon(FontAwesomeIcons.edit),
|
icon: FaIcon(FontAwesomeIcons.edit),
|
||||||
onPressed: null,
|
onPressed: _editPartDialog,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user