mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-22 19:23:31 +00:00
fix: node selection in storage and backups tabs now filters without showing in search
- Storage tab: clicking nodes filters data without adding 'node:xxx' to search - Backups tab: clicking nodes filters data without adding 'node:xxx' to search - Both tabs now use separate selectedNode state for filtering - Search field stays clean for actual text searches - Visual improvements: added hover lift effect to NodeSummaryTable rows
This commit is contained in:
@@ -43,6 +43,7 @@ interface DateGroup {
|
||||
const UnifiedBackups: Component = () => {
|
||||
const { state } = useWebSocket();
|
||||
const [searchTerm, setSearchTerm] = createSignal('');
|
||||
const [selectedNode, setSelectedNode] = createSignal<string | null>(null);
|
||||
const [typeFilter, setTypeFilter] = createSignal<'all' | FilterableGuestType>('all');
|
||||
const [backupTypeFilter, setBackupTypeFilter] = createSignal<'all' | BackupType>('all');
|
||||
const [groupByMode, setGroupByMode] = createSignal<'date' | 'guest'>('date');
|
||||
@@ -354,6 +355,7 @@ const UnifiedBackups: Component = () => {
|
||||
const type = typeFilter();
|
||||
const backupType = backupTypeFilter();
|
||||
const dateRange = selectedDateRange();
|
||||
const nodeFilter = selectedNode();
|
||||
|
||||
// Date range filter
|
||||
if (dateRange) {
|
||||
@@ -362,6 +364,11 @@ const UnifiedBackups: Component = () => {
|
||||
);
|
||||
}
|
||||
|
||||
// Node selection filter
|
||||
if (nodeFilter) {
|
||||
data = data.filter(item => item.node.toLowerCase() === nodeFilter.toLowerCase());
|
||||
}
|
||||
|
||||
// Search filter - with advanced filtering support like Dashboard
|
||||
if (search) {
|
||||
// Check for special PBS namespace filter format first
|
||||
@@ -592,6 +599,7 @@ const UnifiedBackups: Component = () => {
|
||||
// Reset filters
|
||||
const resetFilters = () => {
|
||||
setSearchTerm('');
|
||||
setSelectedNode(null);
|
||||
setIsSearchLocked(false);
|
||||
setTypeFilter('all');
|
||||
setBackupTypeFilter('all');
|
||||
@@ -619,7 +627,7 @@ const UnifiedBackups: Component = () => {
|
||||
// Escape key behavior
|
||||
if (e.key === 'Escape') {
|
||||
// Clear search and reset filters
|
||||
if (searchTerm().trim() || typeFilter() !== 'all' || backupTypeFilter() !== 'all' ||
|
||||
if (searchTerm().trim() || selectedNode() || typeFilter() !== 'all' || backupTypeFilter() !== 'all' ||
|
||||
selectedDateRange() !== null || sortKey() !== 'backupTime' || sortDirection() !== 'desc') {
|
||||
resetFilters();
|
||||
|
||||
@@ -888,14 +896,8 @@ const UnifiedBackups: Component = () => {
|
||||
<UnifiedNodeSelector
|
||||
currentTab="backups"
|
||||
onNodeSelect={(nodeId) => {
|
||||
if (nodeId) {
|
||||
const nodeFilter = `node:${nodeId}`;
|
||||
setSearchTerm(nodeFilter);
|
||||
setIsSearchLocked(true);
|
||||
} else {
|
||||
setSearchTerm('');
|
||||
setIsSearchLocked(false);
|
||||
}
|
||||
setSelectedNode(nodeId);
|
||||
setIsSearchLocked(!!nodeId);
|
||||
}}
|
||||
onNamespaceSelect={(namespaceFilter) => {
|
||||
setSearchTerm(namespaceFilter);
|
||||
|
||||
@@ -13,6 +13,7 @@ const Storage: Component = () => {
|
||||
const { state, connected, activeAlerts, initialDataReceived } = useWebSocket();
|
||||
const [viewMode, setViewMode] = createSignal<'node' | 'storage'>('node');
|
||||
const [searchTerm, setSearchTerm] = createSignal('');
|
||||
const [selectedNode, setSelectedNode] = createSignal<string | null>(null);
|
||||
// TODO: Implement sorting in sortedStorage function
|
||||
// const [sortKey, setSortKey] = createSignal('name');
|
||||
// const [sortDirection, setSortDirection] = createSignal<'asc' | 'desc'>('asc');
|
||||
@@ -59,23 +60,23 @@ const Storage: Component = () => {
|
||||
const sortedStorage = createMemo(() => {
|
||||
let storage = [...filteredStorage()];
|
||||
|
||||
// Apply node selection filter
|
||||
const nodeFilter = selectedNode();
|
||||
if (nodeFilter) {
|
||||
storage = storage.filter(s => s.node.toLowerCase() === nodeFilter.toLowerCase());
|
||||
}
|
||||
|
||||
// Apply search filter
|
||||
const search = searchTerm().toLowerCase();
|
||||
if (search) {
|
||||
// Check if it's a node filter
|
||||
if (search.startsWith('node:')) {
|
||||
const nodeName = search.substring(5).trim();
|
||||
storage = storage.filter(s => s.node.toLowerCase() === nodeName.toLowerCase());
|
||||
} else {
|
||||
// Regular search
|
||||
storage = storage.filter(s =>
|
||||
s.name.toLowerCase().includes(search) ||
|
||||
s.node.toLowerCase().includes(search) ||
|
||||
s.type.toLowerCase().includes(search) ||
|
||||
s.content?.toLowerCase().includes(search) ||
|
||||
(s.status && s.status.toLowerCase().includes(search))
|
||||
);
|
||||
}
|
||||
// Regular search
|
||||
storage = storage.filter(s =>
|
||||
s.name.toLowerCase().includes(search) ||
|
||||
s.node.toLowerCase().includes(search) ||
|
||||
s.type.toLowerCase().includes(search) ||
|
||||
s.content?.toLowerCase().includes(search) ||
|
||||
(s.status && s.status.toLowerCase().includes(search))
|
||||
);
|
||||
}
|
||||
|
||||
// Always sort by name alphabetically for consistent order
|
||||
@@ -116,6 +117,7 @@ const Storage: Component = () => {
|
||||
|
||||
const resetFilters = () => {
|
||||
setSearchTerm('');
|
||||
setSelectedNode(null);
|
||||
setViewMode('node');
|
||||
// setSortKey('name');
|
||||
// setSortDirection('asc');
|
||||
@@ -151,7 +153,7 @@ const Storage: Component = () => {
|
||||
// Escape key behavior
|
||||
if (e.key === 'Escape') {
|
||||
// Clear search and reset filters
|
||||
if (searchTerm().trim() || viewMode() !== 'node') {
|
||||
if (searchTerm().trim() || selectedNode() || viewMode() !== 'node') {
|
||||
resetFilters();
|
||||
|
||||
// Blur the search input if it's focused
|
||||
@@ -173,14 +175,7 @@ const Storage: Component = () => {
|
||||
});
|
||||
|
||||
const handleNodeSelect = (nodeId: string | null) => {
|
||||
if (nodeId) {
|
||||
// Set search to filter by node
|
||||
const nodeFilter = `node:${nodeId}`;
|
||||
setSearchTerm(nodeFilter);
|
||||
} else {
|
||||
// Clear node filter from search
|
||||
setSearchTerm('');
|
||||
}
|
||||
setSelectedNode(nodeId);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -173,7 +173,7 @@ export const NodeSummaryTable: Component<NodeSummaryTableProps> = (props) => {
|
||||
|
||||
return (
|
||||
<tr
|
||||
class={`cursor-pointer transition-colors ${
|
||||
class={`cursor-pointer transition-all duration-150 hover:-translate-y-px hover:shadow-md ${
|
||||
isSelected()
|
||||
? 'bg-blue-100 dark:bg-blue-900/30 hover:bg-blue-100 dark:hover:bg-blue-900/30'
|
||||
: 'hover:bg-gray-50 dark:hover:bg-gray-700/50'
|
||||
|
||||
Reference in New Issue
Block a user