Repository: nautobot/nautobot

Issue:
Interfaces / Console ports count incremented without connections
### Environment
* Python version: 3.8.8
* Nautobot version: 1.2.4

### Steps to Reproduce
1. Add device with interfaces / console ports and dont connect any interfaces / console ports to other devices

### Expected Behavior
Previously before 1.2.4, the count of interfaces on the main page only increased the total number of interfaces / console ports that has a cable to other devices and showing wether or not these interfaces has end-to-end connectivity.

### Observed Behavior
In 1.2.4, the count of interfaces / console ports increases without connecting cables.


Discussion:
@jn-ier What version of Nautobot were you on before upgrading to 1.2.4?
This appears to have been broken with #716.

Resolving patch:
diff --git a/nautobot/core/apps/__init__.py b/nautobot/core/apps/__init__.py
--- a/nautobot/core/apps/__init__.py
+++ b/nautobot/core/apps/__init__.py
@@ -170,6 +170,7 @@ def register_homepage_panels(path, label, homepage_layout):
                     create_or_check_entry(registry_items, item, item.name, f"{panel.name} -> {item.name}")
                     for group_item in item.items:
                         if isinstance(group_item, HomePageItem):
+                            group_item.template_path = template_path
                             create_or_check_entry(
                                 registry_items[item.name]["items"],
                                 group_item,
diff --git a/nautobot/core/views/__init__.py b/nautobot/core/views/__init__.py
--- a/nautobot/core/views/__init__.py
+++ b/nautobot/core/views/__init__.py
@@ -89,9 +89,14 @@ def get(self, request):
                     elif item_details.get("items"):
                         # Collect count for grouped objects.
                         for group_item_details in item_details["items"].values():
-                            group_item_details["count"] = (
-                                group_item_details["model"].objects.restrict(request.user, "view").count()
-                            )
+                            if group_item_details.get("custom_template"):
+                                group_item_details["rendered_html"] = self.render_additional_content(
+                                    request, context, group_item_details
+                                )
+                            elif group_item_details.get("model"):
+                                group_item_details["count"] = (
+                                    group_item_details["model"].objects.restrict(request.user, "view").count()
+                                )
 
         return self.render_to_response(context)
 
diff --git a/nautobot/dcim/homepage.py b/nautobot/dcim/homepage.py
--- a/nautobot/dcim/homepage.py
+++ b/nautobot/dcim/homepage.py
@@ -1,7 +1,33 @@
+from django.contrib.contenttypes.models import ContentType
+from django.db.models import F
+
 from nautobot.core.apps import HomePageGroup, HomePageItem, HomePagePanel
 from nautobot.dcim import models
 
 
+def _connected_consoleports_count(request):
+    # Match queryset used in dcim.views.ConsoleConnectionsListView
+    return models.ConsolePort.objects.restrict(request.user, "view").filter(_path__isnull=False).count()
+
+
+def _connected_interfaces_count(request):
+    # Match queryset used in dcim.views.InterfaceConnectionsListView
+    return (
+        models.Interface.objects.restrict(request.user, "view")
+        .filter(_path__isnull=False)
+        .exclude(
+            _path__destination_type=ContentType.objects.get_for_model(models.Interface),
+            pk__lt=F("_path__destination_id"),
+        )
+        .count()
+    )
+
+
+def _connected_powerports_count(request):
+    # Match queryset used in dcim.views.PowerConnectionsListView
+    return models.PowerPort.objects.restrict(request.user, "view").filter(_path__isnull=False).count()
+
+
 layout = (
     HomePagePanel(
         name="Organization",
@@ -74,22 +100,34 @@
                     ),
                     HomePageItem(
                         name="Interfaces",
-                        link="dcim:interface_connections_list",
-                        model=models.Interface,
+                        custom_template="homepage_connections.html",
+                        custom_data={
+                            "connections_count": _connected_interfaces_count,
+                            "connections_url": "dcim:interface_connections_list",
+                            "connections_label": "Interfaces",
+                        },
                         permissions=["dcim.view_interface"],
                         weight=200,
                     ),
                     HomePageItem(
                         name="Console",
-                        link="dcim:console_connections_list",
-                        model=models.ConsolePort,
+                        custom_template="homepage_connections.html",
+                        custom_data={
+                            "connections_count": _connected_consoleports_count,
+                            "connections_url": "dcim:console_connections_list",
+                            "connections_label": "Console",
+                        },
                         permissions=["dcim.view_consoleport", "dcim.view_consoleserverport"],
                         weight=300,
                     ),
                     HomePageItem(
                         name="Power",
-                        link="dcim:power_connections_list",
-                        model=models.PowerOutlet,
+                        custom_template="homepage_connections.html",
+                        custom_data={
+                            "connections_count": _connected_powerports_count,
+                            "connections_url": "dcim:power_connections_list",
+                            "connections_label": "Power",
+                        },
                         permissions=["dcim.view_powerport", "dcim.view_poweroutlet"],
                         weight=400,
                     ),


Test patch: