From 82001409764c79c73025a99adb485cee61960275 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@gmail.com>
Date: Sat, 12 Aug 2023 20:41:11 +1000
Subject: [PATCH] Label fix (#411)

* Cleanup label printing options

- Improve calls to setState()
- Should fix potential race conditions

* Use name if description not available

* Code simplification

* Fetch plugins even if the server reports "plugins enabled"

- Builtin plugins are still a thing!

* Use name *and* description to display label
---
 lib/api.dart                     |  6 +-----
 lib/labels.dart                  | 12 +++++++++---
 lib/widget/location_display.dart | 16 ++++++++--------
 lib/widget/part_detail.dart      | 17 +++++++++++------
 lib/widget/stock_detail.dart     | 19 +++++++++++--------
 5 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/lib/api.dart b/lib/api.dart
index 26cd5b90..fa740e06 100644
--- a/lib/api.dart
+++ b/lib/api.dart
@@ -645,11 +645,7 @@ class InvenTreeAPI {
   // Request plugin information from the server
   Future<bool> getPluginInformation() async {
 
-    // The server does not support plugins, or they are not enabled
-    if (!pluginsEnabled()) {
-      _plugins.clear();
-      return true;
-    }
+    _plugins.clear();
 
     debug("API: getPluginInformation()");
 
diff --git a/lib/labels.dart b/lib/labels.dart
index ca4f8ad2..c43ad30d 100644
--- a/lib/labels.dart
+++ b/lib/labels.dart
@@ -66,12 +66,18 @@ Future<void> selectAndPrintLabel(
 
   // Construct list of available label templates
   for (var label in labels) {
-    String display_name = (label["description"] ?? "").toString();
+    String name = (label["name"] ?? "").toString();
+    String description = (label["description"] ?? "").toString();
+
+    if (description.isNotEmpty) {
+      name += " - ${description}";
+    }
+
     int pk = (label["pk"] ?? -1) as int;
 
-    if (display_name.isNotEmpty && pk > 0) {
+    if (name.isNotEmpty && pk > 0) {
       label_options.add({
-        "display_name": display_name,
+        "display_name": name,
         "value": pk,
       });
     }
diff --git a/lib/widget/location_display.dart b/lib/widget/location_display.dart
index a26ddc98..0ca1c5dd 100644
--- a/lib/widget/location_display.dart
+++ b/lib/widget/location_display.dart
@@ -40,8 +40,6 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
 
   final InvenTreeStockLocation? location;
 
-  bool allowLabelPrinting = true;
-
   List<Map<String, dynamic>> labels = [];
 
   @override
@@ -169,7 +167,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
       );
     }
 
-    if (widget.location != null && allowLabelPrinting && labels.isNotEmpty) {
+    if (widget.location != null && labels.isNotEmpty) {
       actions.add(
           SpeedDialChild(
               child: FaIcon(FontAwesomeIcons.print),
@@ -225,21 +223,23 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
       }
     }
 
-    allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
-    allowLabelPrinting &= api.getPlugins(mixin: "labels").isNotEmpty;
+    List<Map<String, dynamic>> _labels = [];
+    bool allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
+    allowLabelPrinting &= api.supportsMixin("labels");
 
     if (allowLabelPrinting) {
-      labels.clear();
 
       if (widget.location != null) {
-        labels = await getLabelTemplates("location", {
+        _labels = await getLabelTemplates("location", {
           "location": widget.location!.pk.toString()
         });
       }
     }
 
     if (mounted) {
-      setState(() {});
+      setState(() {
+        labels = _labels;
+      });
     }
   }
 
diff --git a/lib/widget/part_detail.dart b/lib/widget/part_detail.dart
index d8a81b9c..1079fb18 100644
--- a/lib/widget/part_detail.dart
+++ b/lib/widget/part_detail.dart
@@ -56,7 +56,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
 
   bool showParameters = false;
   bool showBom = false;
-  bool allowLabelPrinting = true;
 
   int attachmentCount = 0;
   int bomCount = 0;
@@ -121,7 +120,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
       );
     }
 
-    if (allowLabelPrinting && labels.isNotEmpty) {
+    if (labels.isNotEmpty) {
       actions.add(
         SpeedDialChild(
           child: FaIcon(FontAwesomeIcons.print),
@@ -244,15 +243,21 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
       }
     });
 
-    allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
-    allowLabelPrinting &= api.getPlugins(mixin: "labels").isNotEmpty;
+    List<Map<String, dynamic>> _labels = [];
+    bool allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
+    allowLabelPrinting &= api.supportsMixin("labels");
 
     if (allowLabelPrinting) {
-      labels.clear();
-      labels = await getLabelTemplates("part", {
+      _labels = await getLabelTemplates("part", {
         "part": widget.part.pk.toString(),
       });
     }
+
+    if (mounted) {
+      setState(() {
+        labels = _labels;
+      });
+    }
   }
 
   void _editPartDialog(BuildContext context) {
diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart
index 9e2f517b..decf402a 100644
--- a/lib/widget/stock_detail.dart
+++ b/lib/widget/stock_detail.dart
@@ -128,7 +128,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
       );
     }
 
-    if (allowLabelPrinting && labels.isNotEmpty) {
+    if (labels.isNotEmpty) {
       actions.add(
         SpeedDialChild(
           child: FaIcon(FontAwesomeIcons.print),
@@ -204,8 +204,6 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
 
   int attachmentCount = 0;
 
-  bool allowLabelPrinting = true;
-
   @override
   Future<void> onBuild(BuildContext context) async {
     // Load part data if not already loaded
@@ -259,18 +257,23 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
       }
     });
 
-    // Determine if label printing is supported
-    allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
-    allowLabelPrinting &= api.getPlugins(mixin: "labels").isNotEmpty;
+    List<Map<String, dynamic>> _labels = [];
+    bool allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
+    allowLabelPrinting &= api.supportsMixin("labels");
 
     // Request information on labels available for this stock item
     if (allowLabelPrinting) {
       // Clear the existing labels list
-      labels.clear();
-      labels = await getLabelTemplates("stock", {
+      _labels = await getLabelTemplates("stock", {
         "item": widget.item.pk.toString()
       });
     }
+
+    if (mounted) {
+      setState(() {
+        labels = _labels;
+      });
+    }
   }
 
   /// Delete the stock item from the database