mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-29 05:56:47 +00:00
edit stock item
- Render choice fields
This commit is contained in:
parent
e8cb002e3c
commit
978cefd6bf
@ -599,8 +599,6 @@ class InvenTreeAPI {
|
|||||||
|
|
||||||
Uri? _uri = Uri.tryParse(_url);
|
Uri? _uri = Uri.tryParse(_url);
|
||||||
|
|
||||||
print("apiRequest ${method} -> ${url}");
|
|
||||||
|
|
||||||
if (_uri == null) {
|
if (_uri == null) {
|
||||||
showServerError(L10().invalidHost, L10().invalidHostDetails);
|
showServerError(L10().invalidHost, L10().invalidHostDetails);
|
||||||
return null;
|
return null;
|
||||||
@ -627,12 +625,15 @@ class InvenTreeAPI {
|
|||||||
|
|
||||||
return _request;
|
return _request;
|
||||||
} on SocketException catch (error) {
|
} on SocketException catch (error) {
|
||||||
|
print("SocketException at ${url}: ${error.toString()}");
|
||||||
showServerError(L10().connectionRefused, error.toString());
|
showServerError(L10().connectionRefused, error.toString());
|
||||||
return null;
|
return null;
|
||||||
} on TimeoutException {
|
} on TimeoutException {
|
||||||
|
print("TimeoutException at ${url}");
|
||||||
showTimeoutError();
|
showTimeoutError();
|
||||||
return null;
|
return null;
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
|
print("Server error at ${url}: ${error.toString()}");
|
||||||
showServerError(L10().serverError, error.toString());
|
showServerError(L10().serverError, error.toString());
|
||||||
sentryReportError(error, stackTrace);
|
sentryReportError(error, stackTrace);
|
||||||
return null;
|
return null;
|
||||||
|
@ -111,6 +111,8 @@ class APIFormField {
|
|||||||
|
|
||||||
String get placeholderText => (data['placeholder'] ?? '').toString();
|
String get placeholderText => (data['placeholder'] ?? '').toString();
|
||||||
|
|
||||||
|
List<dynamic> get choices => data["choices"] ?? [];
|
||||||
|
|
||||||
Future<void> loadInitialData() async {
|
Future<void> loadInitialData() async {
|
||||||
|
|
||||||
// Only for "related fields"
|
// Only for "related fields"
|
||||||
@ -151,6 +153,8 @@ class APIFormField {
|
|||||||
return _constructBoolean();
|
return _constructBoolean();
|
||||||
case "related field":
|
case "related field":
|
||||||
return _constructRelatedField();
|
return _constructRelatedField();
|
||||||
|
case "choice":
|
||||||
|
return _constructChoiceField();
|
||||||
default:
|
default:
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@ -163,6 +167,40 @@ class APIFormField {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _constructChoiceField() {
|
||||||
|
|
||||||
|
dynamic _initial;
|
||||||
|
|
||||||
|
// Check if the current value is within the allowed values
|
||||||
|
for (var opt in choices) {
|
||||||
|
if (opt['value'] == value) {
|
||||||
|
_initial = opt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DropdownSearch<dynamic>(
|
||||||
|
mode: Mode.BOTTOM_SHEET,
|
||||||
|
showSelectedItem: false,
|
||||||
|
selectedItem: _initial,
|
||||||
|
items: choices,
|
||||||
|
label: label,
|
||||||
|
hint: helpText,
|
||||||
|
onChanged: null,
|
||||||
|
showClearButton: !required,
|
||||||
|
itemAsString: (dynamic item) {
|
||||||
|
return item['display_name'];
|
||||||
|
},
|
||||||
|
onSaved: (item) {
|
||||||
|
if (item == null) {
|
||||||
|
data['value'] = null;
|
||||||
|
} else {
|
||||||
|
data['value'] = item['value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Construct an input for a related field
|
// Construct an input for a related field
|
||||||
Widget _constructRelatedField() {
|
Widget _constructRelatedField() {
|
||||||
|
|
||||||
|
@ -276,8 +276,6 @@ class InvenTreeModel {
|
|||||||
params[key] = filters[key] ?? '';
|
params[key] = filters[key] ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
print("LIST: $URL ${params.toString()}");
|
|
||||||
|
|
||||||
var response = await api.get(URL, params: params);
|
var response = await api.get(URL, params: params);
|
||||||
|
|
||||||
// A list of "InvenTreeModel" items
|
// A list of "InvenTreeModel" items
|
||||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
|||||||
Subproject commit 94e1193ef17ad536afc92b3b071cb3335e7d828c
|
Subproject commit 4dccf7c37fe5bca94fe0ef9ab05f7d5f0ec52452
|
@ -56,7 +56,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
key: _addProfileKey,
|
key: _addProfileKey,
|
||||||
callback: () {
|
callback: () {
|
||||||
if (createNew) {
|
if (createNew) {
|
||||||
// TODO - create the new profile...
|
|
||||||
UserProfile profile = UserProfile(
|
UserProfile profile = UserProfile(
|
||||||
name: _name,
|
name: _name,
|
||||||
server: _server,
|
server: _server,
|
||||||
|
@ -20,6 +20,8 @@ import 'package:inventree/api.dart';
|
|||||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
|
import '../api_form.dart';
|
||||||
|
|
||||||
class StockDetailWidget extends StatefulWidget {
|
class StockDetailWidget extends StatefulWidget {
|
||||||
|
|
||||||
StockDetailWidget(this.item, {Key? key}) : super(key: key);
|
StockDetailWidget(this.item, {Key? key}) : super(key: key);
|
||||||
@ -49,20 +51,29 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
List<Widget> getAppBarActions(BuildContext context) {
|
List<Widget> getAppBarActions(BuildContext context) {
|
||||||
return <Widget>[
|
|
||||||
IconButton(
|
List<Widget> actions = [];
|
||||||
icon: FaIcon(FontAwesomeIcons.globe),
|
|
||||||
onPressed: _openInvenTreePage,
|
if (InvenTreeAPI().checkPermission('stock', 'view')) {
|
||||||
),
|
actions.add(
|
||||||
// TODO: Hide the 'edit' button if the user does not have permission!!
|
IconButton(
|
||||||
/*
|
icon: FaIcon(FontAwesomeIcons.globe),
|
||||||
IconButton(
|
onPressed: _openInvenTreePage,
|
||||||
icon: FaIcon(FontAwesomeIcons.edit),
|
)
|
||||||
tooltip: L10().edit,
|
);
|
||||||
onPressed: _editPartDialog,
|
}
|
||||||
)
|
|
||||||
*/
|
if (InvenTreeAPI().checkPermission('stock', 'change')) {
|
||||||
];
|
actions.add(
|
||||||
|
IconButton(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.edit),
|
||||||
|
tooltip: L10().edit,
|
||||||
|
onPressed: () { _editStockItem(context); },
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _openInvenTreePage() async {
|
Future<void> _openInvenTreePage() async {
|
||||||
@ -95,6 +106,24 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
await item.getTestResults();
|
await item.getTestResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _editStockItem(BuildContext context) async {
|
||||||
|
|
||||||
|
launchApiForm(
|
||||||
|
context,
|
||||||
|
L10().editItem,
|
||||||
|
item.url,
|
||||||
|
{
|
||||||
|
"status": {},
|
||||||
|
"batch": {},
|
||||||
|
"packaging": {},
|
||||||
|
"link": {},
|
||||||
|
},
|
||||||
|
modelData: item.jsondata,
|
||||||
|
onSuccess: refresh
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void _addStock() async {
|
void _addStock() async {
|
||||||
|
|
||||||
double quantity = double.parse(_quantityController.text);
|
double quantity = double.parse(_quantityController.text);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user