2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-07-06 22:00:43 +00:00

Link icons (#677)

* Add LinkIcon component

* Visual UI updates

- Refactor some components
- Clearer text display
- Add obvious chevron icon when a "tile" will take the user somewhere else

* dart format

* Adjust release notes

* Add visual separator

* Cleanup unused imports
This commit is contained in:
Oliver
2025-07-04 21:16:04 +10:00
committed by GitHub
parent c30f1a19d1
commit 2adf8e3430
28 changed files with 261 additions and 195 deletions

View File

@ -10,6 +10,7 @@ import "package:inventree/l10.dart";
import "package:inventree/inventree/stock.dart";
import "package:inventree/preferences.dart";
import "package:inventree/widget/link_icon.dart";
import "package:inventree/widget/stock/location_list.dart";
import "package:inventree/widget/progress.dart";
@ -341,6 +342,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
title: Text(L10().parentLocation),
subtitle: Text("${location!.parentPathString}"),
leading: Icon(TablerIcons.arrow_move_up, color: COLOR_ACTION),
trailing: LinkIcon(),
onTap: () async {
int parentId = location?.parentId ?? -1;

View File

@ -2,6 +2,7 @@ import "package:flutter/material.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/link_icon.dart";
import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart";
@ -86,7 +87,7 @@ class _PaginatedStockLocationListState
return ListTile(
title: Text(location.name),
subtitle: Text(location.pathstring),
trailing: Text("${location.itemcount}"),
trailing: LargeText("${location.itemcount}", size: 14),
leading: location.customIcon == null ? null : Icon(location.customIcon),
onTap: () {
location.goToDetailPage(context);

View File

@ -18,9 +18,9 @@ import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/stock.dart";
import "package:inventree/inventree/part.dart";
import "package:inventree/widget/company/supplier_part_detail.dart";
import "package:inventree/widget/dialogs.dart";
import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/link_icon.dart";
import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart";
@ -490,14 +490,11 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
Widget? trailing;
if (!widget.item.isInStock) {
trailing = Text(L10().unavailable, style: TextStyle(color: COLOR_DANGER));
trailing = LargeText(L10().unavailable, color: COLOR_DANGER);
} else if (!widget.item.isSerialized()) {
trailing = Text(
trailing = LargeText(
widget.item.quantityString(),
style: TextStyle(
fontSize: 20,
color: api.StockStatus.color(widget.item.status),
),
color: api.StockStatus.color(widget.item.status),
);
}
@ -518,7 +515,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
}
}
},
//trailing: Text(item.serialOrQuantityDisplay()),
//trailing: LargeText(item.serialOrQuantityDisplay()),
),
);
}
@ -546,6 +543,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
title: Text(L10().stockLocation),
subtitle: Text("${widget.item.locationPathString}"),
leading: Icon(TablerIcons.location, color: COLOR_ACTION),
trailing: LinkIcon(),
onTap: () async {
if (widget.item.locationId > 0) {
showLoadingOverlay();
@ -587,7 +585,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
? Text(L10().quantityAvailable)
: Text(L10().quantity),
leading: Icon(TablerIcons.packages),
trailing: Text("${widget.item.quantityString()}"),
trailing: LargeText("${widget.item.quantityString()}"),
),
);
}
@ -613,9 +611,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().status),
leading: Icon(TablerIcons.help_circle),
trailing: Text(
trailing: LargeText(
api.StockStatus.label(widget.item.status),
style: TextStyle(color: api.StockStatus.color(widget.item.status)),
color: api.StockStatus.color(widget.item.status),
),
),
);
@ -627,10 +625,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
title: Text(L10().supplierPart),
subtitle: Text(widget.item.supplierSKU),
leading: Icon(TablerIcons.building, color: COLOR_ACTION),
trailing: InvenTreeAPI().getThumbnail(
widget.item.supplierImage,
hideIfNull: true,
),
trailing: LinkIcon(),
onTap: () async {
showLoadingOverlay();
var sp = await InvenTreeSupplierPart().get(
@ -638,12 +633,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
);
hideLoadingOverlay();
if (sp is InvenTreeSupplierPart) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SupplierPartDetailWidget(sp),
),
);
sp.goToDetailPage(context);
}
},
),
@ -667,9 +657,11 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
tiles.add(
ListTile(
title: Text(L10().salesOrder),
subtitle: Text(salesOrder?.description ?? ""),
subtitle: Text(
salesOrder?.reference ?? salesOrder?.description ?? "",
),
leading: Icon(TablerIcons.truck_delivery, color: COLOR_ACTION),
trailing: Text(salesOrder?.reference ?? ""),
trailing: LinkIcon(),
onTap: () {
salesOrder?.goToDetailPage(context);
},
@ -681,9 +673,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
tiles.add(
ListTile(
title: Text(L10().customer),
subtitle: Text(customer?.description ?? ""),
subtitle: Text("${customer?.name} - ${customer?.description}"),
leading: Icon(TablerIcons.building_store, color: COLOR_ACTION),
trailing: Text(customer?.name ?? ""),
trailing: LinkIcon(),
onTap: () {
customer?.goToDetailPage(context);
},
@ -741,7 +733,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
tiles.add(
ListTile(
title: Text(L10().lastUpdated),
subtitle: Text(widget.item.updatedDateString),
trailing: LargeText(widget.item.updatedDateString),
leading: Icon(TablerIcons.calendar),
),
);
@ -775,7 +767,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().testResults),
leading: Icon(TablerIcons.list_check, color: COLOR_ACTION),
trailing: Text("${widget.item.testResultCount}"),
trailing: LinkIcon(text: "${widget.item.testResultCount}"),
onTap: () {
Navigator.push(
context,
@ -795,7 +787,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().purchasePrice),
leading: Icon(TablerIcons.currency_dollar),
trailing: Text(
trailing: LargeText(
renderCurrency(
widget.item.purchasePrice,
widget.item.purchasePriceCurrency,
@ -812,7 +804,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().history),
leading: Icon(TablerIcons.history, color: COLOR_ACTION),
trailing: Text("${widget.item.trackingItemCount}"),
trailing: LinkIcon(text: "${widget.item.trackingItemCount}"),
onTap: () {
Navigator.push(
context,
@ -832,6 +824,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().notes),
leading: Icon(TablerIcons.note, color: COLOR_ACTION),
trailing: LinkIcon(),
onTap: () {
Navigator.push(
context,
@ -845,7 +838,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
ListTile(
title: Text(L10().attachments),
leading: Icon(TablerIcons.file, color: COLOR_ACTION),
trailing: attachmentCount > 0 ? Text(attachmentCount.toString()) : null,
trailing: LinkIcon(
text: attachmentCount > 0 ? attachmentCount.toString() : null,
),
onTap: () {
Navigator.push(
context,

View File

@ -2,6 +2,7 @@ import "package:flutter/material.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/link_icon.dart";
import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/l10.dart";
@ -130,16 +131,10 @@ class _PaginatedStockItemListState
title: Text("${item.partName}"),
subtitle: Text(item.locationPathString),
leading: InvenTreeAPI().getThumbnail(item.partThumbnail),
trailing: SizedBox(
width: 48,
child: Text(
"${item.displayQuantity}",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: InvenTreeAPI().StockStatus.color(item.status),
),
),
trailing: LargeText(
item.displayQuantity,
size: 14,
color: InvenTreeAPI().StockStatus.color(item.status),
),
onTap: () {
item.goToDetailPage(context);