mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-29 05:56:47 +00:00
Merge branch 'barcode-actions'
This commit is contained in:
commit
13780b0c80
@ -41,6 +41,16 @@ class BarcodeHandler {
|
|||||||
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
||||||
// Called when the server does not know about a barcode
|
// Called when the server does not know about a barcode
|
||||||
// Override this function
|
// Override this function
|
||||||
|
showErrorDialog(
|
||||||
|
_context,
|
||||||
|
"Invalid Barcode",
|
||||||
|
"Barcode does not match any known item",
|
||||||
|
error: "Barcode Error",
|
||||||
|
icon: FontAwesomeIcons.barcode,
|
||||||
|
onDismissed: () {
|
||||||
|
_controller.resumeCamera();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) {
|
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) {
|
||||||
@ -339,6 +349,40 @@ class _QRViewState extends State<InvenTreeQRView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class StockItemScanIntoLocationHandler extends BarcodeHandler {
|
||||||
|
/**
|
||||||
|
* Barcode handler for scanning a provided StockItem into a scanned StockLocation
|
||||||
|
*/
|
||||||
|
|
||||||
|
final InvenTreeStockItem item;
|
||||||
|
|
||||||
|
StockItemScanIntoLocationHandler(this.item);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onBarcodeMatched(Map<String, dynamic> data) {
|
||||||
|
// If the barcode points to a 'stocklocation', great!
|
||||||
|
if (!data.containsKey('stocklocation')) {
|
||||||
|
showErrorDialog(
|
||||||
|
_context,
|
||||||
|
"Invalid Barcode",
|
||||||
|
"Barcode does not match a Stock Location",
|
||||||
|
onDismissed: _controller.resumeCamera,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Extract location information
|
||||||
|
int location = data['stocklocation']['pk'] as int;
|
||||||
|
|
||||||
|
// Transfer stock to specified location
|
||||||
|
item.transferStock(location).then((response) {
|
||||||
|
print("Response: ${response.statusCode}");
|
||||||
|
_controller.dispose();
|
||||||
|
Navigator.of(_context).pop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> scanQrCode(BuildContext context) async {
|
Future<void> scanQrCode(BuildContext context) async {
|
||||||
|
|
||||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeQRView(BarcodeScanHandler())));
|
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeQRView(BarcodeScanHandler())));
|
||||||
|
@ -379,20 +379,26 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> transferStock(double q, int location, {String notes}) async {
|
Future<http.Response> transferStock(int location, {double quantity, String notes}) async {
|
||||||
|
if (quantity == null) {} else
|
||||||
|
if ((quantity < 0) || (quantity > this.quantity)) {
|
||||||
|
quantity = this.quantity;
|
||||||
|
}
|
||||||
|
|
||||||
if ((q == null) || (q > quantity)) q = quantity;
|
Map<String, dynamic> data = {
|
||||||
|
|
||||||
return api.post("/stock/transfer/", body: {
|
|
||||||
"item": {
|
"item": {
|
||||||
"pk": "${pk}",
|
"pk": "${pk}",
|
||||||
"quantity": "${q}",
|
},
|
||||||
},
|
|
||||||
"location": "${location}",
|
"location": "${location}",
|
||||||
"notes": notes ?? '',
|
"notes": notes ?? '',
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
if (quantity != null) {
|
||||||
|
data["item"]["quantity"] = "${quantity}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.post("/stock/transfer/", body: data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ class QuantityField extends TextFormField {
|
|||||||
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) {
|
||||||
|
@ -133,11 +133,87 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget getBody(BuildContext context) {
|
Widget getBottomNavBar(BuildContext context) {
|
||||||
|
return BottomNavigationBar(
|
||||||
|
currentIndex: tabIndex,
|
||||||
|
onTap: onTabSelectionChanged,
|
||||||
|
items: const <BottomNavigationBarItem> [
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.boxes),
|
||||||
|
title: Text("Stock"),
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.wrench),
|
||||||
|
title: Text("Actions"),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return ListView(
|
Widget getSelectedWidget(int index) {
|
||||||
children: <Widget> [
|
switch (index) {
|
||||||
locationDescriptionCard(),
|
case 0:
|
||||||
|
return ListView(
|
||||||
|
children: detailTiles(),
|
||||||
|
);
|
||||||
|
case 1:
|
||||||
|
return ListView(
|
||||||
|
children: actionTiles(),
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget getBody(BuildContext context) {
|
||||||
|
return getSelectedWidget(tabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<Widget> detailTiles() {
|
||||||
|
List<Widget> tiles = [];
|
||||||
|
|
||||||
|
// Location description
|
||||||
|
tiles.add(locationDescriptionCard());
|
||||||
|
|
||||||
|
// Sublocation panel
|
||||||
|
ExpansionPanel sublocations = ExpansionPanel(
|
||||||
|
headerBuilder: (BuildContext context, bool isExpanded) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text("Sublocations"),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.mapMarkerAlt),
|
||||||
|
trailing: Text("${_sublocations.length}"),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
InvenTreePreferences().expandLocationList = !InvenTreePreferences().expandLocationList;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
body: SublocationList(_sublocations),
|
||||||
|
isExpanded: InvenTreePreferences().expandLocationList && _sublocations.length > 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
ExpansionPanel subitems = ExpansionPanel(
|
||||||
|
headerBuilder: (BuildContext context, bool isExpanded) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text("Stock Items"),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.boxes),
|
||||||
|
trailing: Text("${_items.length}"),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
InvenTreePreferences().expandStockList = !InvenTreePreferences().expandStockList;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
body: StockList(_items),
|
||||||
|
isExpanded: InvenTreePreferences().expandStockList && _items.length > 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Sublocations and items
|
||||||
|
tiles.add(
|
||||||
ExpansionPanelList(
|
ExpansionPanelList(
|
||||||
expansionCallback: (int index, bool isExpanded) {
|
expansionCallback: (int index, bool isExpanded) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -152,49 +228,48 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
children: <ExpansionPanel> [
|
children: <ExpansionPanel> [
|
||||||
ExpansionPanel(
|
sublocations,
|
||||||
headerBuilder: (BuildContext context, bool isExpanded) {
|
subitems,
|
||||||
return ListTile(
|
|
||||||
title: Text("Sublocations"),
|
|
||||||
leading: FaIcon(FontAwesomeIcons.mapMarkerAlt),
|
|
||||||
trailing: Text("${_sublocations.length}"),
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
InvenTreePreferences().expandLocationList = !InvenTreePreferences().expandLocationList;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: SublocationList(_sublocations),
|
|
||||||
isExpanded: InvenTreePreferences().expandLocationList && _sublocations.length > 0,
|
|
||||||
),
|
|
||||||
ExpansionPanel(
|
|
||||||
headerBuilder: (BuildContext context, bool isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text("Stock Items"),
|
|
||||||
leading: FaIcon(FontAwesomeIcons.boxes),
|
|
||||||
trailing: Text("${_items.length}"),
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
InvenTreePreferences().expandStockList = !InvenTreePreferences().expandStockList;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: StockList(_items),
|
|
||||||
isExpanded: InvenTreePreferences().expandStockList && _items.length > 0,
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
),
|
)
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Widget> actionTiles() {
|
||||||
|
List<Widget> tiles = [];
|
||||||
|
|
||||||
|
tiles.add(locationDescriptionCard());
|
||||||
|
|
||||||
|
// Scan items into location
|
||||||
|
tiles.add(
|
||||||
|
ListTile(
|
||||||
|
title: Text("Scan in Stock Item"),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.exchangeAlt),
|
||||||
|
trailing: FaIcon(FontAwesomeIcons.qrcode),
|
||||||
|
onTap: null,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Move location into another location
|
||||||
|
tiles.add(
|
||||||
|
ListTile(
|
||||||
|
title: Text("Move Stock Location"),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.sitemap),
|
||||||
|
trailing: FaIcon(FontAwesomeIcons.qrcode),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SublocationList extends StatelessWidget {
|
class SublocationList extends StatelessWidget {
|
||||||
final List<InvenTreeStockLocation> _locations;
|
final List<InvenTreeStockLocation> _locations;
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
|
|
||||||
InvenTreePart part;
|
InvenTreePart part;
|
||||||
|
|
||||||
int _tabIndex = 0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onBuild(BuildContext context) async {
|
Future<void> onBuild(BuildContext context) async {
|
||||||
refresh();
|
refresh();
|
||||||
@ -302,12 +300,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onTabSelectionChanged(int index) {
|
|
||||||
setState(() {
|
|
||||||
_tabIndex = index;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget getSelectedWidget(int index) {
|
Widget getSelectedWidget(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -335,8 +327,8 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
@override
|
@override
|
||||||
Widget getBottomNavBar(BuildContext context) {
|
Widget getBottomNavBar(BuildContext context) {
|
||||||
return BottomNavigationBar(
|
return BottomNavigationBar(
|
||||||
currentIndex: _tabIndex,
|
currentIndex: tabIndex,
|
||||||
onTap: _onTabSelectionChanged,
|
onTap: onTabSelectionChanged,
|
||||||
items: const <BottomNavigationBarItem> [
|
items: const <BottomNavigationBarItem> [
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: FaIcon(FontAwesomeIcons.infoCircle),
|
icon: FaIcon(FontAwesomeIcons.infoCircle),
|
||||||
@ -356,6 +348,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget getBody(BuildContext context) {
|
Widget getBody(BuildContext context) {
|
||||||
return getSelectedWidget(_tabIndex);
|
return getSelectedWidget(tabIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,16 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
|
|||||||
// Storage for context once "Build" is called
|
// Storage for context once "Build" is called
|
||||||
BuildContext context;
|
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) {
|
List<Widget> getAppBarActions(BuildContext context) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
void _addStockDialog() async {
|
void _addStockDialog() async {
|
||||||
|
|
||||||
_quantityController.clear();
|
_quantityController.clear();
|
||||||
|
_notesController.clear();
|
||||||
|
|
||||||
showFormDialog(context, "Add Stock",
|
showFormDialog(context, "Add Stock",
|
||||||
key: _addStockKey,
|
key: _addStockKey,
|
||||||
@ -165,6 +166,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
void _removeStockDialog() {
|
void _removeStockDialog() {
|
||||||
|
|
||||||
_quantityController.clear();
|
_quantityController.clear();
|
||||||
|
_notesController.clear();
|
||||||
|
|
||||||
showFormDialog(context, "Remove Stock",
|
showFormDialog(context, "Remove Stock",
|
||||||
key: _removeStockKey,
|
key: _removeStockKey,
|
||||||
@ -212,6 +214,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
void _countStockDialog() async {
|
void _countStockDialog() async {
|
||||||
|
|
||||||
|
_quantityController.text = item.quantity.toString();
|
||||||
|
_notesController.clear();
|
||||||
|
|
||||||
showFormDialog(context, "Count Stock",
|
showFormDialog(context, "Count Stock",
|
||||||
key: _countStockKey,
|
key: _countStockKey,
|
||||||
actions: <Widget> [
|
actions: <Widget> [
|
||||||
@ -248,7 +253,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
_quantityController.clear();
|
_quantityController.clear();
|
||||||
_notesController.clear();
|
_notesController.clear();
|
||||||
|
|
||||||
var response = await item.transferStock(quantity, location.pk, notes: notes);
|
var response = await item.transferStock(location.pk, quantity: quantity, notes: notes);
|
||||||
|
|
||||||
// TODO - Error handling (potentially return false?)
|
// TODO - Error handling (potentially return false?)
|
||||||
refresh();
|
refresh();
|
||||||
@ -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.
|
* Construct a list of detail elements about this StockItem.
|
||||||
* The number of elements may vary depending on the StockItem details
|
* The number of elements may vary depending on the StockItem details
|
||||||
*/
|
*/
|
||||||
List<Widget> stockTiles() {
|
List<Widget> detailTiles() {
|
||||||
List<Widget> tiles = [];
|
List<Widget> tiles = [];
|
||||||
|
|
||||||
// Image / name / description
|
// Image / name / description
|
||||||
tiles.add(
|
tiles.add(headerTile());
|
||||||
Card(
|
|
||||||
child: ListTile(
|
|
||||||
title: Text("${item.partName}"),
|
|
||||||
subtitle: Text("${item.partDescription}"),
|
|
||||||
leading: InvenTreeAPI().getImage(item.partImage),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
tiles.add(
|
tiles.add(
|
||||||
ListTile(
|
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?
|
// Supplier part?
|
||||||
if (item.supplierPartId > 0) {
|
if (item.supplierPartId > 0) {
|
||||||
tiles.add(
|
tiles.add(
|
||||||
@ -486,11 +479,87 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
return tiles;
|
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: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => InvenTreeQRView(StockItemScanIntoLocationHandler(item)))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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.
|
* Return a list of context-sensitive action buttons.
|
||||||
* Not all buttons will be avaialable for a given StockItem,
|
* Not all buttons will be avaialable for a given StockItem,
|
||||||
* depending on the properties of that StockItem
|
* depending on the properties of that StockItem
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
List<SpeedDialChild> actionButtons() {
|
List<SpeedDialChild> actionButtons() {
|
||||||
var buttons = List<SpeedDialChild>();
|
var buttons = List<SpeedDialChild>();
|
||||||
|
|
||||||
@ -525,32 +594,47 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget getBottomNavBar(BuildContext context) {
|
Widget getBottomNavBar(BuildContext context) {
|
||||||
return BottomNavigationBar(
|
return BottomNavigationBar(
|
||||||
currentIndex: 0,
|
currentIndex: tabIndex,
|
||||||
onTap: null,
|
onTap: onTabSelectionChanged,
|
||||||
items: const <BottomNavigationBarItem> [
|
items: const <BottomNavigationBarItem> [
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: FaIcon(FontAwesomeIcons.infoCircle),
|
icon: FaIcon(FontAwesomeIcons.infoCircle),
|
||||||
title: Text("Details"),
|
title: Text("Details"),
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: FaIcon(FontAwesomeIcons.history),
|
icon: FaIcon(FontAwesomeIcons.wrench),
|
||||||
title: Text("History"),
|
title: Text("Actions"),
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
Widget getSelectedWidget(int index) {
|
||||||
Widget getBody(BuildContext context) {
|
switch (index) {
|
||||||
return ListView(
|
case 0:
|
||||||
children: stockTiles()
|
return ListView(
|
||||||
);
|
children: detailTiles(),
|
||||||
|
);
|
||||||
|
case 1:
|
||||||
|
return ListView(
|
||||||
|
children: actionTiles(),
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget getBody(BuildContext context) {
|
||||||
|
return getSelectedWidget(tabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
@override
|
@override
|
||||||
Widget getFab(BuildContext context) {
|
Widget getFab(BuildContext context) {
|
||||||
return SpeedDial(
|
return SpeedDial(
|
||||||
@ -560,4 +644,5 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
children: actionButtons(),
|
children: actionButtons(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user