diff --git a/lib/towerops/activity_feed.ex b/lib/towerops/activity_feed.ex
index 1a07a704..6ffd6ca0 100644
--- a/lib/towerops/activity_feed.ex
+++ b/lib/towerops/activity_feed.ex
@@ -45,6 +45,7 @@ defmodule Towerops.ActivityFeed do
types = Keyword.get(opts, :types, nil)
after_dt = Keyword.get(opts, :after, nil)
before_dt = Keyword.get(opts, :before, nil)
+ search = Keyword.get(opts, :search, nil)
sources = active_sources(types)
@@ -54,10 +55,52 @@ defmodule Towerops.ActivityFeed do
end)
items
+ |> maybe_filter_search(search)
|> Enum.sort_by(& &1.timestamp, {:desc, DateTime})
|> Enum.take(limit)
end
+ @doc """
+ Returns counts of items per type for an organization (for filter chip badges).
+ """
+ def count_by_type(organization_id) do
+ # Count recent items (last 24h) per type for badge display
+ since = DateTime.add(DateTime.utc_now(), -86400, :second)
+
+ active_sources(nil)
+ |> Enum.map(fn source ->
+ items = fetch_source(source, organization_id, since, nil, 1000)
+ {source, length(items)}
+ end)
+ |> Map.new()
+ end
+
+ defp maybe_filter_search(items, nil), do: items
+ defp maybe_filter_search(items, ""), do: items
+
+ defp maybe_filter_search(items, search) do
+ search_lower = String.downcase(search)
+
+ Enum.filter(items, fn item ->
+ matches_search?(item, search_lower)
+ end)
+ end
+
+ defp matches_search?(item, search) do
+ searchable =
+ [
+ item.device_name,
+ item.site_name,
+ item.summary,
+ item.detail
+ ]
+ |> Enum.reject(&is_nil/1)
+ |> Enum.join(" ")
+ |> String.downcase()
+
+ String.contains?(searchable, search)
+ end
+
defp active_sources(nil),
do: [:config_change, :alert_fired, :alert_resolved, :device_event, :sync, :device_added]
diff --git a/lib/towerops_web/components/layouts.ex b/lib/towerops_web/components/layouts.ex
index e93868b1..00c64579 100644
--- a/lib/towerops_web/components/layouts.ex
+++ b/lib/towerops_web/components/layouts.ex
@@ -228,19 +228,13 @@ defmodule ToweropsWeb.Layouts do
navigate={~p"/network-map"}
active={@active_page == "network-map"}
>
-
- <.icon name="hero-beaker" class="h-3.5 w-3.5 text-blue-500 dark:text-blue-400" />
- Network Map
-
+ Network Map
<.nav_link
navigate={~p"/alerts"}
active={@active_page == "alerts"}
>
-
- <.icon name="hero-beaker" class="h-3.5 w-3.5 text-blue-500 dark:text-blue-400" />
- Alerts
-
+ Alerts
<.nav_link
navigate={~p"/insights"}