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

Make a 'refreshable_state' class which makes API requests easier

This commit is contained in:
Oliver Walters 2020-04-15 11:39:29 +10:00
parent 5cc80ee3f4
commit 58f6fd0f15
2 changed files with 123 additions and 99 deletions

View File

@ -8,10 +8,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:InvenTree/widget/refreshable_state.dart';
class LocationDisplayWidget extends StatefulWidget { class LocationDisplayWidget extends StatefulWidget {
LocationDisplayWidget(this.location, {Key key}) : super(key: key); LocationDisplayWidget(this.location, {Key key}) : super(key: key);
final InvenTreeStockLocation location; final InvenTreeStockLocation location;
@ -22,21 +22,15 @@ class LocationDisplayWidget extends StatefulWidget {
_LocationDisplayState createState() => _LocationDisplayState(location); _LocationDisplayState createState() => _LocationDisplayState(location);
} }
class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
class _LocationDisplayState extends State<LocationDisplayWidget> {
BuildContext context;
_LocationDisplayState(this.location) {
}
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _requestData(context));
}
final InvenTreeStockLocation location; final InvenTreeStockLocation location;
@override
String app_bar_title = "Stock Location";
_LocationDisplayState(this.location) {}
List<InvenTreeStockLocation> _sublocations = List<InvenTreeStockLocation>(); List<InvenTreeStockLocation> _sublocations = List<InvenTreeStockLocation>();
String _locationFilter = ''; String _locationFilter = '';
@ -52,27 +46,8 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
List<InvenTreeStockItem> _items = List<InvenTreeStockItem>(); List<InvenTreeStockItem> _items = List<InvenTreeStockItem>();
String get _title { @override
Future<void> request(BuildContext context) async {
if (location == null) {
return "Stock Locations";
} else {
return "Stock Location - ${location.name}";
}
}
Future<void> _refresh() async {
await _requestData(context);
}
/*
* Request data from the server.
* It will be displayed once loaded
*
* - List of sublocations under this one
* - List of stock items at this location
*/
Future<void> _requestData(BuildContext context) async {
int pk = location?.pk ?? -1; int pk = location?.pk ?? -1;
@ -146,75 +121,63 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
} }
@override @override
Widget build(BuildContext context) { Widget getBody(BuildContext context) {
// Save the context return ListView(
this.context = context; children: <Widget> [
locationDescriptionCard(),
return Scaffold( ExpansionPanelList(
appBar: AppBar( expansionCallback: (int index, bool isExpanded) {
title: Text(_title), setState(() {
), switch (index) {
drawer: new InvenTreeDrawer(context), case 0:
body: new RefreshIndicator( InvenTreePreferences().expandLocationList = !isExpanded;
onRefresh: _refresh, break;
child: ListView( case 1:
children: <Widget> [ InvenTreePreferences().expandStockList = !isExpanded;
locationDescriptionCard(), break;
ExpansionPanelList( default:
expansionCallback: (int index, bool isExpanded) { break;
setState(() { }
switch (index) { });
case 0:
InvenTreePreferences().expandLocationList = !isExpanded;
break;
case 1:
InvenTreePreferences().expandStockList = !isExpanded;
break;
default:
break;
}
});
},
children: <ExpansionPanel> [
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;
});
},
);
}, },
children: <ExpansionPanel> [ body: SublocationList(_sublocations),
ExpansionPanel( isExpanded: InvenTreePreferences().expandLocationList && _sublocations.length > 0,
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(
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,
)
]
), ),
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,
)
] ]
) ),
) ]
); );
} }
} }

View File

@ -0,0 +1,61 @@
import 'package:InvenTree/widget/drawer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:InvenTree/widget/drawer.dart';
abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
// Storage for context once "Build" is called
BuildContext context;
String app_bar_title = "App Bar Title";
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => request(context));
}
// Function to request data for this page
Future<void> request(BuildContext context) async {
return;
}
Future<void> refresh() async {
await request(context);
setState(() {});
}
// Function to construct an appbar (override if needed)
AppBar getAppBar(BuildContext context) {
return AppBar(
title: Text(app_bar_title)
);
}
// Function to construct a drawer (override if needed)
Widget getDrawer(BuildContext context) {
return InvenTreeDrawer(context);
}
// Function to construct a body (MUST BE PROVIDED)
Widget getBody(BuildContext context);
@override
Widget build(BuildContext context) {
// Save the context for future use
this.context = context;
return Scaffold(
appBar: getAppBar(context),
drawer: getDrawer(context),
body: RefreshIndicator(
onRefresh: refresh,
child: getBody(context)
)
);
}
}