From e13605d2f32b51bb3824dba83dfd10c958888ac9 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 26 Dec 2025 11:43:34 +0000 Subject: [PATCH] fix: Allow clearing AI findings when AI is disabled Users who accumulated AI findings before the patrol-without-AI bug was fixed (24c4bb0b) could not dismiss them because the AI Insights tab and Clear All button were only visible when patrol was enabled. Now the AI Insights tab and Clear All button are visible whenever there are findings to clear, even if AI/patrol is not enabled. Related to #885 --- .../src/components/Storage/Storage.tsx | 133 ++++++++++++------ .../src/components/Storage/StorageFilter.tsx | 20 +++ frontend-modern/src/pages/Alerts.tsx | 11 +- frontend-modern/src/utils/localStorage.ts | 1 + 4 files changed, 114 insertions(+), 51 deletions(-) diff --git a/frontend-modern/src/components/Storage/Storage.tsx b/frontend-modern/src/components/Storage/Storage.tsx index 419b88739..1d591816a 100644 --- a/frontend-modern/src/components/Storage/Storage.tsx +++ b/frontend-modern/src/components/Storage/Storage.tsx @@ -18,6 +18,8 @@ import { getNodeDisplayName } from '@/utils/nodes'; import { usePersistentSignal } from '@/hooks/usePersistentSignal'; import { useDebouncedValue } from '@/hooks/useDebouncedValue'; import { useAlertsActivation } from '@/stores/alertsActivation'; +import { useColumnVisibility, type ColumnDef } from '@/hooks/useColumnVisibility'; +import { STORAGE_KEYS } from '@/utils/localStorage'; type StorageSortKey = 'name' | 'node' | 'type' | 'status' | 'usage' | 'free' | 'total'; @@ -61,6 +63,24 @@ const Storage: Component = () => { }, ); + // Column definitions for storage table + const STORAGE_COLUMNS: ColumnDef[] = [ + { id: 'type', label: 'Type', priority: 3 }, + { id: 'content', label: 'Content', priority: 4 }, + { id: 'status', label: 'Status', priority: 2 }, + { id: 'shared', label: 'Shared', priority: 5, hiddenByDefault: true }, + { id: 'free', label: 'Free', priority: 4 }, + { id: 'total', label: 'Total', priority: 3 }, + ]; + + // Column visibility management + const columnVisibility = useColumnVisibility( + STORAGE_COLUMNS, + STORAGE_KEYS.STORAGE_HIDDEN_COLUMNS + ); + + const isColumnVisible = (id: string) => !columnVisibility.isHiddenByUser(id); + // PERFORMANCE: Debounce search term to prevent jank during rapid typing const debouncedSearchTerm = useDebouncedValue(() => searchTerm(), 200); @@ -601,6 +621,7 @@ const Storage: Component = () => { statusFilter={statusFilter} setStatusFilter={setStatusFilter} searchInputRef={(el) => (searchInputRef = el)} + columnVisibility={columnVisibility} /> @@ -794,16 +815,22 @@ const Storage: Component = () => { Storage - - Type - - - Content - - - Status - - + + + Type + + + + + Content + + + + + Status + + + Shared @@ -811,12 +838,16 @@ const Storage: Component = () => { Usage - - Free - - - Total - + + + Free + + + + + Total + + @@ -1154,30 +1185,36 @@ const Storage: Component = () => { - - - {storage.type} - - - - - {storage.content || '-'} - - - - - {storage.status || 'unknown'} - - - + + + + {storage.type} + + + + + + + {storage.content || '-'} + + + + + + + {storage.status || 'unknown'} + + + + {storage.shared ? '✓' : '-'} @@ -1193,12 +1230,16 @@ const Storage: Component = () => { zfsPool={storage.zfsPool} /> - - {formatBytes(storage.free || 0, 0)} - - - {formatBytes(storage.total || 0, 0)} - + + + {formatBytes(storage.free || 0, 0)} + + + + + {formatBytes(storage.total || 0, 0)} + + diff --git a/frontend-modern/src/components/Storage/StorageFilter.tsx b/frontend-modern/src/components/Storage/StorageFilter.tsx index c9fe946e7..f4f374798 100644 --- a/frontend-modern/src/components/Storage/StorageFilter.tsx +++ b/frontend-modern/src/components/Storage/StorageFilter.tsx @@ -1,6 +1,8 @@ import { Component, Show, For, createSignal, onMount, createEffect, onCleanup } from 'solid-js'; import { Card } from '@/components/shared/Card'; import { SearchTipsPopover } from '@/components/shared/SearchTipsPopover'; +import { ColumnPicker } from '@/components/shared/ColumnPicker'; +import type { ColumnDef } from '@/hooks/useColumnVisibility'; import { STORAGE_KEYS } from '@/utils/localStorage'; import { createSearchHistoryManager } from '@/utils/searchHistory'; @@ -17,6 +19,13 @@ interface StorageFilterProps { searchInputRef?: (el: HTMLInputElement) => void; statusFilter?: () => 'all' | 'available' | 'offline'; setStatusFilter?: (value: 'all' | 'available' | 'offline') => void; + // Column visibility (optional) + columnVisibility?: { + availableToggles: () => ColumnDef[]; + isHiddenByUser: (id: string) => boolean; + toggle: (id: string) => void; + resetToDefaults: () => void; + }; } export const StorageFilter: Component = (props) => { @@ -387,6 +396,17 @@ export const StorageFilter: Component = (props) => { + {/* Column Picker */} + + + + + {/* Reset Button - Only show when filters are active */} diff --git a/frontend-modern/src/pages/Alerts.tsx b/frontend-modern/src/pages/Alerts.tsx index 3933fb877..8b7d54195 100644 --- a/frontend-modern/src/pages/Alerts.tsx +++ b/frontend-modern/src/pages/Alerts.tsx @@ -2661,7 +2661,8 @@ function OverviewTab(props: { {/* Sub-tabs for AI Insights vs Active Alerts */} - + {/* Show tabs when patrol is enabled OR when there are legacy findings to clear */} + 0}>