mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Add progress indicators to a bunch o' stuff
This commit is contained in:
parent
dba45c7600
commit
b1b85a33f8
@ -2,6 +2,7 @@
|
||||
import 'package:InvenTree/api.dart';
|
||||
import 'package:InvenTree/inventree/part.dart';
|
||||
import 'package:InvenTree/preferences.dart';
|
||||
import 'package:InvenTree/widget/progress.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
@ -155,13 +156,16 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text("${category.name}"),
|
||||
title: Text("${category.name}",
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
),
|
||||
subtitle: Text("${category.description}"),
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).parentCategory),
|
||||
subtitle: Text("${category.parentpathstring}"),
|
||||
leading: FaIcon(FontAwesomeIcons.sitemap),
|
||||
leading: FaIcon(FontAwesomeIcons.levelUpAlt),
|
||||
onTap: () {
|
||||
if (category.parentId < 0) {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => CategoryDisplayWidget(null)));
|
||||
@ -204,37 +208,64 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
}
|
||||
|
||||
List<Widget> detailTiles() {
|
||||
return <Widget>[
|
||||
List<Widget> tiles = <Widget>[
|
||||
getCategoryDescriptionCard(),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(
|
||||
I18N.of(context).subcategories,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
)
|
||||
),
|
||||
SubcategoryList(_subcategories),
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
} else if (_subcategories.length == 0) {
|
||||
tiles.add(ListTile(
|
||||
title: Text("No Subcategories"),
|
||||
subtitle: Text("No subcategories available")
|
||||
));
|
||||
} else {
|
||||
tiles.add(SubcategoryList(_subcategories));
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
List<Widget> partTiles() {
|
||||
return <Widget>[
|
||||
List<Widget> tiles = <Widget>[
|
||||
getCategoryDescriptionCard(),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(
|
||||
I18N.of(context).parts,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
)
|
||||
),
|
||||
PartList(_parts)
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
} else if (_parts.length == 0) {
|
||||
tiles.add(ListTile(
|
||||
title: Text("No Parts"),
|
||||
subtitle: Text("No parts available in this category")
|
||||
));
|
||||
} else {
|
||||
tiles.add(PartList(_parts));
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
List<Widget> actionTiles() {
|
||||
|
||||
List<Widget> tiles = [
|
||||
getCategoryDescriptionCard()
|
||||
getCategoryDescriptionCard(),
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).actions,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
)
|
||||
)
|
||||
];
|
||||
|
||||
// TODO - Actions!
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:InvenTree/api.dart';
|
||||
import 'package:InvenTree/inventree/stock.dart';
|
||||
import 'package:InvenTree/preferences.dart';
|
||||
import 'package:InvenTree/widget/progress.dart';
|
||||
|
||||
import 'package:InvenTree/widget/refreshable_state.dart';
|
||||
import 'package:InvenTree/widget/fields.dart';
|
||||
@ -235,16 +236,25 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
||||
List<Widget> detailTiles() {
|
||||
List<Widget> tiles = [
|
||||
locationDescriptionCard(),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(
|
||||
I18N.of(context).sublocations,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
),
|
||||
),
|
||||
SublocationList(_sublocations)
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
} else if (_sublocations.length > 0) {
|
||||
tiles.add(SublocationList(_sublocations));
|
||||
} else {
|
||||
tiles.add(ListTile(
|
||||
title: Text("No Sublocations"),
|
||||
subtitle: Text("No sublocations available")
|
||||
));
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
@ -252,16 +262,25 @@ List<Widget> detailTiles() {
|
||||
List<Widget> stockTiles() {
|
||||
List<Widget> tiles = [
|
||||
locationDescriptionCard(),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text(
|
||||
I18N.of(context).stockItems,
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
)
|
||||
),
|
||||
StockList(_items),
|
||||
)
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
} else if (_items.length > 0) {
|
||||
tiles.add(StockList(_items));
|
||||
} else {
|
||||
tiles.add(ListTile(
|
||||
title: Text("No Stock Items"),
|
||||
subtitle: Text("No stock items available in this location")
|
||||
));
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:InvenTree/widget/progress.dart';
|
||||
import 'package:InvenTree/widget/snacks.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -172,6 +173,11 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
headerTile()
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
return tiles;
|
||||
}
|
||||
|
||||
// Category information
|
||||
if (part.categoryName != null && part.categoryName.isNotEmpty) {
|
||||
tiles.add(
|
||||
|
13
lib/widget/progress.dart
Normal file
13
lib/widget/progress.dart
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Construct a circular progress indicator
|
||||
*/
|
||||
Widget progressIndicator() {
|
||||
|
||||
return Center(
|
||||
child: CircularProgressIndicator()
|
||||
);
|
||||
}
|
@ -16,6 +16,11 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
|
||||
// Current tab index (used for widgets which display bottom tabs)
|
||||
int tabIndex = 0;
|
||||
|
||||
// Bool indicator
|
||||
bool loading = false;
|
||||
|
||||
bool get loaded => !loading;
|
||||
|
||||
// Update current tab selection
|
||||
void onTabSelectionChanged(int index) {
|
||||
setState(() {
|
||||
@ -45,8 +50,16 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
|
||||
}
|
||||
|
||||
Future<void> refresh() async {
|
||||
|
||||
setState(() {
|
||||
loading = true;
|
||||
});
|
||||
|
||||
await request(context);
|
||||
setState(() {});
|
||||
|
||||
setState(() {
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Function to construct an appbar (override if needed)
|
||||
|
@ -8,6 +8,7 @@ import 'package:InvenTree/widget/dialogs.dart';
|
||||
import 'package:InvenTree/widget/fields.dart';
|
||||
import 'package:InvenTree/widget/location_display.dart';
|
||||
import 'package:InvenTree/widget/part_detail.dart';
|
||||
import 'package:InvenTree/widget/progress.dart';
|
||||
import 'package:InvenTree/widget/refreshable_state.dart';
|
||||
import 'package:InvenTree/widget/snacks.dart';
|
||||
import 'package:InvenTree/widget/stock_item_test_results.dart';
|
||||
@ -314,6 +315,15 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
color: item.statusColor
|
||||
)
|
||||
),
|
||||
onTap: () {
|
||||
if (item.partId > 0) {
|
||||
InvenTreePart().get(context, item.partId).then((var part) {
|
||||
if (part is InvenTreePart) {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
//trailing: Text(item.serialOrQuantityDisplay()),
|
||||
)
|
||||
);
|
||||
@ -329,22 +339,29 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
// Image / name / description
|
||||
tiles.add(headerTile());
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).part),
|
||||
subtitle: Text("${item.partName}"),
|
||||
leading: FaIcon(FontAwesomeIcons.shapes),
|
||||
onTap: () {
|
||||
if (item.partId > 0) {
|
||||
InvenTreePart().get(context, item.partId).then((var part) {
|
||||
if (part is InvenTreePart) {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
);
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
return tiles;
|
||||
}
|
||||
|
||||
// Quantity information
|
||||
if (item.isSerialized()) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).serialNumber),
|
||||
leading: FaIcon(FontAwesomeIcons.hashtag),
|
||||
trailing: Text("${item.serialNumber}"),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).quantity),
|
||||
leading: FaIcon(FontAwesomeIcons.cubes),
|
||||
trailing: Text("${item.quantityString}"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Location information
|
||||
if ((item.locationId > 0) && (item.locationName != null) && (item.locationName.isNotEmpty)) {
|
||||
@ -373,24 +390,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
// Quantity information
|
||||
if (item.isSerialized()) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).serialNumber),
|
||||
leading: FaIcon(FontAwesomeIcons.hashtag),
|
||||
trailing: Text("${item.serialNumber}"),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).quantity),
|
||||
leading: FaIcon(FontAwesomeIcons.cubes),
|
||||
trailing: Text("${item.quantityString}"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Supplier part?
|
||||
// TODO: Display supplier part info page?
|
||||
|
@ -4,6 +4,7 @@ import 'package:InvenTree/inventree/model.dart';
|
||||
import 'package:InvenTree/api.dart';
|
||||
import 'package:InvenTree/widget/dialogs.dart';
|
||||
import 'package:InvenTree/widget/fields.dart';
|
||||
import 'package:InvenTree/widget/progress.dart';
|
||||
import 'package:InvenTree/widget/snacks.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
@ -166,8 +167,40 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
List<Widget> resultsList() {
|
||||
List<Widget> tiles = [];
|
||||
|
||||
tiles.add(
|
||||
Card(
|
||||
child: ListTile(
|
||||
title: Text(item.partName),
|
||||
subtitle: Text(item.partDescription),
|
||||
leading: InvenTreeAPI().getImage(item.partImage),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text("Test Results",
|
||||
style: TextStyle(fontWeight: FontWeight.bold)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
tiles.add(progressIndicator());
|
||||
return tiles;
|
||||
}
|
||||
|
||||
var results = getTestResults();
|
||||
|
||||
if (results.length == 0) {
|
||||
tiles.add(ListTile(
|
||||
title: Text("No Results"),
|
||||
subtitle: Text("No test results available"),
|
||||
));
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
for (var item in results) {
|
||||
|
||||
bool _required = false;
|
||||
@ -231,6 +264,7 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
|
||||
@override
|
||||
Widget getBody(BuildContext context) {
|
||||
|
||||
return ListView(
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
@ -239,6 +273,7 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
List<SpeedDialChild> actionButtons() {
|
||||
|
||||
var buttons = List<SpeedDialChild>();
|
||||
@ -253,14 +288,15 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
|
||||
return buttons;
|
||||
}
|
||||
*/
|
||||
|
||||
@override
|
||||
Widget getFab(BuildContext context) {
|
||||
return SpeedDial(
|
||||
visible: true,
|
||||
animatedIcon: AnimatedIcons.menu_close,
|
||||
heroTag: 'stock-item-results-tab',
|
||||
children: actionButtons(),
|
||||
return FloatingActionButton(
|
||||
child: Icon(FontAwesomeIcons.plus),
|
||||
onPressed: () {
|
||||
addTestResult();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
42
pubspec.lock
42
pubspec.lock
@ -434,48 +434,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.4"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.12+4"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.2+4"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+11"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+7"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.2+3"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
Loading…
x
Reference in New Issue
Block a user