asd
This commit is contained in:
70
frontend/src/store/columnVisibilityStore.ts
Normal file
70
frontend/src/store/columnVisibilityStore.ts
Normal 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,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
@@ -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(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user