mirror of
https://github.com/inventree/inventree-app.git
synced 2025-06-16 12:15:31 +00:00
Format code
This commit is contained in:
@ -13,34 +13,26 @@ import "package:url_launcher/url_launcher.dart";
|
||||
const String DOCS_URL = "https://docs.inventree.org/app";
|
||||
|
||||
class InvenTreeAboutWidget extends StatelessWidget {
|
||||
|
||||
const InvenTreeAboutWidget(this.info) : super();
|
||||
|
||||
final PackageInfo info;
|
||||
|
||||
Future <void> _releaseNotes(BuildContext context) async {
|
||||
|
||||
Future<void> _releaseNotes(BuildContext context) async {
|
||||
// Load release notes from external file
|
||||
String notes = await rootBundle.loadString("assets/release_notes.md");
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => ReleaseNotesWidget(notes))
|
||||
);
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (context) => ReleaseNotesWidget(notes)));
|
||||
}
|
||||
|
||||
Future <void> _credits(BuildContext context) async {
|
||||
|
||||
Future<void> _credits(BuildContext context) async {
|
||||
String notes = await rootBundle.loadString("assets/credits.md");
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => CreditsWidget(notes))
|
||||
);
|
||||
context, MaterialPageRoute(builder: (context) => CreditsWidget(notes)));
|
||||
}
|
||||
|
||||
Future <void> _openDocs() async {
|
||||
|
||||
Future<void> _openDocs() async {
|
||||
var docsUrl = Uri.parse(DOCS_URL);
|
||||
|
||||
if (await canLaunchUrl(docsUrl)) {
|
||||
@ -48,8 +40,7 @@ class InvenTreeAboutWidget extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
Future <void> _reportBug(BuildContext context) async {
|
||||
|
||||
Future<void> _reportBug(BuildContext context) async {
|
||||
var url = Uri(
|
||||
scheme: "https",
|
||||
host: "github.com",
|
||||
@ -60,11 +51,9 @@ class InvenTreeAboutWidget extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
Future <void> _translate() async {
|
||||
var url = Uri(
|
||||
scheme: "https",
|
||||
host: "crowdin.com",
|
||||
path: "/project/inventree");
|
||||
Future<void> _translate() async {
|
||||
var url =
|
||||
Uri(scheme: "https", host: "crowdin.com", path: "/project/inventree");
|
||||
|
||||
if (await canLaunchUrl(url)) {
|
||||
await launchUrl(url);
|
||||
@ -73,165 +62,137 @@ class InvenTreeAboutWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
List<Widget> tiles = [];
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().serverDetails,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(
|
||||
L10().serverDetails,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
));
|
||||
|
||||
if (InvenTreeAPI().isConnected()) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().address),
|
||||
subtitle: Text(InvenTreeAPI().baseUrl.isNotEmpty ? InvenTreeAPI().baseUrl : L10().notConnected),
|
||||
leading: Icon(TablerIcons.globe),
|
||||
trailing: InvenTreeAPI().isConnected() ? Icon(TablerIcons.circle_check, color: COLOR_SUCCESS) : Icon(TablerIcons.circle_x, color: COLOR_DANGER),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().address),
|
||||
subtitle: Text(InvenTreeAPI().baseUrl.isNotEmpty
|
||||
? InvenTreeAPI().baseUrl
|
||||
: L10().notConnected),
|
||||
leading: Icon(TablerIcons.globe),
|
||||
trailing: InvenTreeAPI().isConnected()
|
||||
? Icon(TablerIcons.circle_check, color: COLOR_SUCCESS)
|
||||
: Icon(TablerIcons.circle_x, color: COLOR_DANGER),
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().username),
|
||||
subtitle: Text(InvenTreeAPI().username),
|
||||
leading: InvenTreeAPI().username.isNotEmpty ? Icon(TablerIcons.user) : Icon(TablerIcons.user_cancel, color: COLOR_DANGER),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().username),
|
||||
subtitle: Text(InvenTreeAPI().username),
|
||||
leading: InvenTreeAPI().username.isNotEmpty
|
||||
? Icon(TablerIcons.user)
|
||||
: Icon(TablerIcons.user_cancel, color: COLOR_DANGER),
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().version),
|
||||
subtitle: Text(InvenTreeAPI().serverVersion.isNotEmpty ? InvenTreeAPI().serverVersion : L10().notConnected),
|
||||
leading: Icon(TablerIcons.info_circle),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().version),
|
||||
subtitle: Text(InvenTreeAPI().serverVersion.isNotEmpty
|
||||
? InvenTreeAPI().serverVersion
|
||||
: L10().notConnected),
|
||||
leading: Icon(TablerIcons.info_circle),
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().serverInstance),
|
||||
subtitle: Text(InvenTreeAPI().serverInstance.isNotEmpty ? InvenTreeAPI().serverInstance : L10().notConnected),
|
||||
leading: Icon(TablerIcons.server),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().serverInstance),
|
||||
subtitle: Text(InvenTreeAPI().serverInstance.isNotEmpty
|
||||
? InvenTreeAPI().serverInstance
|
||||
: L10().notConnected),
|
||||
leading: Icon(TablerIcons.server),
|
||||
));
|
||||
|
||||
// Display extra tile if the server supports plugins
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().pluginSupport),
|
||||
subtitle: Text(L10().pluginSupportDetail),
|
||||
leading: Icon(TablerIcons.plug),
|
||||
)
|
||||
);
|
||||
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().pluginSupport),
|
||||
subtitle: Text(L10().pluginSupportDetail),
|
||||
leading: Icon(TablerIcons.plug),
|
||||
));
|
||||
} else {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().notConnected),
|
||||
subtitle: Text(
|
||||
L10().serverNotConnected,
|
||||
style: TextStyle(fontStyle: FontStyle.italic),
|
||||
),
|
||||
leading: Icon(TablerIcons.exclamation_circle)
|
||||
)
|
||||
);
|
||||
leading: Icon(TablerIcons.exclamation_circle)));
|
||||
}
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().appDetails,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(
|
||||
L10().appDetails,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().packageName),
|
||||
subtitle: Text("${info.packageName}"),
|
||||
leading: Icon(TablerIcons.box)
|
||||
)
|
||||
);
|
||||
leading: Icon(TablerIcons.box)));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().version),
|
||||
subtitle: Text("${info.version} - Build ${info.buildNumber}"),
|
||||
leading: Icon(TablerIcons.info_circle)
|
||||
)
|
||||
);
|
||||
leading: Icon(TablerIcons.info_circle)));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().releaseNotes),
|
||||
subtitle: Text(L10().appReleaseNotes),
|
||||
leading: Icon(TablerIcons.file, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_releaseNotes(context);
|
||||
},
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().releaseNotes),
|
||||
subtitle: Text(L10().appReleaseNotes),
|
||||
leading: Icon(TablerIcons.file, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_releaseNotes(context);
|
||||
},
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().credits),
|
||||
subtitle: Text(L10().appCredits),
|
||||
leading: Icon(TablerIcons.balloon, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_credits(context);
|
||||
}
|
||||
)
|
||||
);
|
||||
}));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().documentation),
|
||||
subtitle: Text(DOCS_URL),
|
||||
leading: Icon(TablerIcons.book, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_openDocs();
|
||||
},
|
||||
)
|
||||
);
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().documentation),
|
||||
subtitle: Text(DOCS_URL),
|
||||
leading: Icon(TablerIcons.book, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_openDocs();
|
||||
},
|
||||
));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().translate),
|
||||
subtitle: Text(L10().translateHelp),
|
||||
leading: Icon(TablerIcons.language, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_translate();
|
||||
}
|
||||
)
|
||||
);
|
||||
}));
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().reportBug),
|
||||
subtitle: Text(L10().reportBugDescription),
|
||||
leading: Icon(TablerIcons.bug, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().reportBug),
|
||||
subtitle: Text(L10().reportBugDescription),
|
||||
leading: Icon(TablerIcons.bug, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
_reportBug(context);
|
||||
},
|
||||
)
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().appAbout),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: ListView(
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: tiles,
|
||||
).toList(),
|
||||
)
|
||||
);
|
||||
appBar: AppBar(
|
||||
title: Text(L10().appAbout),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: ListView(
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: tiles,
|
||||
).toList(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,17 +16,16 @@ import "package:inventree/preferences.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
|
||||
class InvenTreeAppSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
_InvenTreeAppSettingsState createState() => _InvenTreeAppSettingsState();
|
||||
}
|
||||
|
||||
class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
|
||||
_InvenTreeAppSettingsState();
|
||||
|
||||
final GlobalKey<_InvenTreeAppSettingsState> _settingsKey = GlobalKey<_InvenTreeAppSettingsState>();
|
||||
final GlobalKey<_InvenTreeAppSettingsState> _settingsKey =
|
||||
GlobalKey<_InvenTreeAppSettingsState>();
|
||||
|
||||
// Sound settings
|
||||
bool barcodeSounds = true;
|
||||
@ -48,16 +47,21 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
loadSettings(OneContext().context!);
|
||||
}
|
||||
|
||||
Future <void> loadSettings(BuildContext context) async {
|
||||
|
||||
Future<void> loadSettings(BuildContext context) async {
|
||||
showLoadingOverlay();
|
||||
|
||||
barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
|
||||
serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
|
||||
reportErrors = await InvenTreeSettingsManager().getValue(INV_REPORT_ERRORS, true) as bool;
|
||||
strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool;
|
||||
screenOrientation = await InvenTreeSettingsManager().getValue(INV_SCREEN_ORIENTATION, SCREEN_ORIENTATION_SYSTEM) as int;
|
||||
enableLabelPrinting = await InvenTreeSettingsManager().getValue(INV_ENABLE_LABEL_PRINTING, true) as bool;
|
||||
barcodeSounds = await InvenTreeSettingsManager()
|
||||
.getValue(INV_SOUNDS_BARCODE, true) as bool;
|
||||
serverSounds = await InvenTreeSettingsManager()
|
||||
.getValue(INV_SOUNDS_SERVER, true) as bool;
|
||||
reportErrors = await InvenTreeSettingsManager()
|
||||
.getValue(INV_REPORT_ERRORS, true) as bool;
|
||||
strictHttps = await InvenTreeSettingsManager()
|
||||
.getValue(INV_STRICT_HTTPS, false) as bool;
|
||||
screenOrientation = await InvenTreeSettingsManager()
|
||||
.getValue(INV_SCREEN_ORIENTATION, SCREEN_ORIENTATION_SYSTEM) as int;
|
||||
enableLabelPrinting = await InvenTreeSettingsManager()
|
||||
.getValue(INV_ENABLE_LABEL_PRINTING, true) as bool;
|
||||
|
||||
darkMode = AdaptiveTheme.of(context).mode.isDark;
|
||||
|
||||
@ -71,7 +75,6 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
}
|
||||
|
||||
Future<void> _selectLocale(BuildContext context) async {
|
||||
|
||||
List<Map<String, dynamic>> options = [
|
||||
{
|
||||
"display_name": L10().languageDefault,
|
||||
@ -96,46 +99,39 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
}
|
||||
};
|
||||
|
||||
launchApiForm(
|
||||
context,
|
||||
L10().languageSelect,
|
||||
"",
|
||||
fields,
|
||||
icon: TablerIcons.circle_check,
|
||||
onSuccess: (Map<String, dynamic> data) async {
|
||||
launchApiForm(context, L10().languageSelect, "", fields,
|
||||
icon: TablerIcons.circle_check,
|
||||
onSuccess: (Map<String, dynamic> data) async {
|
||||
String locale_name = (data["locale"] ?? "") as String;
|
||||
Locale? selected_locale;
|
||||
|
||||
String locale_name = (data["locale"] ?? "") as String;
|
||||
Locale? selected_locale;
|
||||
|
||||
for (var locale in supported_locales) {
|
||||
if (locale.toString() == locale_name) {
|
||||
selected_locale = locale;
|
||||
}
|
||||
for (var locale in supported_locales) {
|
||||
if (locale.toString() == locale_name) {
|
||||
selected_locale = locale;
|
||||
}
|
||||
|
||||
await InvenTreeSettingsManager().setSelectedLocale(selected_locale);
|
||||
|
||||
setState(() {
|
||||
locale = selected_locale;
|
||||
});
|
||||
|
||||
// Refresh the entire app locale
|
||||
InvenTreeApp.of(context)?.setLocale(locale);
|
||||
|
||||
// Clear the cached status label information
|
||||
InvenTreeAPI().clearStatusCodeData();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
await InvenTreeSettingsManager().setSelectedLocale(selected_locale);
|
||||
|
||||
setState(() {
|
||||
locale = selected_locale;
|
||||
});
|
||||
|
||||
// Refresh the entire app locale
|
||||
InvenTreeApp.of(context)?.setLocale(locale);
|
||||
|
||||
// Clear the cached status label information
|
||||
InvenTreeAPI().clearStatusCodeData();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
String languageName = L10().languageDefault;
|
||||
|
||||
if (locale != null) {
|
||||
languageName = LocaleNames.of(context)!.nameOf(locale.toString()) ?? L10().languageDefault;
|
||||
languageName = LocaleNames.of(context)!.nameOf(locale.toString()) ??
|
||||
L10().languageDefault;
|
||||
}
|
||||
|
||||
IconData orientationIcon = Icons.screen_rotation;
|
||||
@ -154,166 +150,163 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
key: _settingsKey,
|
||||
appBar: AppBar(
|
||||
title: Text(L10().appSettings),
|
||||
backgroundColor: COLOR_APP_BAR
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
/* Sound Settings */
|
||||
Divider(height: 3),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().appSettings,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
leading: Icon(TablerIcons.device_mobile),
|
||||
key: _settingsKey,
|
||||
appBar: AppBar(
|
||||
title: Text(L10().appSettings), backgroundColor: COLOR_APP_BAR),
|
||||
body: Container(
|
||||
child: ListView(children: [
|
||||
/* Sound Settings */
|
||||
Divider(height: 3),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().appSettings,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(TablerIcons.device_mobile),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().darkMode),
|
||||
subtitle: Text(L10().darkModeEnable),
|
||||
leading: Icon(TablerIcons.sun_moon),
|
||||
trailing: Switch(
|
||||
value: darkMode,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
AdaptiveTheme.of(context).setDark();
|
||||
} else {
|
||||
AdaptiveTheme.of(context).setLight();
|
||||
}
|
||||
setState(() {
|
||||
darkMode = value;
|
||||
});
|
||||
}
|
||||
)
|
||||
),
|
||||
GestureDetector(
|
||||
child: ListTile(
|
||||
title: Text(L10().orientation),
|
||||
subtitle: Text(L10().orientationDetail),
|
||||
leading: Icon(Icons.screen_rotation_alt),
|
||||
trailing: Icon(orientationIcon),
|
||||
),
|
||||
onTap: () async {
|
||||
choiceDialog(
|
||||
L10().orientation,
|
||||
[
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_rotation, color: screenOrientation == SCREEN_ORIENTATION_SYSTEM ? COLOR_ACTION : null),
|
||||
title: Text(L10().orientationSystem),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_lock_portrait, color: screenOrientation == SCREEN_ORIENTATION_PORTRAIT ? COLOR_ACTION : null),
|
||||
title: Text(L10().orientationPortrait),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_lock_landscape, color: screenOrientation == SCREEN_ORIENTATION_LANDSCAPE ? COLOR_ACTION : null),
|
||||
title: Text(L10().orientationLandscape),
|
||||
)
|
||||
],
|
||||
onSelected: (idx) async {
|
||||
screenOrientation = idx as int;
|
||||
|
||||
InvenTreeSettingsManager().setValue(INV_SCREEN_ORIENTATION, screenOrientation);
|
||||
|
||||
value: darkMode,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
AdaptiveTheme.of(context).setDark();
|
||||
} else {
|
||||
AdaptiveTheme.of(context).setLight();
|
||||
}
|
||||
setState(() {
|
||||
darkMode = value;
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
})),
|
||||
GestureDetector(
|
||||
child: ListTile(
|
||||
title: Text(L10().orientation),
|
||||
subtitle: Text(L10().orientationDetail),
|
||||
leading: Icon(Icons.screen_rotation_alt),
|
||||
trailing: Icon(orientationIcon),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().labelPrinting),
|
||||
subtitle: Text(L10().labelPrintingDetail),
|
||||
leading: Icon(TablerIcons.printer),
|
||||
trailing: Switch(
|
||||
onTap: () async {
|
||||
choiceDialog(L10().orientation, [
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_rotation,
|
||||
color: screenOrientation == SCREEN_ORIENTATION_SYSTEM
|
||||
? COLOR_ACTION
|
||||
: null),
|
||||
title: Text(L10().orientationSystem),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_lock_portrait,
|
||||
color: screenOrientation == SCREEN_ORIENTATION_PORTRAIT
|
||||
? COLOR_ACTION
|
||||
: null),
|
||||
title: Text(L10().orientationPortrait),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.screen_lock_landscape,
|
||||
color: screenOrientation == SCREEN_ORIENTATION_LANDSCAPE
|
||||
? COLOR_ACTION
|
||||
: null),
|
||||
title: Text(L10().orientationLandscape),
|
||||
)
|
||||
], onSelected: (idx) async {
|
||||
screenOrientation = idx as int;
|
||||
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_SCREEN_ORIENTATION, screenOrientation);
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().labelPrinting),
|
||||
subtitle: Text(L10().labelPrintingDetail),
|
||||
leading: Icon(TablerIcons.printer),
|
||||
trailing: Switch(
|
||||
value: enableLabelPrinting,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_ENABLE_LABEL_PRINTING, value);
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_ENABLE_LABEL_PRINTING, value);
|
||||
setState(() {
|
||||
enableLabelPrinting = value;
|
||||
});
|
||||
}
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().strictHttps),
|
||||
subtitle: Text(L10().strictHttpsDetails),
|
||||
leading: Icon(TablerIcons.lock),
|
||||
trailing: Switch(
|
||||
value: strictHttps,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STRICT_HTTPS, value);
|
||||
setState(() {
|
||||
strictHttps = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().language),
|
||||
subtitle: Text(languageName),
|
||||
leading: Icon(TablerIcons.language),
|
||||
onTap: () async {
|
||||
_selectLocale(context);
|
||||
}),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().strictHttps),
|
||||
subtitle: Text(L10().strictHttpsDetails),
|
||||
leading: Icon(TablerIcons.lock),
|
||||
trailing: Switch(
|
||||
value: strictHttps,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STRICT_HTTPS, value);
|
||||
setState(() {
|
||||
strictHttps = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().errorReportUpload),
|
||||
subtitle: Text(L10().errorReportUploadDetails),
|
||||
leading: Icon(TablerIcons.bug),
|
||||
trailing: Switch(
|
||||
value: reportErrors,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_REPORT_ERRORS, value);
|
||||
setState(() {
|
||||
reportErrors = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().language),
|
||||
subtitle: Text(languageName),
|
||||
leading: Icon(TablerIcons.language),
|
||||
onTap: () async {
|
||||
_selectLocale(context);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().errorReportUpload),
|
||||
subtitle: Text(L10().errorReportUploadDetails),
|
||||
leading: Icon(TablerIcons.bug),
|
||||
trailing: Switch(
|
||||
value: reportErrors,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_REPORT_ERRORS, value);
|
||||
setState(() {
|
||||
reportErrors = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().sounds,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
leading: Icon(TablerIcons.volume),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10().sounds,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().serverError),
|
||||
subtitle: Text(L10().soundOnServerError),
|
||||
leading: Icon(TablerIcons.server),
|
||||
trailing: Switch(
|
||||
value: serverSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_SERVER, value);
|
||||
setState(() {
|
||||
serverSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
leading: Icon(TablerIcons.volume),
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().serverError),
|
||||
subtitle: Text(L10().soundOnServerError),
|
||||
leading: Icon(TablerIcons.server),
|
||||
trailing: Switch(
|
||||
value: serverSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_SERVER, value);
|
||||
setState(() {
|
||||
serverSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().barcodeTones),
|
||||
subtitle: Text(L10().soundOnBarcodeAction),
|
||||
leading: Icon(TablerIcons.qrcode),
|
||||
trailing: Switch(
|
||||
value: barcodeSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_BARCODE, value);
|
||||
setState(() {
|
||||
barcodeSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().barcodeTones),
|
||||
subtitle: Text(L10().soundOnBarcodeAction),
|
||||
leading: Icon(TablerIcons.qrcode),
|
||||
trailing: Switch(
|
||||
value: barcodeSounds,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SOUNDS_BARCODE, value);
|
||||
setState(() {
|
||||
barcodeSounds = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
Divider(height: 1),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
),
|
||||
Divider(height: 1),
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,97 +7,98 @@ import "package:inventree/app_colors.dart";
|
||||
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
|
||||
|
||||
class InvenTreeBarcodeSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
_InvenTreeBarcodeSettingsState createState() => _InvenTreeBarcodeSettingsState();
|
||||
_InvenTreeBarcodeSettingsState createState() =>
|
||||
_InvenTreeBarcodeSettingsState();
|
||||
}
|
||||
|
||||
class _InvenTreeBarcodeSettingsState
|
||||
extends State<InvenTreeBarcodeSettingsWidget> {
|
||||
_InvenTreeBarcodeSettingsState();
|
||||
|
||||
class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidget> {
|
||||
int barcodeScanDelay = 500;
|
||||
int barcodeScanType = BARCODE_CONTROLLER_CAMERA;
|
||||
bool barcodeScanSingle = false;
|
||||
|
||||
_InvenTreeBarcodeSettingsState();
|
||||
final TextEditingController _barcodeScanDelayController =
|
||||
TextEditingController();
|
||||
|
||||
int barcodeScanDelay = 500;
|
||||
int barcodeScanType = BARCODE_CONTROLLER_CAMERA;
|
||||
bool barcodeScanSingle = false;
|
||||
|
||||
final TextEditingController _barcodeScanDelayController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadSettings();
|
||||
}
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
Future<void> loadSettings() async {
|
||||
barcodeScanDelay = await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
|
||||
barcodeScanType = await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_TYPE, BARCODE_CONTROLLER_CAMERA) as int;
|
||||
barcodeScanSingle = await InvenTreeSettingsManager().getBool(INV_BARCODE_SCAN_SINGLE, false);
|
||||
barcodeScanDelay = await InvenTreeSettingsManager()
|
||||
.getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
|
||||
barcodeScanType = await InvenTreeSettingsManager()
|
||||
.getValue(INV_BARCODE_SCAN_TYPE, BARCODE_CONTROLLER_CAMERA) as int;
|
||||
barcodeScanSingle = await InvenTreeSettingsManager()
|
||||
.getBool(INV_BARCODE_SCAN_SINGLE, false);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
// Callback function to edit the barcode scan delay value
|
||||
// TODO: Next time any new settings are added, refactor this into a generic function
|
||||
Future<void> _editBarcodeScanDelay(BuildContext context) async {
|
||||
|
||||
_barcodeScanDelayController.text = barcodeScanDelay.toString();
|
||||
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(L10().barcodeScanDelay),
|
||||
content: TextField(
|
||||
onChanged: (value) {},
|
||||
controller: _barcodeScanDelayController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
hintText: L10().barcodeScanDelayDetail,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(L10().barcodeScanDelay),
|
||||
content: TextField(
|
||||
onChanged: (value) {},
|
||||
controller: _barcodeScanDelayController,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
hintText: L10().barcodeScanDelayDetail,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
MaterialButton(
|
||||
color: Colors.red,
|
||||
textColor: Colors.white,
|
||||
child: Text(L10().cancel),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
MaterialButton(
|
||||
color: Colors.green,
|
||||
textColor: Colors.white,
|
||||
child: Text(L10().ok),
|
||||
onPressed: () async {
|
||||
int delay = int.tryParse(_barcodeScanDelayController.text) ?? barcodeScanDelay;
|
||||
actions: <Widget>[
|
||||
MaterialButton(
|
||||
color: Colors.red,
|
||||
textColor: Colors.white,
|
||||
child: Text(L10().cancel),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
MaterialButton(
|
||||
color: Colors.green,
|
||||
textColor: Colors.white,
|
||||
child: Text(L10().ok),
|
||||
onPressed: () async {
|
||||
int delay = int.tryParse(_barcodeScanDelayController.text) ??
|
||||
barcodeScanDelay;
|
||||
|
||||
// Apply limits
|
||||
if (delay < 100) delay = 100;
|
||||
if (delay > 2500) delay = 2500;
|
||||
// Apply limits
|
||||
if (delay < 100) delay = 100;
|
||||
if (delay > 2500) delay = 2500;
|
||||
|
||||
InvenTreeSettingsManager().setValue(INV_BARCODE_SCAN_DELAY, delay);
|
||||
setState(() {
|
||||
barcodeScanDelay = delay;
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_BARCODE_SCAN_DELAY, delay);
|
||||
setState(() {
|
||||
barcodeScanDelay = delay;
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
// Construct an icon for the barcode scanner input
|
||||
Widget? barcodeInputIcon;
|
||||
|
||||
@ -112,22 +113,18 @@ class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidge
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().barcodeSettings),
|
||||
backgroundColor: COLOR_APP_BAR
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().barcodeSettings), backgroundColor: COLOR_APP_BAR),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().barcodeScanController),
|
||||
subtitle: Text(L10().barcodeScanControllerDetail),
|
||||
leading: Icon(Icons.qr_code_scanner),
|
||||
trailing: barcodeInputIcon,
|
||||
onTap: () async {
|
||||
choiceDialog(
|
||||
L10().barcodeScanController,
|
||||
[
|
||||
title: Text(L10().barcodeScanController),
|
||||
subtitle: Text(L10().barcodeScanControllerDetail),
|
||||
leading: Icon(Icons.qr_code_scanner),
|
||||
trailing: barcodeInputIcon,
|
||||
onTap: () async {
|
||||
choiceDialog(L10().barcodeScanController, [
|
||||
ListTile(
|
||||
title: Text(L10().cameraInternal),
|
||||
subtitle: Text(L10().cameraInternalDetail),
|
||||
@ -138,17 +135,15 @@ class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidge
|
||||
subtitle: Text(L10().scannerExternalDetail),
|
||||
leading: Icon(Icons.barcode_reader),
|
||||
)
|
||||
],
|
||||
onSelected: (idx) async {
|
||||
], onSelected: (idx) async {
|
||||
barcodeScanType = idx as int;
|
||||
InvenTreeSettingsManager().setValue(INV_BARCODE_SCAN_TYPE, barcodeScanType);
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_BARCODE_SCAN_TYPE, barcodeScanType);
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
),
|
||||
});
|
||||
}),
|
||||
ListTile(
|
||||
title: Text(L10().barcodeScanDelay),
|
||||
subtitle: Text(L10().barcodeScanDelayDetail),
|
||||
@ -167,7 +162,8 @@ class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidge
|
||||
trailing: Switch(
|
||||
value: barcodeScanSingle,
|
||||
onChanged: (bool v) {
|
||||
InvenTreeSettingsManager().setValue(INV_BARCODE_SCAN_SINGLE, v);
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_BARCODE_SCAN_SINGLE, v);
|
||||
setState(() {
|
||||
barcodeScanSingle = v;
|
||||
});
|
||||
@ -175,9 +171,6 @@ class _InvenTreeBarcodeSettingsState extends State<InvenTreeBarcodeSettingsWidge
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
@ -12,10 +11,10 @@ class HomeScreenSettingsWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _HomeScreenSettingsState extends State<HomeScreenSettingsWidget> {
|
||||
|
||||
_HomeScreenSettingsState();
|
||||
|
||||
final GlobalKey<_HomeScreenSettingsState> _settingsKey = GlobalKey<_HomeScreenSettingsState>();
|
||||
final GlobalKey<_HomeScreenSettingsState> _settingsKey =
|
||||
GlobalKey<_HomeScreenSettingsState>();
|
||||
|
||||
// Home screen settings
|
||||
bool homeShowSubscribed = true;
|
||||
@ -32,24 +31,27 @@ class _HomeScreenSettingsState extends State<HomeScreenSettingsWidget> {
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
Future <void> loadSettings() async {
|
||||
|
||||
Future<void> loadSettings() async {
|
||||
// Load initial settings
|
||||
|
||||
homeShowSubscribed = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
|
||||
homeShowPo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_PO, true) as bool;
|
||||
homeShowSo = await InvenTreeSettingsManager().getValue(INV_HOME_SHOW_SO, 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;
|
||||
homeShowSubscribed = await InvenTreeSettingsManager()
|
||||
.getValue(INV_HOME_SHOW_SUBSCRIBED, true) as bool;
|
||||
homeShowPo = await InvenTreeSettingsManager()
|
||||
.getValue(INV_HOME_SHOW_PO, true) as bool;
|
||||
homeShowSo = await InvenTreeSettingsManager()
|
||||
.getValue(INV_HOME_SHOW_SO, 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;
|
||||
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Scaffold(
|
||||
key: _settingsKey,
|
||||
appBar: AppBar(
|
||||
@ -57,67 +59,67 @@ class _HomeScreenSettingsState extends State<HomeScreenSettingsWidget> {
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSubscribed),
|
||||
subtitle: Text(L10().homeShowSubscribedDescription),
|
||||
leading: Icon(TablerIcons.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: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: homeShowPo,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_PO, value);
|
||||
setState(() {
|
||||
homeShowPo = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSo),
|
||||
subtitle: Text(L10().homeShowSoDescription),
|
||||
leading: Icon(TablerIcons.truck),
|
||||
trailing: Switch(
|
||||
value: homeShowSo,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SO, value);
|
||||
setState(() {
|
||||
homeShowSo = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSuppliers),
|
||||
subtitle: Text(L10().homeShowSuppliersDescription),
|
||||
leading: Icon(TablerIcons.building),
|
||||
trailing: Switch(
|
||||
value: homeShowSuppliers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SUPPLIERS, value);
|
||||
setState(() {
|
||||
homeShowSuppliers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
// TODO: When these features are improved, add them back in!
|
||||
// Currently, the company display does not provide any value
|
||||
/*
|
||||
child: ListView(children: [
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSubscribed),
|
||||
subtitle: Text(L10().homeShowSubscribedDescription),
|
||||
leading: Icon(TablerIcons.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: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: homeShowPo,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_PO, value);
|
||||
setState(() {
|
||||
homeShowPo = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSo),
|
||||
subtitle: Text(L10().homeShowSoDescription),
|
||||
leading: Icon(TablerIcons.truck),
|
||||
trailing: Switch(
|
||||
value: homeShowSo,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_SO, value);
|
||||
setState(() {
|
||||
homeShowSo = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeShowSuppliers),
|
||||
subtitle: Text(L10().homeShowSuppliersDescription),
|
||||
leading: Icon(TablerIcons.building),
|
||||
trailing: Switch(
|
||||
value: homeShowSuppliers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_HOME_SHOW_SUPPLIERS, value);
|
||||
setState(() {
|
||||
homeShowSuppliers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
// TODO: When these features are improved, add them back in!
|
||||
// Currently, the company display does not provide any value
|
||||
/*
|
||||
ListTile(
|
||||
title: Text(L10().homeShowManufacturers),
|
||||
subtitle: Text(L10().homeShowManufacturersDescription),
|
||||
@ -133,23 +135,21 @@ class _HomeScreenSettingsState extends State<HomeScreenSettingsWidget> {
|
||||
),
|
||||
),
|
||||
*/
|
||||
ListTile(
|
||||
title: Text(L10().homeShowCustomers),
|
||||
subtitle: Text(L10().homeShowCustomersDescription),
|
||||
leading: Icon(TablerIcons.user),
|
||||
trailing: Switch(
|
||||
value: homeShowCustomers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_HOME_SHOW_CUSTOMERS, value);
|
||||
setState(() {
|
||||
homeShowCustomers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
ListTile(
|
||||
title: Text(L10().homeShowCustomers),
|
||||
subtitle: Text(L10().homeShowCustomersDescription),
|
||||
leading: Icon(TablerIcons.user),
|
||||
trailing: Switch(
|
||||
value: homeShowCustomers,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_HOME_SHOW_CUSTOMERS, value);
|
||||
setState(() {
|
||||
homeShowCustomers = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
|
||||
@ -9,21 +8,16 @@ import "package:inventree/api.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
|
||||
class InvenTreeLoginWidget extends StatefulWidget {
|
||||
|
||||
const InvenTreeLoginWidget(this.profile) : super();
|
||||
|
||||
final UserProfile profile;
|
||||
|
||||
@override
|
||||
_InvenTreeLoginState createState() => _InvenTreeLoginState();
|
||||
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
|
||||
|
||||
final formKey = GlobalKey<FormState>();
|
||||
|
||||
String username = "";
|
||||
@ -35,14 +29,12 @@ class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
|
||||
|
||||
// Attempt login
|
||||
Future<void> _doLogin(BuildContext context) async {
|
||||
|
||||
// Save form
|
||||
formKey.currentState?.save();
|
||||
|
||||
bool valid = formKey.currentState?.validate() ?? false;
|
||||
|
||||
if (valid) {
|
||||
|
||||
// Dismiss the keyboard
|
||||
FocusScopeNode currentFocus = FocusScope.of(context);
|
||||
|
||||
@ -53,7 +45,8 @@ class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
|
||||
showLoadingOverlay();
|
||||
|
||||
// Attempt login
|
||||
final response = await InvenTreeAPI().fetchToken(widget.profile, username, password);
|
||||
final response =
|
||||
await InvenTreeAPI().fetchToken(widget.profile, username, password);
|
||||
|
||||
hideLoadingOverlay();
|
||||
|
||||
@ -75,12 +68,10 @@ class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
List<Widget> before = [
|
||||
ListTile(
|
||||
title: Text(L10().loginEnter),
|
||||
@ -106,82 +97,77 @@ class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
|
||||
));
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().login),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(TablerIcons.transition_right, color: COLOR_SUCCESS),
|
||||
onPressed: () async {
|
||||
_doLogin(context);
|
||||
},
|
||||
)
|
||||
]
|
||||
),
|
||||
body: Form(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...before,
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().username,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: L10().enterUsername
|
||||
),
|
||||
initialValue: "",
|
||||
keyboardType: TextInputType.text,
|
||||
onSaved: (value) {
|
||||
username = value?.trim() ?? "";
|
||||
appBar: AppBar(
|
||||
title: Text(L10().login),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(TablerIcons.transition_right, color: COLOR_SUCCESS),
|
||||
onPressed: () async {
|
||||
_doLogin(context);
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().usernameEmpty;
|
||||
}
|
||||
)
|
||||
]),
|
||||
body: Form(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...before,
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().username,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: L10().enterUsername),
|
||||
initialValue: "",
|
||||
keyboardType: TextInputType.text,
|
||||
onSaved: (value) {
|
||||
username = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().usernameEmpty;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().password,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: L10().enterPassword,
|
||||
suffixIcon: IconButton(
|
||||
icon: _obscured ? Icon(TablerIcons.eye) : Icon(TablerIcons.eye_off),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_obscured = !_obscured;
|
||||
});
|
||||
},
|
||||
),
|
||||
return null;
|
||||
},
|
||||
),
|
||||
initialValue: "",
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
obscureText: _obscured,
|
||||
onSaved: (value) {
|
||||
password = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().passwordEmpty;
|
||||
}
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().password,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: L10().enterPassword,
|
||||
suffixIcon: IconButton(
|
||||
icon: _obscured
|
||||
? Icon(TablerIcons.eye)
|
||||
: Icon(TablerIcons.eye_off),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_obscured = !_obscured;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
initialValue: "",
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
obscureText: _obscured,
|
||||
onSaved: (value) {
|
||||
password = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().passwordEmpty;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
...after,
|
||||
],
|
||||
),
|
||||
...after,
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.all(16),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
padding: EdgeInsets.all(16),
|
||||
)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
|
||||
@ -6,15 +5,12 @@ import "package:inventree/l10.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
|
||||
class InvenTreePartSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
_InvenTreePartSettingsState createState() => _InvenTreePartSettingsState();
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreePartSettingsState extends State<InvenTreePartSettingsWidget> {
|
||||
|
||||
_InvenTreePartSettingsState();
|
||||
|
||||
bool partShowParameters = true;
|
||||
@ -32,117 +28,120 @@ class _InvenTreePartSettingsState extends State<InvenTreePartSettingsWidget> {
|
||||
}
|
||||
|
||||
Future<void> loadSettings() async {
|
||||
partShowParameters = await InvenTreeSettingsManager().getBool(INV_PART_SHOW_PARAMETERS, true);
|
||||
partShowBom = await InvenTreeSettingsManager().getBool(INV_PART_SHOW_BOM, true);
|
||||
partShowPricing = await InvenTreeSettingsManager().getBool(INV_PART_SHOW_PRICING, true);
|
||||
stockShowHistory = await InvenTreeSettingsManager().getBool(INV_STOCK_SHOW_HISTORY, false);
|
||||
stockShowTests = await InvenTreeSettingsManager().getBool(INV_STOCK_SHOW_TESTS, true);
|
||||
stockConfirmScan = await InvenTreeSettingsManager().getBool(INV_STOCK_CONFIRM_SCAN, false);
|
||||
partShowParameters = await InvenTreeSettingsManager()
|
||||
.getBool(INV_PART_SHOW_PARAMETERS, true);
|
||||
partShowBom =
|
||||
await InvenTreeSettingsManager().getBool(INV_PART_SHOW_BOM, true);
|
||||
partShowPricing =
|
||||
await InvenTreeSettingsManager().getBool(INV_PART_SHOW_PRICING, true);
|
||||
stockShowHistory =
|
||||
await InvenTreeSettingsManager().getBool(INV_STOCK_SHOW_HISTORY, false);
|
||||
stockShowTests =
|
||||
await InvenTreeSettingsManager().getBool(INV_STOCK_SHOW_TESTS, true);
|
||||
stockConfirmScan =
|
||||
await InvenTreeSettingsManager().getBool(INV_STOCK_CONFIRM_SCAN, false);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().partSettings),
|
||||
backgroundColor: COLOR_APP_BAR
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().parameters),
|
||||
subtitle: Text(L10().parametersSettingDetail),
|
||||
leading: Icon(TablerIcons.list),
|
||||
trailing: Switch(
|
||||
value: partShowParameters,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PART_SHOW_PARAMETERS, value);
|
||||
setState(() {
|
||||
partShowParameters = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
appBar: AppBar(
|
||||
title: Text(L10().partSettings), backgroundColor: COLOR_APP_BAR),
|
||||
body: Container(
|
||||
child: ListView(children: [
|
||||
ListTile(
|
||||
title: Text(L10().parameters),
|
||||
subtitle: Text(L10().parametersSettingDetail),
|
||||
leading: Icon(TablerIcons.list),
|
||||
trailing: Switch(
|
||||
value: partShowParameters,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_PART_SHOW_PARAMETERS, value);
|
||||
setState(() {
|
||||
partShowParameters = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().bom),
|
||||
subtitle: Text(L10().bomEnable),
|
||||
leading: Icon(TablerIcons.list),
|
||||
trailing: Switch(
|
||||
value: partShowBom,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PART_SHOW_BOM, value);
|
||||
setState(() {
|
||||
partShowBom = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().bom),
|
||||
subtitle: Text(L10().bomEnable),
|
||||
leading: Icon(TablerIcons.list),
|
||||
trailing: Switch(
|
||||
value: partShowBom,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PART_SHOW_BOM, value);
|
||||
setState(() {
|
||||
partShowBom = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().partPricing),
|
||||
subtitle: Text(L10().partPricingSettingDetail),
|
||||
leading: Icon(TablerIcons.currency_dollar),
|
||||
trailing: Switch(
|
||||
value: partShowPricing,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PART_SHOW_PRICING, value);
|
||||
setState(() {
|
||||
partShowPricing = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().partPricing),
|
||||
subtitle: Text(L10().partPricingSettingDetail),
|
||||
leading: Icon(TablerIcons.currency_dollar),
|
||||
trailing: Switch(
|
||||
value: partShowPricing,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_PART_SHOW_PRICING, value);
|
||||
setState(() {
|
||||
partShowPricing = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().stockItemHistory),
|
||||
subtitle: Text(L10().stockItemHistoryDetail),
|
||||
leading: Icon(TablerIcons.history),
|
||||
trailing: Switch(
|
||||
value: stockShowHistory,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STOCK_SHOW_HISTORY, value);
|
||||
setState(() {
|
||||
stockShowHistory = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().stockItemHistory),
|
||||
subtitle: Text(L10().stockItemHistoryDetail),
|
||||
leading: Icon(TablerIcons.history),
|
||||
trailing: Switch(
|
||||
value: stockShowHistory,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_STOCK_SHOW_HISTORY, value);
|
||||
setState(() {
|
||||
stockShowHistory = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().testResults),
|
||||
subtitle: Text(L10().testResultsDetail),
|
||||
leading: Icon(TablerIcons.test_pipe),
|
||||
trailing: Switch(
|
||||
value: stockShowTests,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STOCK_SHOW_TESTS, value);
|
||||
setState(() {
|
||||
stockShowTests = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().testResults),
|
||||
subtitle: Text(L10().testResultsDetail),
|
||||
leading: Icon(TablerIcons.test_pipe),
|
||||
trailing: Switch(
|
||||
value: stockShowTests,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_STOCK_SHOW_TESTS, value);
|
||||
setState(() {
|
||||
stockShowTests = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().confirmScan),
|
||||
subtitle: Text(L10().confirmScanDetail),
|
||||
leading: Icon(TablerIcons.qrcode),
|
||||
trailing: Switch(
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().confirmScan),
|
||||
subtitle: Text(L10().confirmScanDetail),
|
||||
leading: Icon(TablerIcons.qrcode),
|
||||
trailing: Switch(
|
||||
value: stockConfirmScan,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_STOCK_CONFIRM_SCAN, value);
|
||||
InvenTreeSettingsManager()
|
||||
.setValue(INV_STOCK_CONFIRM_SCAN, value);
|
||||
setState(() {
|
||||
stockConfirmScan = value;
|
||||
});
|
||||
}
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
}),
|
||||
)
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
@ -6,15 +5,14 @@ import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
|
||||
class InvenTreePurchaseOrderSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
_InvenTreePurchaseOrderSettingsState createState() => _InvenTreePurchaseOrderSettingsState();
|
||||
_InvenTreePurchaseOrderSettingsState createState() =>
|
||||
_InvenTreePurchaseOrderSettingsState();
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreePurchaseOrderSettingsState extends State<InvenTreePurchaseOrderSettingsWidget> {
|
||||
|
||||
class _InvenTreePurchaseOrderSettingsState
|
||||
extends State<InvenTreePurchaseOrderSettingsWidget> {
|
||||
_InvenTreePurchaseOrderSettingsState();
|
||||
|
||||
bool poEnable = true;
|
||||
@ -30,12 +28,13 @@ class _InvenTreePurchaseOrderSettingsState extends State<InvenTreePurchaseOrderS
|
||||
|
||||
Future<void> loadSettings() async {
|
||||
poEnable = await InvenTreeSettingsManager().getBool(INV_PO_ENABLE, true);
|
||||
poShowCamera = await InvenTreeSettingsManager().getBool(INV_PO_SHOW_CAMERA, true);
|
||||
poConfirmScan = await InvenTreeSettingsManager().getBool(INV_PO_CONFIRM_SCAN, true);
|
||||
poShowCamera =
|
||||
await InvenTreeSettingsManager().getBool(INV_PO_SHOW_CAMERA, true);
|
||||
poConfirmScan =
|
||||
await InvenTreeSettingsManager().getBool(INV_PO_CONFIRM_SCAN, true);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,53 +46,49 @@ class _InvenTreePurchaseOrderSettingsState extends State<InvenTreePurchaseOrderS
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderEnable),
|
||||
subtitle: Text(L10().purchaseOrderEnableDetail),
|
||||
leading: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: poEnable,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_ENABLE, value);
|
||||
setState(() {
|
||||
poEnable = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderShowCamera),
|
||||
subtitle: Text(L10().purchaseOrderShowCameraDetail),
|
||||
leading: Icon(TablerIcons.camera),
|
||||
trailing: Switch(
|
||||
value: poShowCamera,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_SHOW_CAMERA, value);
|
||||
setState(() {
|
||||
poShowCamera = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderConfirmScan),
|
||||
subtitle: Text(L10().purchaseOrderConfirmScanDetail),
|
||||
leading: Icon(TablerIcons.barcode),
|
||||
trailing: Switch (
|
||||
value: poConfirmScan,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_CONFIRM_SCAN, value);
|
||||
setState(() {
|
||||
poConfirmScan = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
child: ListView(children: [
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderEnable),
|
||||
subtitle: Text(L10().purchaseOrderEnableDetail),
|
||||
leading: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: poEnable,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_ENABLE, value);
|
||||
setState(() {
|
||||
poEnable = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderShowCamera),
|
||||
subtitle: Text(L10().purchaseOrderShowCameraDetail),
|
||||
leading: Icon(TablerIcons.camera),
|
||||
trailing: Switch(
|
||||
value: poShowCamera,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_SHOW_CAMERA, value);
|
||||
setState(() {
|
||||
poShowCamera = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrderConfirmScan),
|
||||
subtitle: Text(L10().purchaseOrderConfirmScanDetail),
|
||||
leading: Icon(TablerIcons.barcode),
|
||||
trailing: Switch(
|
||||
value: poConfirmScan,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_PO_CONFIRM_SCAN, value);
|
||||
setState(() {
|
||||
poConfirmScan = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,44 +6,38 @@ import "package:url_launcher/url_launcher.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/helpers.dart";
|
||||
|
||||
|
||||
class ReleaseNotesWidget extends StatelessWidget {
|
||||
|
||||
const ReleaseNotesWidget(this.releaseNotes);
|
||||
|
||||
final String releaseNotes;
|
||||
|
||||
@override
|
||||
Widget build (BuildContext context) {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().releaseNotes),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Markdown(
|
||||
selectable: false,
|
||||
data: releaseNotes,
|
||||
onTapLink: (url, href, title) {
|
||||
var link = href ?? "";
|
||||
if (link.isNotEmpty) {
|
||||
openLink(link);
|
||||
}
|
||||
},
|
||||
)
|
||||
);
|
||||
appBar: AppBar(
|
||||
title: Text(L10().releaseNotes),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Markdown(
|
||||
selectable: false,
|
||||
data: releaseNotes,
|
||||
onTapLink: (url, href, title) {
|
||||
var link = href ?? "";
|
||||
if (link.isNotEmpty) {
|
||||
openLink(link);
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CreditsWidget extends StatelessWidget {
|
||||
|
||||
const CreditsWidget(this.credits);
|
||||
|
||||
final String credits;
|
||||
|
||||
// Callback function when a link is clicked in the markdown
|
||||
Future<void> openLink(String url) async {
|
||||
|
||||
final link = Uri.parse(url);
|
||||
|
||||
if (await canLaunchUrl(link)) {
|
||||
@ -52,22 +46,21 @@ class CreditsWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build (BuildContext context) {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10().credits),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Markdown(
|
||||
selectable: false,
|
||||
data: credits,
|
||||
onTapLink: (url, href, title) {
|
||||
var link = href ?? "";
|
||||
if (link.isNotEmpty) {
|
||||
openLink(link);
|
||||
}
|
||||
},
|
||||
)
|
||||
);
|
||||
appBar: AppBar(
|
||||
title: Text(L10().credits),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Markdown(
|
||||
selectable: false,
|
||||
data: credits,
|
||||
onTapLink: (url, href, title) {
|
||||
var link = href ?? "";
|
||||
if (link.isNotEmpty) {
|
||||
openLink(link);
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
|
||||
@ -6,15 +5,14 @@ import "package:inventree/l10.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
|
||||
class InvenTreeSalesOrderSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
_InvenTreeSalesOrderSettingsState createState() => _InvenTreeSalesOrderSettingsState();
|
||||
_InvenTreeSalesOrderSettingsState createState() =>
|
||||
_InvenTreeSalesOrderSettingsState();
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreeSalesOrderSettingsState extends State<InvenTreeSalesOrderSettingsWidget> {
|
||||
|
||||
class _InvenTreeSalesOrderSettingsState
|
||||
extends State<InvenTreeSalesOrderSettingsWidget> {
|
||||
_InvenTreeSalesOrderSettingsState();
|
||||
|
||||
bool soEnable = true;
|
||||
@ -29,11 +27,11 @@ class _InvenTreeSalesOrderSettingsState extends State<InvenTreeSalesOrderSetting
|
||||
|
||||
Future<void> loadSettings() async {
|
||||
soEnable = await InvenTreeSettingsManager().getBool(INV_SO_ENABLE, true);
|
||||
soShowCamera = await InvenTreeSettingsManager().getBool(INV_SO_SHOW_CAMERA, true);
|
||||
soShowCamera =
|
||||
await InvenTreeSettingsManager().getBool(INV_SO_SHOW_CAMERA, true);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,39 +43,35 @@ class _InvenTreeSalesOrderSettingsState extends State<InvenTreeSalesOrderSetting
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().salesOrderEnable),
|
||||
subtitle: Text(L10().salesOrderEnableDetail),
|
||||
leading: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: soEnable,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SO_ENABLE, value);
|
||||
setState(() {
|
||||
soEnable = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().salesOrderShowCamera),
|
||||
subtitle: Text(L10().salesOrderShowCameraDetail),
|
||||
leading: Icon(TablerIcons.camera),
|
||||
trailing: Switch(
|
||||
value: soShowCamera,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SO_SHOW_CAMERA, value);
|
||||
setState(() {
|
||||
soShowCamera = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
child: ListView(children: [
|
||||
ListTile(
|
||||
title: Text(L10().salesOrderEnable),
|
||||
subtitle: Text(L10().salesOrderEnableDetail),
|
||||
leading: Icon(TablerIcons.shopping_cart),
|
||||
trailing: Switch(
|
||||
value: soEnable,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SO_ENABLE, value);
|
||||
setState(() {
|
||||
soEnable = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().salesOrderShowCamera),
|
||||
subtitle: Text(L10().salesOrderShowCameraDetail),
|
||||
leading: Icon(TablerIcons.camera),
|
||||
trailing: Switch(
|
||||
value: soShowCamera,
|
||||
onChanged: (bool value) {
|
||||
InvenTreeSettingsManager().setValue(INV_SO_SHOW_CAMERA, value);
|
||||
setState(() {
|
||||
soShowCamera = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,39 +12,35 @@ import "package:inventree/api.dart";
|
||||
import "package:inventree/user_profile.dart";
|
||||
|
||||
class InvenTreeSelectServerWidget extends StatefulWidget {
|
||||
|
||||
@override
|
||||
_InvenTreeSelectServerState createState() => _InvenTreeSelectServerState();
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
|
||||
_InvenTreeSelectServerState() {
|
||||
_reload();
|
||||
}
|
||||
|
||||
final GlobalKey<_InvenTreeSelectServerState> _loginKey = GlobalKey<_InvenTreeSelectServerState>();
|
||||
final GlobalKey<_InvenTreeSelectServerState> _loginKey =
|
||||
GlobalKey<_InvenTreeSelectServerState>();
|
||||
|
||||
List<UserProfile> profiles = [];
|
||||
|
||||
Future <void> _reload() async {
|
||||
|
||||
Future<void> _reload() async {
|
||||
profiles = await UserProfileDBManager().getAllProfiles();
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
/*
|
||||
* Logout the selected profile (delete the stored token)
|
||||
*/
|
||||
Future<void> _logoutProfile(BuildContext context, {UserProfile? userProfile}) async {
|
||||
|
||||
Future<void> _logoutProfile(BuildContext context,
|
||||
{UserProfile? userProfile}) async {
|
||||
if (userProfile != null) {
|
||||
userProfile.token = "";
|
||||
await UserProfileDBManager().updateProfile(userProfile);
|
||||
@ -54,26 +50,23 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
|
||||
InvenTreeAPI().disconnectFromServer();
|
||||
_reload();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Edit the selected profile
|
||||
*/
|
||||
void _editProfile(BuildContext context, {UserProfile? userProfile, bool createNew = false}) {
|
||||
|
||||
void _editProfile(BuildContext context,
|
||||
{UserProfile? userProfile, bool createNew = false}) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProfileEditWidget(userProfile)
|
||||
)
|
||||
).then((context) {
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProfileEditWidget(userProfile)))
|
||||
.then((context) {
|
||||
_reload();
|
||||
});
|
||||
}
|
||||
|
||||
Future <void> _selectProfile(BuildContext context, UserProfile profile) async {
|
||||
|
||||
Future<void> _selectProfile(BuildContext context, UserProfile profile) async {
|
||||
// Disconnect InvenTree
|
||||
InvenTreeAPI().disconnectFromServer();
|
||||
|
||||
@ -94,9 +87,11 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
// First check if the profile has an associate token
|
||||
if (!prf.hasToken) {
|
||||
// Redirect user to login screen
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (context) => InvenTreeLoginWidget(profile))
|
||||
).then((value) async {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => InvenTreeLoginWidget(profile)))
|
||||
.then((value) async {
|
||||
_reload();
|
||||
// Reload profile
|
||||
prf = await UserProfileDBManager().getProfileByKey(key);
|
||||
@ -125,8 +120,7 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
_reload();
|
||||
}
|
||||
|
||||
Future <void> _deleteProfile(UserProfile profile) async {
|
||||
|
||||
Future<void> _deleteProfile(UserProfile profile) async {
|
||||
await UserProfileDBManager().deleteProfile(profile);
|
||||
|
||||
if (!mounted) {
|
||||
@ -135,13 +129,13 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
|
||||
_reload();
|
||||
|
||||
if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? "")) {
|
||||
if (InvenTreeAPI().isConnected() &&
|
||||
profile.key == (InvenTreeAPI().profile?.key ?? "")) {
|
||||
InvenTreeAPI().disconnectFromServer();
|
||||
}
|
||||
}
|
||||
|
||||
Widget? _getProfileIcon(UserProfile profile) {
|
||||
|
||||
// Not selected? No icon for you!
|
||||
if (!profile.selected) return null;
|
||||
|
||||
@ -152,10 +146,7 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
|
||||
// Reflect the connection status of the server
|
||||
if (InvenTreeAPI().isConnected()) {
|
||||
return Icon(
|
||||
TablerIcons.circle_check,
|
||||
color: COLOR_SUCCESS
|
||||
);
|
||||
return Icon(TablerIcons.circle_check, color: COLOR_SUCCESS);
|
||||
} else if (InvenTreeAPI().isConnecting()) {
|
||||
return Spinner(
|
||||
icon: TablerIcons.loader_2,
|
||||
@ -171,7 +162,6 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
List<Widget> children = [];
|
||||
|
||||
if (profiles.isNotEmpty) {
|
||||
@ -182,84 +172,76 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
title: Text(
|
||||
profile.name,
|
||||
),
|
||||
tileColor: profile.selected ? Theme.of(context).secondaryHeaderColor : null,
|
||||
tileColor:
|
||||
profile.selected ? Theme.of(context).secondaryHeaderColor : null,
|
||||
subtitle: Text("${profile.server}"),
|
||||
leading: profile.hasToken ? Icon(TablerIcons.user_check, color: COLOR_SUCCESS) : Icon(TablerIcons.user_cancel, color: COLOR_WARNING),
|
||||
leading: profile.hasToken
|
||||
? Icon(TablerIcons.user_check, color: COLOR_SUCCESS)
|
||||
: Icon(TablerIcons.user_cancel, color: COLOR_WARNING),
|
||||
trailing: _getProfileIcon(profile),
|
||||
onTap: () {
|
||||
_selectProfile(context, profile);
|
||||
},
|
||||
onLongPress: () {
|
||||
OneContext().showDialog(
|
||||
builder: (BuildContext context) {
|
||||
return SimpleDialog(
|
||||
title: Text(profile.name),
|
||||
children: <Widget>[
|
||||
Divider(),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_selectProfile(context, profile);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileConnect),
|
||||
leading: Icon(TablerIcons.server),
|
||||
)
|
||||
),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_editProfile(context, userProfile: profile);
|
||||
},
|
||||
child: ListTile(
|
||||
OneContext().showDialog(builder: (BuildContext context) {
|
||||
return SimpleDialog(
|
||||
title: Text(profile.name),
|
||||
children: <Widget>[
|
||||
Divider(),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_selectProfile(context, profile);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileConnect),
|
||||
leading: Icon(TablerIcons.server),
|
||||
)),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_editProfile(context, userProfile: profile);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileEdit),
|
||||
leading: Icon(TablerIcons.edit)
|
||||
)
|
||||
),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_logoutProfile(context, userProfile: profile);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileLogout),
|
||||
leading: Icon(TablerIcons.logout),
|
||||
)
|
||||
),
|
||||
Divider(),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
// Navigator.of(context, rootNavigator: true).pop();
|
||||
confirmationDialog(
|
||||
L10().delete,
|
||||
L10().profileDelete + "?",
|
||||
leading: Icon(TablerIcons.edit))),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
_logoutProfile(context, userProfile: profile);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileLogout),
|
||||
leading: Icon(TablerIcons.logout),
|
||||
)),
|
||||
Divider(),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
// Navigator.of(context, rootNavigator: true).pop();
|
||||
confirmationDialog(
|
||||
L10().delete, L10().profileDelete + "?",
|
||||
color: Colors.red,
|
||||
icon: TablerIcons.trash,
|
||||
onAccept: () {
|
||||
_deleteProfile(profile);
|
||||
}
|
||||
);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileDelete, style: TextStyle(color: Colors.red)),
|
||||
leading: Icon(TablerIcons.trash, color: Colors.red),
|
||||
)
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
icon: TablerIcons.trash, onAccept: () {
|
||||
_deleteProfile(profile);
|
||||
});
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(L10().profileDelete,
|
||||
style: TextStyle(color: Colors.red)),
|
||||
leading: Icon(TablerIcons.trash, color: Colors.red),
|
||||
))
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// No profile available!
|
||||
children.add(
|
||||
ListTile(
|
||||
title: Text(L10().profileNone),
|
||||
)
|
||||
);
|
||||
children.add(ListTile(
|
||||
title: Text(L10().profileNone),
|
||||
));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
@ -277,23 +259,18 @@ class _InvenTreeSelectServerState extends State<InvenTreeSelectServerWidget> {
|
||||
],
|
||||
),
|
||||
body: Container(
|
||||
child: ListView(
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: children
|
||||
).toList(),
|
||||
)
|
||||
),
|
||||
child: ListView(
|
||||
children:
|
||||
ListTile.divideTiles(context: context, tiles: children).toList(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Widget for editing server details
|
||||
*/
|
||||
class ProfileEditWidget extends StatefulWidget {
|
||||
|
||||
const ProfileEditWidget(this.profile) : super();
|
||||
|
||||
final UserProfile? profile;
|
||||
@ -303,7 +280,6 @@ class ProfileEditWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ProfileEditState extends State<ProfileEditWidget> {
|
||||
|
||||
_ProfileEditState() : super();
|
||||
|
||||
final formKey = GlobalKey<FormState>();
|
||||
@ -314,120 +290,117 @@ class _ProfileEditState extends State<ProfileEditWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
title: Text(widget.profile == null ? L10().profileAdd : L10().profileEdit),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(TablerIcons.circle_check),
|
||||
onPressed: () async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
formKey.currentState!.save();
|
||||
appBar: AppBar(
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
title: Text(
|
||||
widget.profile == null ? L10().profileAdd : L10().profileEdit),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(TablerIcons.circle_check),
|
||||
onPressed: () async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
formKey.currentState!.save();
|
||||
|
||||
UserProfile? prf = widget.profile;
|
||||
UserProfile? prf = widget.profile;
|
||||
|
||||
if (prf == null) {
|
||||
UserProfile profile = UserProfile(
|
||||
name: name,
|
||||
server: server,
|
||||
);
|
||||
if (prf == null) {
|
||||
UserProfile profile = UserProfile(
|
||||
name: name,
|
||||
server: server,
|
||||
);
|
||||
|
||||
await UserProfileDBManager().addProfile(profile);
|
||||
} else {
|
||||
|
||||
prf.name = name;
|
||||
prf.server = server;
|
||||
|
||||
await UserProfileDBManager().updateProfile(prf);
|
||||
}
|
||||
|
||||
// Close the window
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
)
|
||||
]
|
||||
),
|
||||
body: Form(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().profileName,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
initialValue: widget.profile?.name ?? "",
|
||||
maxLines: 1,
|
||||
keyboardType: TextInputType.text,
|
||||
onSaved: (value) {
|
||||
name = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().valueCannotBeEmpty;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().server,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: "http[s]://<server>:<port>",
|
||||
),
|
||||
initialValue: widget.profile?.server ?? "",
|
||||
keyboardType: TextInputType.url,
|
||||
onSaved: (value) {
|
||||
server = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().serverEmpty;
|
||||
}
|
||||
|
||||
value = value.trim();
|
||||
|
||||
// Spaces are bad
|
||||
if (value.contains(" ")) {
|
||||
return L10().invalidHost;
|
||||
}
|
||||
|
||||
if (!value.startsWith("http:") && !value.startsWith("https:")) {
|
||||
// return L10().serverStart;
|
||||
}
|
||||
|
||||
Uri? _uri = Uri.tryParse(value);
|
||||
|
||||
if (_uri == null || _uri.host.isEmpty) {
|
||||
return L10().invalidHost;
|
||||
} else {
|
||||
Uri uri = Uri.parse(value);
|
||||
|
||||
if (uri.hasScheme) {
|
||||
if (!["http", "https"].contains(uri.scheme.toLowerCase())) {
|
||||
return L10().serverStart;
|
||||
}
|
||||
await UserProfileDBManager().addProfile(profile);
|
||||
} else {
|
||||
return L10().invalidHost;
|
||||
prf.name = name;
|
||||
prf.server = server;
|
||||
|
||||
await UserProfileDBManager().updateProfile(prf);
|
||||
}
|
||||
|
||||
// Close the window
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
// Everything is OK
|
||||
return null;
|
||||
},
|
||||
),
|
||||
]
|
||||
),
|
||||
padding: EdgeInsets.all(16),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
)
|
||||
]),
|
||||
body: Form(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().profileName,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
initialValue: widget.profile?.name ?? "",
|
||||
maxLines: 1,
|
||||
keyboardType: TextInputType.text,
|
||||
onSaved: (value) {
|
||||
name = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().valueCannotBeEmpty;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: L10().server,
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
hintText: "http[s]://<server>:<port>",
|
||||
),
|
||||
initialValue: widget.profile?.server ?? "",
|
||||
keyboardType: TextInputType.url,
|
||||
onSaved: (value) {
|
||||
server = value?.trim() ?? "";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return L10().serverEmpty;
|
||||
}
|
||||
|
||||
value = value.trim();
|
||||
|
||||
// Spaces are bad
|
||||
if (value.contains(" ")) {
|
||||
return L10().invalidHost;
|
||||
}
|
||||
|
||||
if (!value.startsWith("http:") &&
|
||||
!value.startsWith("https:")) {
|
||||
// return L10().serverStart;
|
||||
}
|
||||
|
||||
Uri? _uri = Uri.tryParse(value);
|
||||
|
||||
if (_uri == null || _uri.host.isEmpty) {
|
||||
return L10().invalidHost;
|
||||
} else {
|
||||
Uri uri = Uri.parse(value);
|
||||
|
||||
if (uri.hasScheme) {
|
||||
if (!["http", "https"]
|
||||
.contains(uri.scheme.toLowerCase())) {
|
||||
return L10().serverStart;
|
||||
}
|
||||
} else {
|
||||
return L10().invalidHost;
|
||||
}
|
||||
}
|
||||
|
||||
// Everything is OK
|
||||
return null;
|
||||
},
|
||||
),
|
||||
]),
|
||||
padding: EdgeInsets.all(16),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,11 @@ import "package:inventree/settings/sales_order_settings.dart";
|
||||
|
||||
// InvenTree settings view
|
||||
class InvenTreeSettingsWidget extends StatefulWidget {
|
||||
|
||||
@override
|
||||
_InvenTreeSettingsState createState() => _InvenTreeSettingsState();
|
||||
|
||||
}
|
||||
|
||||
|
||||
class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
|
||||
|
||||
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
/*
|
||||
@ -40,80 +36,96 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
title: Text(L10().settings),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(L10().server),
|
||||
subtitle: Text(L10().configureServer),
|
||||
leading: Icon(TablerIcons.server, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeSelectServerWidget()));
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().appSettings),
|
||||
subtitle: Text(L10().appSettingsDetails),
|
||||
leading: Icon(TablerIcons.settings, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeAppSettingsWidget()));
|
||||
}
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().homeScreen),
|
||||
subtitle: Text(L10().homeScreenSettings),
|
||||
leading: Icon(TablerIcons.home, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreenSettingsWidget()));
|
||||
}
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().barcodes),
|
||||
subtitle: Text(L10().barcodeSettings),
|
||||
leading: Icon(TablerIcons.barcode, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeBarcodeSettingsWidget()));
|
||||
}
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().part),
|
||||
subtitle: Text(L10().partSettings),
|
||||
leading: Icon(TablerIcons.box, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreePartSettingsWidget()));
|
||||
}
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrder),
|
||||
subtitle: Text(L10().purchaseOrderSettings),
|
||||
leading: Icon(TablerIcons.shopping_cart, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreePurchaseOrderSettingsWidget()));
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().salesOrder),
|
||||
subtitle: Text(L10().salesOrderSettings),
|
||||
leading: Icon(TablerIcons.truck, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeSalesOrderSettingsWidget()));
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().about),
|
||||
leading: Icon(TablerIcons.info_circle, color: COLOR_ACTION),
|
||||
onTap: _about,
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
title: Text(L10().settings),
|
||||
backgroundColor: COLOR_APP_BAR,
|
||||
),
|
||||
body: Center(
|
||||
child: ListView(children: [
|
||||
ListTile(
|
||||
title: Text(L10().server),
|
||||
subtitle: Text(L10().configureServer),
|
||||
leading: Icon(TablerIcons.server, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => InvenTreeSelectServerWidget()));
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().appSettings),
|
||||
subtitle: Text(L10().appSettingsDetails),
|
||||
leading: Icon(TablerIcons.settings, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => InvenTreeAppSettingsWidget()));
|
||||
}),
|
||||
ListTile(
|
||||
title: Text(L10().homeScreen),
|
||||
subtitle: Text(L10().homeScreenSettings),
|
||||
leading: Icon(TablerIcons.home, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => HomeScreenSettingsWidget()));
|
||||
}),
|
||||
ListTile(
|
||||
title: Text(L10().barcodes),
|
||||
subtitle: Text(L10().barcodeSettings),
|
||||
leading: Icon(TablerIcons.barcode, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
InvenTreeBarcodeSettingsWidget()));
|
||||
}),
|
||||
ListTile(
|
||||
title: Text(L10().part),
|
||||
subtitle: Text(L10().partSettings),
|
||||
leading: Icon(TablerIcons.box, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => InvenTreePartSettingsWidget()));
|
||||
}),
|
||||
ListTile(
|
||||
title: Text(L10().purchaseOrder),
|
||||
subtitle: Text(L10().purchaseOrderSettings),
|
||||
leading: Icon(TablerIcons.shopping_cart, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
InvenTreePurchaseOrderSettingsWidget()));
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10().salesOrder),
|
||||
subtitle: Text(L10().salesOrderSettings),
|
||||
leading: Icon(TablerIcons.truck, color: COLOR_ACTION),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
InvenTreeSalesOrderSettingsWidget()));
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(L10().about),
|
||||
leading: Icon(TablerIcons.info_circle, color: COLOR_ACTION),
|
||||
onTap: _about,
|
||||
)
|
||||
])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user