mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
User configurable home screen actions
This commit is contained in:
parent
fd54b20b92
commit
2788ed5bd7
@ -1,11 +1,12 @@
|
||||
## InvenTree App Release Notes
|
||||
---
|
||||
|
||||
### 0.x.x - January 2022
|
||||
### 0.5.4 - January 2022
|
||||
---
|
||||
|
||||
- Enable usage of camera flash when scanning barcodes
|
||||
- Enable camera toggle when scanning barcodes
|
||||
- Configurable home screen actions
|
||||
- Updated icon set
|
||||
- Removed "upload error report" functionality (instead link to GitHub issues)
|
||||
- Updated multiple language translations
|
||||
|
@ -488,9 +488,7 @@ class InvenTreeAPI {
|
||||
List<String> perms = List.from(roles[role] as List<dynamic>);
|
||||
return perms.contains(permission);
|
||||
} catch (error, stackTrace) {
|
||||
if (error is CastError) {
|
||||
// Ignore CastError
|
||||
} else if (error is TypeError) {
|
||||
if (error is TypeError) {
|
||||
// Ignore TypeError
|
||||
} else {
|
||||
// Unknown error - report it!
|
||||
|
@ -5,6 +5,21 @@
|
||||
import "package:sembast/sembast.dart";
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
// Settings key values
|
||||
const String INV_HOME_SHOW_SUBSCRIBED = "homeShowSubscribed";
|
||||
const String INV_HOME_SHOW_PO = "homeShowPo";
|
||||
const String INV_HOME_SHOW_MANUFACTURERS = "homeShowManufacturers";
|
||||
const String INV_HOME_SHOW_CUSTOMERS = "homeShowCustomers";
|
||||
const String INV_HOME_SHOW_SUPPLIERS = "homeShowSuppliers";
|
||||
|
||||
const String INV_SOUNDS_BARCODE = "barcodeSounds";
|
||||
const String INV_SOUNDS_SERVER = "serverSounds";
|
||||
|
||||
const String INV_PART_SUBCATEGORY = "partSubcategory";
|
||||
|
||||
const String INV_STOCK_SUBLOCATION = "stockSublocation";
|
||||
|
||||
|
||||
class InvenTreeSettingsManager {
|
||||
|
||||
factory InvenTreeSettingsManager() {
|
||||
|
@ -18,7 +18,7 @@ String simpleNumberString(double number) {
|
||||
|
||||
Future<void> successTone() async {
|
||||
|
||||
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
|
||||
|
||||
if (en) {
|
||||
final player = AudioCache();
|
||||
@ -28,7 +28,7 @@ Future<void> successTone() async {
|
||||
|
||||
Future <void> failureTone() async {
|
||||
|
||||
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
|
||||
|
||||
if (en) {
|
||||
final player = AudioCache();
|
||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
||||
Subproject commit 08bfb71daa2f4cd0780708bf3553ff2b1e2adc50
|
||||
Subproject commit feae1bee4275544b1571a37273b0e8113622eb2c
|
@ -19,9 +19,21 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
|
||||
final GlobalKey<_InvenTreeAppSettingsState> _settingsKey = GlobalKey<_InvenTreeAppSettingsState>();
|
||||
|
||||
// Home screen settings
|
||||
bool homeShowSubscribed = true;
|
||||
bool homeShowPo = true;
|
||||
bool homeShowSuppliers = true;
|
||||
bool homeShowManufacturers = true;
|
||||
bool homeShowCustomers = true;
|
||||
|
||||
// Sound settings
|
||||
bool barcodeSounds = true;
|
||||
bool serverSounds = true;
|
||||
|
||||
// Part settings
|
||||
bool partSubcategory = false;
|
||||
|
||||
// Stock settings
|
||||
bool stockSublocation = false;
|
||||
|
||||
@override
|
||||
@ -32,45 +44,21 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
}
|
||||
|
||||
Future <void> loadSettings() async {
|
||||
barcodeSounds = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
serverSounds = await InvenTreeSettingsManager().getValue("serverSounds", true) as bool;
|
||||
|
||||
partSubcategory = await InvenTreeSettingsManager().getValue("partSubcategory", true) as bool;
|
||||
stockSublocation = await InvenTreeSettingsManager().getValue("stockSublocation", true) as bool;
|
||||
// Load initial settings
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
homeShowSubscribed = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
|
||||
homeShowPo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_PO, true) as bool;
|
||||
homeShowManufacturers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_MANUFACTURERS, true) as bool;
|
||||
homeShowCustomers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_CUSTOMERS, true) as bool;
|
||||
homeShowSuppliers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUPPLIERS, true) as bool;
|
||||
|
||||
Future <void> setBarcodeSounds(bool en) async {
|
||||
barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
|
||||
serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
|
||||
|
||||
await InvenTreeSettingsManager().setValue("barcodeSounds", en);
|
||||
barcodeSounds = await InvenTreeSettingsManager().getBool("barcodeSounds", true);
|
||||
partSubcategory = await InvenTreeSettingsManager().getValue(INV_PART_SUBCATEGORY, true) as bool;
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> setServerSounds(bool en) async {
|
||||
|
||||
await InvenTreeSettingsManager().setValue("serverSounds", en);
|
||||
serverSounds = await InvenTreeSettingsManager().getBool("serverSounds", true);
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> setPartSubcategory(bool en) async {
|
||||
await InvenTreeSettingsManager().setValue("partSubcategory", en);
|
||||
partSubcategory = await InvenTreeSettingsManager().getBool("partSubcategory", true);
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> setStockSublocation(bool en) async {
|
||||
await InvenTreeSettingsManager().setValue("stockSublocation", en);
|
||||
stockSublocation = await InvenTreeSettingsManager().getBool("stockSublocation", true);
|
||||
stockSublocation = await InvenTreeSettingsManager().getValue(INV_STOCK_SUBLOCATION, true) as bool;
|
||||
|
||||
setState(() {
|
||||
});
|
||||
@ -87,12 +75,90 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
/* Home Screen Settings */
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().homeScreen,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSubscribed),
|
||||
subtitle: Text(L10().homeShowSubscribedDescription),
|
||||
leading: FaIcon(FontAwesomeIcons.bell),
|
||||
trailing: Switch(
|
||||
value: homeShowSubscribed,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SUBSCRIBED, value);
|
||||
setState(() {
|
||||
homeShowSubscribed = value;
|
||||
});
|
||||
},
|
||||
)
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowPo),
|
||||
subtitle: Text(L10().homeShowPoDescription),
|
||||
leading: FaIcon(FontAwesomeIcons.shoppingCart),
|
||||
trailing: Switch(
|
||||
value: homeShowPo,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_PO, value);
|
||||
setState(() {
|
||||
homeShowPo = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSuppliers),
|
||||
subtitle: Text(L10().homeShowSuppliersDescription),
|
||||
leading: FaIcon(FontAwesomeIcons.building),
|
||||
trailing: Switch(
|
||||
value: homeShowSuppliers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SUPPLIERS, value);
|
||||
setState(() {
|
||||
homeShowSuppliers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowManufacturers),
|
||||
subtitle: Text(L10().homeShowManufacturersDescription),
|
||||
leading: FaIcon(FontAwesomeIcons.industry),
|
||||
trailing: Switch(
|
||||
value: homeShowManufacturers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_MANUFACTURERS, value);
|
||||
setState(() {
|
||||
homeShowManufacturers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowCustomers),
|
||||
subtitle: Text(L10().homeShowCustomersDescription),
|
||||
leading: FaIcon(FontAwesomeIcons.userTie),
|
||||
trailing: Switch(
|
||||
value: homeShowCustomers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_CUSTOMERS, value);
|
||||
setState(() {
|
||||
homeShowCustomers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
/* Part Settings */
|
||||
Divider(height: 3),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().parts,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
leading: FaIcon(FontAwesomeIcons.shapes),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().includeSubcategories),
|
||||
@ -100,15 +166,20 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
leading: FaIcon(FontAwesomeIcons.sitemap),
|
||||
trailing: Switch(
|
||||
value: partSubcategory,
|
||||
onChanged: setPartSubcategory,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PART_SUBCATEGORY, value);
|
||||
setState(() {
|
||||
partSubcategory = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
/* Stock Settings */
|
||||
Divider(height: 3),
|
||||
ListTile(
|
||||
title: Text(L10().stock,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
leading: FaIcon(FontAwesomeIcons.boxes),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().includeSublocations),
|
||||
@ -116,9 +187,15 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
leading: FaIcon(FontAwesomeIcons.sitemap),
|
||||
trailing: Switch(
|
||||
value: stockSublocation,
|
||||
onChanged: setStockSublocation,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STOCK_SUBLOCATION, value);
|
||||
setState(() {
|
||||
stockSublocation = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
/* Sound Settings */
|
||||
Divider(height: 3),
|
||||
ListTile(
|
||||
title: Text(
|
||||
@ -133,7 +210,12 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
leading: FaIcon(FontAwesomeIcons.server),
|
||||
trailing: Switch(
|
||||
value: serverSounds,
|
||||
onChanged: setServerSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_SERVER, value);
|
||||
setState(() {
|
||||
serverSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
@ -142,7 +224,12 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
leading: Icon(Icons.qr_code),
|
||||
trailing: Switch(
|
||||
value: barcodeSounds,
|
||||
onChanged: setBarcodeSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_BARCODE, value);
|
||||
setState(() {
|
||||
barcodeSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Divider(height: 1),
|
||||
|
@ -106,7 +106,7 @@ Future<void> showServerError(String title, String description) async {
|
||||
}
|
||||
|
||||
// Play a sound
|
||||
final bool tones = await InvenTreeSettingsManager().getValue("serverSounds", true) as bool;
|
||||
final bool tones = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
|
||||
|
||||
if (tones) {
|
||||
final player = AudioCache();
|
||||
|
@ -19,6 +19,8 @@ import "package:inventree/widget/search.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:inventree/widget/drawer.dart";
|
||||
|
||||
import "../app_settings.dart";
|
||||
|
||||
|
||||
class InvenTreeHomePage extends StatefulWidget {
|
||||
|
||||
@ -32,10 +34,20 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
|
||||
_InvenTreeHomePageState() : super() {
|
||||
|
||||
// Load display settings
|
||||
_loadSettings();
|
||||
|
||||
// Initially load the profile and attempt server connection
|
||||
_loadProfile();
|
||||
|
||||
}
|
||||
|
||||
bool homeShowPo = true;
|
||||
bool homeShowSubscribed = true;
|
||||
bool homeShowManufacturers = true;
|
||||
bool homeShowCustomers = true;
|
||||
bool homeShowSuppliers = true;
|
||||
|
||||
final GlobalKey<_InvenTreeHomePageState> _homeKey = GlobalKey<_InvenTreeHomePageState>();
|
||||
|
||||
// Selected user profile
|
||||
@ -127,6 +139,22 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> _loadSettings() async {
|
||||
|
||||
print("_loadSettings");
|
||||
|
||||
homeShowSubscribed = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
|
||||
homeShowPo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_PO, true) as bool;
|
||||
homeShowManufacturers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_MANUFACTURERS, true) as bool;
|
||||
homeShowCustomers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_CUSTOMERS, true) as bool;
|
||||
homeShowSuppliers = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUPPLIERS, true) as bool;
|
||||
|
||||
print("suppliers: ${homeShowSuppliers}");
|
||||
|
||||
setState(() {
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> _loadProfile() async {
|
||||
|
||||
_profile = await UserProfileDBManager().getSelectedProfile();
|
||||
@ -201,95 +229,120 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
}
|
||||
|
||||
List<Widget> getGridTiles(BuildContext context) {
|
||||
return [
|
||||
_iconButton(
|
||||
|
||||
List<Widget> tiles = [];
|
||||
|
||||
// Barcode scanner
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().scanBarcode,
|
||||
Icons.qr_code_scanner,
|
||||
callback: () {
|
||||
_scan(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
|
||||
// Search widget
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().search,
|
||||
FontAwesomeIcons.search,
|
||||
callback: () {
|
||||
_search(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
|
||||
// Parts
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().parts,
|
||||
FontAwesomeIcons.shapes,
|
||||
callback: () {
|
||||
_showParts(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
|
||||
// Starred parts
|
||||
if (homeShowSubscribed) {
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().partsStarred,
|
||||
FontAwesomeIcons.solidStar,
|
||||
FontAwesomeIcons.bell,
|
||||
callback: () {
|
||||
_showStarredParts(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
}
|
||||
|
||||
// Stock button
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().stock,
|
||||
FontAwesomeIcons.boxes,
|
||||
callback: () {
|
||||
_showStock(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
|
||||
// Purchase orderes
|
||||
if (homeShowPo) {
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().purchaseOrders,
|
||||
FontAwesomeIcons.shoppingCart,
|
||||
callback: () {
|
||||
_showPurchaseOrders(context);
|
||||
}
|
||||
),
|
||||
/*
|
||||
_iconButton(
|
||||
context,
|
||||
L10().salesOrders,
|
||||
FontAwesomeIcons.truck,
|
||||
),
|
||||
*/
|
||||
_iconButton(
|
||||
));
|
||||
}
|
||||
|
||||
// Suppliers
|
||||
if (homeShowSuppliers) {
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().suppliers,
|
||||
FontAwesomeIcons.building,
|
||||
callback: () {
|
||||
_showSuppliers(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
}
|
||||
|
||||
// Manufacturers
|
||||
if (homeShowManufacturers) {
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().manufacturers,
|
||||
FontAwesomeIcons.industry,
|
||||
callback: () {
|
||||
_showManufacturers(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
}
|
||||
|
||||
// Customers
|
||||
if (homeShowCustomers) {
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().customers,
|
||||
FontAwesomeIcons.userTie,
|
||||
callback: () {
|
||||
_showCustomers(context);
|
||||
}
|
||||
),
|
||||
_iconButton(
|
||||
));
|
||||
}
|
||||
|
||||
// Settings
|
||||
tiles.add(_iconButton(
|
||||
context,
|
||||
L10().settings,
|
||||
FontAwesomeIcons.cogs,
|
||||
callback: () {
|
||||
_showSettings(context);
|
||||
}
|
||||
)
|
||||
];
|
||||
));
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
@override
|
||||
|
Loading…
x
Reference in New Issue
Block a user