feat(WEB): 테이블 컬럼 표시/숨김 설정 기능 추가
- useColumnSettings 훅: 컬럼 가시성 토글 로직 - useTableColumnStore: Zustand 기반 컬럼 설정 영속화 (localStorage) - ColumnSettingsPopover: 컬럼 설정 UI 컴포넌트 - UniversalListPage/IntegratedListTemplateV2에 컬럼 설정 통합 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
101
src/stores/useTableColumnStore.ts
Normal file
101
src/stores/useTableColumnStore.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { safeJsonParse } from '@/lib/utils';
|
||||
|
||||
interface PageColumnSettings {
|
||||
columnWidths: Record<string, number>;
|
||||
hiddenColumns: string[];
|
||||
}
|
||||
|
||||
interface TableColumnState {
|
||||
pageSettings: Record<string, PageColumnSettings>;
|
||||
setColumnWidth: (pageId: string, columnKey: string, width: number) => void;
|
||||
toggleColumnVisibility: (pageId: string, columnKey: string) => void;
|
||||
resetPageSettings: (pageId: string) => void;
|
||||
getPageSettings: (pageId: string) => PageColumnSettings;
|
||||
}
|
||||
|
||||
function getUserId(): string {
|
||||
if (typeof window === 'undefined') return 'default';
|
||||
const userStr = localStorage.getItem('user');
|
||||
if (!userStr) return 'default';
|
||||
const user = safeJsonParse<Record<string, unknown> | null>(userStr, null);
|
||||
return user?.id ? String(user.id) : 'default';
|
||||
}
|
||||
|
||||
function getStorageKey(): string {
|
||||
return `sam-table-columns-${getUserId()}`;
|
||||
}
|
||||
|
||||
const DEFAULT_PAGE_SETTINGS: PageColumnSettings = {
|
||||
columnWidths: {},
|
||||
hiddenColumns: [],
|
||||
};
|
||||
|
||||
export const useTableColumnStore = create<TableColumnState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
pageSettings: {},
|
||||
|
||||
setColumnWidth: (pageId: string, columnKey: string, width: number) => {
|
||||
const { pageSettings } = get();
|
||||
const current = pageSettings[pageId] || { ...DEFAULT_PAGE_SETTINGS };
|
||||
set({
|
||||
pageSettings: {
|
||||
...pageSettings,
|
||||
[pageId]: {
|
||||
...current,
|
||||
columnWidths: { ...current.columnWidths, [columnKey]: width },
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
toggleColumnVisibility: (pageId: string, columnKey: string) => {
|
||||
const { pageSettings } = get();
|
||||
const current = pageSettings[pageId] || { ...DEFAULT_PAGE_SETTINGS };
|
||||
const hidden = current.hiddenColumns.includes(columnKey)
|
||||
? current.hiddenColumns.filter((k) => k !== columnKey)
|
||||
: [...current.hiddenColumns, columnKey];
|
||||
set({
|
||||
pageSettings: {
|
||||
...pageSettings,
|
||||
[pageId]: { ...current, hiddenColumns: hidden },
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
resetPageSettings: (pageId: string) => {
|
||||
const { pageSettings } = get();
|
||||
const { [pageId]: _, ...rest } = pageSettings;
|
||||
set({ pageSettings: rest });
|
||||
},
|
||||
|
||||
getPageSettings: (pageId: string) => {
|
||||
return get().pageSettings[pageId] || DEFAULT_PAGE_SETTINGS;
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'sam-table-columns',
|
||||
storage: {
|
||||
getItem: (name) => {
|
||||
const key = getStorageKey();
|
||||
const str = localStorage.getItem(key);
|
||||
if (!str) {
|
||||
const fallback = localStorage.getItem(name);
|
||||
return fallback ? JSON.parse(fallback) : null;
|
||||
}
|
||||
return JSON.parse(str);
|
||||
},
|
||||
setItem: (name, value) => {
|
||||
const key = getStorageKey();
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
},
|
||||
removeItem: (name) => {
|
||||
const key = getStorageKey();
|
||||
localStorage.removeItem(key);
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user