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

Add "actions" panel to stock item view

This commit is contained in:
Oliver Walters 2021-01-29 00:08:17 +11:00
parent 02cfeef31e
commit db6aae8a78
4 changed files with 128 additions and 46 deletions

View File

@ -141,7 +141,6 @@ class QuantityField extends TextFormField {
labelText: label,
hintText: hint,
),
initialValue: initial,
controller: controller,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
validator: (value) {

View File

@ -51,8 +51,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
InvenTreePart part;
int _tabIndex = 0;
@override
Future<void> onBuild(BuildContext context) async {
refresh();
@ -302,12 +300,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
}
void _onTabSelectionChanged(int index) {
setState(() {
_tabIndex = index;
});
}
Widget getSelectedWidget(int index) {
switch (index) {
case 0:
@ -335,8 +327,8 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
@override
Widget getBottomNavBar(BuildContext context) {
return BottomNavigationBar(
currentIndex: _tabIndex,
onTap: _onTabSelectionChanged,
currentIndex: tabIndex,
onTap: onTabSelectionChanged,
items: const <BottomNavigationBarItem> [
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.infoCircle),
@ -356,6 +348,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
@override
Widget getBody(BuildContext context) {
return getSelectedWidget(_tabIndex);
return getSelectedWidget(tabIndex);
}
}

View File

@ -11,6 +11,16 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
// Storage for context once "Build" is called
BuildContext context;
// Current tab index (used for widgets which display bottom tabs)
int tabIndex = 0;
// Update current tab selection
void onTabSelectionChanged(int index) {
setState(() {
tabIndex = index;
});
}
List<Widget> getAppBarActions(BuildContext context) {
return [];
}

View File

@ -119,6 +119,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
void _addStockDialog() async {
_quantityController.clear();
_notesController.clear();
showFormDialog(context, "Add Stock",
key: _addStockKey,
@ -165,6 +166,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
void _removeStockDialog() {
_quantityController.clear();
_notesController.clear();
showFormDialog(context, "Remove Stock",
key: _removeStockKey,
@ -212,6 +214,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
void _countStockDialog() async {
_quantityController.text = item.quantity.toString();
_notesController.clear();
showFormDialog(context, "Count Stock",
key: _countStockKey,
actions: <Widget> [
@ -331,23 +336,25 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
);
}
Widget headerTile() {
return Card(
child: ListTile(
title: Text("${item.partName}"),
subtitle: Text("${item.partDescription}"),
leading: InvenTreeAPI().getImage(item.partImage),
)
);
}
/*
* Construct a list of detail elements about this StockItem.
* The number of elements may vary depending on the StockItem details
*/
List<Widget> stockTiles() {
List<Widget> detailTiles() {
List<Widget> tiles = [];
// Image / name / description
tiles.add(
Card(
child: ListTile(
title: Text("${item.partName}"),
subtitle: Text("${item.partDescription}"),
leading: InvenTreeAPI().getImage(item.partImage),
)
)
);
tiles.add(headerTile());
tiles.add(
ListTile(
@ -412,20 +419,6 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
);
}
tiles.add(
ListTile(
title: Text("Add Barcode"),
leading: FaIcon(FontAwesomeIcons.qrcode),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => InvenTreeQRView(StockItemBarcodeAssignmentHandler(item)))
);
//Navigator.push(context, MaterialPageRoute(builder: (context) => AssignBarcodeToStockItemView(item)));
},
)
);
// Supplier part?
if (item.supplierPartId > 0) {
tiles.add(
@ -486,11 +479,83 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
return tiles;
}
List<Widget> actionTiles() {
List<Widget> tiles = [];
tiles.add(headerTile());
if (!item.isSerialized()) {
tiles.add(
ListTile(
title: Text("Count Stock"),
leading: FaIcon(FontAwesomeIcons.checkCircle),
onTap: _countStockDialog,
)
);
tiles.add(
ListTile(
title: Text("Remove Stock"),
leading: FaIcon(FontAwesomeIcons.minusCircle),
onTap: _removeStockDialog,
)
);
tiles.add(
ListTile(
title: Text("Add Stock"),
leading: FaIcon(FontAwesomeIcons.plusCircle),
onTap: _addStockDialog,
)
);
}
tiles.add(
ListTile(
title: Text("Transfer Stock"),
leading: FaIcon(FontAwesomeIcons.exchangeAlt),
onTap: _transferStockDialog,
)
);
// Scan item into a location
tiles.add(
ListTile(
title: Text("Scan Into Location"),
leading: FaIcon(FontAwesomeIcons.exchangeAlt),
trailing: FaIcon(FontAwesomeIcons.qrcode),
onTap: () {
},
)
);
// Add or remove custom barcode
if (item.uid.isEmpty) {
tiles.add(
ListTile(
title: Text("Assign Barcode"),
leading: FaIcon(FontAwesomeIcons.barcode),
trailing: FaIcon(FontAwesomeIcons.qrcode),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => InvenTreeQRView(StockItemBarcodeAssignmentHandler(item)))
);
}
)
);
}
return tiles;
}
/*
* Return a list of context-sensitive action buttons.
* Not all buttons will be avaialable for a given StockItem,
* depending on the properties of that StockItem
*/
/*
List<SpeedDialChild> actionButtons() {
var buttons = List<SpeedDialChild>();
@ -525,32 +590,47 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
return buttons;
}
*/
@override
Widget getBottomNavBar(BuildContext context) {
return BottomNavigationBar(
currentIndex: 0,
onTap: null,
currentIndex: tabIndex,
onTap: onTabSelectionChanged,
items: const <BottomNavigationBarItem> [
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.infoCircle),
title: Text("Details"),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.history),
title: Text("History"),
)
icon: FaIcon(FontAwesomeIcons.wrench),
title: Text("Actions"),
),
]
);
}
@override
Widget getBody(BuildContext context) {
return ListView(
children: stockTiles()
);
Widget getSelectedWidget(int index) {
switch (index) {
case 0:
return ListView(
children: detailTiles(),
);
case 1:
return ListView(
children: actionTiles(),
);
default:
return null;
}
}
@override
Widget getBody(BuildContext context) {
return getSelectedWidget(tabIndex);
}
/*
@override
Widget getFab(BuildContext context) {
return SpeedDial(
@ -560,4 +640,5 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
children: actionButtons(),
);
}
*/
}