This commit is contained in:
Desktop
2025-11-13 00:52:28 +05:00
parent 52dc95d66c
commit 235f01c1fe
2 changed files with 114 additions and 52 deletions

View File

@@ -0,0 +1,70 @@
/**
* Column Visibility Store (Zustand)
* Manages column visibility settings per page with localStorage persistence
* Uses the same pattern as siteStore and sectorStore
*/
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface ColumnVisibilityState {
// Map of page pathname to Set of visible column keys
pageColumns: Record<string, string[]>;
// Actions
setPageColumns: (pathname: string, columnKeys: string[]) => void;
getPageColumns: (pathname: string) => string[];
toggleColumn: (pathname: string, columnKey: string) => void;
resetPageColumns: (pathname: string) => void;
}
export const useColumnVisibilityStore = create<ColumnVisibilityState>()(
persist<ColumnVisibilityState>(
(set, get) => ({
pageColumns: {},
setPageColumns: (pathname: string, columnKeys: string[]) => {
set((state) => ({
pageColumns: {
...state.pageColumns,
[pathname]: columnKeys,
},
}));
},
getPageColumns: (pathname: string) => {
return get().pageColumns[pathname] || [];
},
toggleColumn: (pathname: string, columnKey: string) => {
set((state) => {
const currentColumns = state.pageColumns[pathname] || [];
const newColumns = currentColumns.includes(columnKey)
? currentColumns.filter((key) => key !== columnKey)
: [...currentColumns, columnKey];
return {
pageColumns: {
...state.pageColumns,
[pathname]: newColumns,
},
};
});
},
resetPageColumns: (pathname: string) => {
set((state) => {
const newPageColumns = { ...state.pageColumns };
delete newPageColumns[pathname];
return { pageColumns: newPageColumns };
});
},
}),
{
name: 'igny8-column-visibility',
partialize: (state) => ({
pageColumns: state.pageColumns,
}),
}
)
);

View File

@@ -39,6 +39,7 @@ import BulkExportModal from '../components/common/BulkExportModal';
import BulkStatusUpdateModal from '../components/common/BulkStatusUpdateModal'; import BulkStatusUpdateModal from '../components/common/BulkStatusUpdateModal';
import { CompactPagination } from '../components/ui/pagination'; import { CompactPagination } from '../components/ui/pagination';
import { usePageSizeStore } from '../store/pageSizeStore'; import { usePageSizeStore } from '../store/pageSizeStore';
import { useColumnVisibilityStore } from '../store/columnVisibilityStore';
import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow'; import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow';
import ColumnSelector from '../components/common/ColumnSelector'; import ColumnSelector from '../components/common/ColumnSelector';
@@ -224,81 +225,72 @@ export default function TablePageTemplate({
const { setMetrics } = useHeaderMetrics(); const { setMetrics } = useHeaderMetrics();
const toast = useToast(); const toast = useToast();
const { pageSize, setPageSize } = usePageSizeStore(); const { pageSize, setPageSize } = usePageSizeStore();
const { pageColumns, setPageColumns, getPageColumns } = useColumnVisibilityStore();
// Column visibility state management with localStorage persistence // Column visibility state management with Zustand store (same pattern as site/sector stores)
const getStorageKey = () => { // Initialize visible columns from store or defaults
// Use pathname to create unique storage key per page
return `table-columns-${location.pathname}`;
};
// Initialize visible columns from localStorage or defaults
const initializeVisibleColumns = useMemo(() => { const initializeVisibleColumns = useMemo(() => {
const storageKey = getStorageKey(); const savedColumnKeys = getPageColumns(location.pathname);
try {
const saved = localStorage.getItem(storageKey); if (savedColumnKeys.length > 0) {
if (saved) { const savedSet = new Set(savedColumnKeys);
const savedSet = new Set(JSON.parse(saved)); // Validate that all saved columns still exist
// Validate that all saved columns still exist const validColumns = columns.filter(col => savedSet.has(col.key));
const validColumns = columns.filter(col => savedSet.has(col.key)); if (validColumns.length > 0) {
if (validColumns.length > 0) { // Add any new columns with defaultVisible !== false
// Add any new columns with defaultVisible !== false const newColumns = columns
const newColumns = columns .filter(col => !savedSet.has(col.key) && col.defaultVisible !== false)
.filter(col => !savedSet.has(col.key) && col.defaultVisible !== false) .map(col => col.key);
.map(col => col.key); return new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns]);
return new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns]);
}
} }
} catch (e) {
// Ignore parse errors
} }
// Default: show all columns that have defaultVisible !== false // Default: show all columns that have defaultVisible !== false
return new Set( return new Set(
columns columns
.filter(col => col.defaultVisible !== false) .filter(col => col.defaultVisible !== false)
.map(col => col.key) .map(col => col.key)
); );
}, [columns, location.pathname]); }, [columns, location.pathname, getPageColumns]);
const [visibleColumns, setVisibleColumns] = useState<Set<string>>(initializeVisibleColumns); const [visibleColumns, setVisibleColumns] = useState<Set<string>>(initializeVisibleColumns);
// Update visible columns when columns prop or pathname changes // Update visible columns when columns prop or pathname changes
useEffect(() => { useEffect(() => {
const storageKey = getStorageKey(); const savedColumnKeys = getPageColumns(location.pathname);
try {
const saved = localStorage.getItem(storageKey); if (savedColumnKeys.length > 0) {
if (saved) { const savedSet = new Set(savedColumnKeys);
const savedSet = new Set(JSON.parse(saved)); // Validate that all saved columns still exist
// Validate that all saved columns still exist const validColumns = columns.filter(col => savedSet.has(col.key));
const validColumns = columns.filter(col => savedSet.has(col.key)); if (validColumns.length > 0) {
if (validColumns.length > 0) { // Add any new columns with defaultVisible !== false
// Add any new columns with defaultVisible !== false const newColumns = columns
const newColumns = columns .filter(col => !savedSet.has(col.key) && col.defaultVisible !== false)
.filter(col => !savedSet.has(col.key) && col.defaultVisible !== false) .map(col => col.key);
.map(col => col.key); const newSet = new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns]);
setVisibleColumns(new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns])); setVisibleColumns(newSet);
return; // Update store with validated columns
} setPageColumns(location.pathname, Array.from(newSet));
return;
} }
} catch (e) {
// Ignore parse errors
} }
// Default: show all columns that have defaultVisible !== false // Default: show all columns that have defaultVisible !== false
setVisibleColumns(new Set( const defaultSet = new Set(
columns columns
.filter(col => col.defaultVisible !== false) .filter(col => col.defaultVisible !== false)
.map(col => col.key) .map(col => col.key)
)); );
}, [columns, location.pathname]); // Re-initialize when columns or pathname changes setVisibleColumns(defaultSet);
// Save defaults to store
setPageColumns(location.pathname, Array.from(defaultSet));
}, [columns, location.pathname, getPageColumns, setPageColumns]);
// Save to localStorage whenever visibleColumns changes // Save to store whenever visibleColumns changes (Zustand persist middleware handles localStorage)
useEffect(() => { useEffect(() => {
const storageKey = getStorageKey(); setPageColumns(location.pathname, Array.from(visibleColumns));
try { }, [visibleColumns, location.pathname, setPageColumns]);
localStorage.setItem(storageKey, JSON.stringify(Array.from(visibleColumns)));
} catch (e) {
// Ignore storage errors
}
}, [visibleColumns, location.pathname]);
// Filter columns based on visibility // Filter columns based on visibility
const visibleColumnsList = useMemo(() => { const visibleColumnsList = useMemo(() => {