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:
유병철
2026-02-20 18:09:17 +09:00
parent 30ca2afca8
commit ceeeeb1ef4
6 changed files with 353 additions and 6 deletions

View 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);
},
},
}
)
);