feat: Implement dynamic search filter in Shipping Plan page
- Integrated DynamicSearchFilter component to manage search filters. - Removed individual search state variables and replaced with a single searchFilters state. - Updated fetchData function to handle new filter structure. - Refactored search filter UI to utilize DynamicSearchFilter. - Adjusted table header styles for better visibility and consistency. style: Update global styles for improved UI consistency - Unified font size across the application to 16px, excluding buttons. - Adjusted header padding and font size for better readability. - Enhanced dark mode styles for checkboxes to ensure visibility. feat: Add Options Setting page for category and numbering configurations - Created a new OptionsSettingPage component with tabs for category and numbering settings. - Implemented drag-to-resize functionality for the category column list. - Integrated CategoryColumnList and CategoryValueManager components for managing categories. feat: Introduce useTableSettings hook for table configuration management - Developed useTableSettings hook to manage column visibility, order, and width. - Implemented localStorage persistence for table settings. - Enhanced TableSettingsModal to accept defaultVisibleKeys for initial column visibility. chore: Update AdminPageRenderer to include new COMPANY_16 routes - Added new routes for COMPANY_16 master-data options and other pages.
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* useTableSettings — 날코딩 페이지용 테이블 설정 훅
|
||||
*
|
||||
* TableSettingsModal과 함께 사용하여 컬럼 표시/숨김, 순서, 너비를 관리합니다.
|
||||
* 설정은 localStorage에 자동 저장/복원됩니다.
|
||||
*
|
||||
* @example
|
||||
* const ts = useTableSettings("item-info", TABLE_NAME, GRID_COLUMNS);
|
||||
*
|
||||
* // 툴바 버튼
|
||||
* <Button variant="ghost" size="sm" onClick={() => ts.setOpen(true)}>
|
||||
* <Settings2 className="h-4 w-4" />
|
||||
* </Button>
|
||||
*
|
||||
* // 테이블 헤더 — GRID_COLUMNS 대신 ts.visibleColumns 사용
|
||||
* {ts.visibleColumns.map(col => <TableHead key={col.key}>{col.label}</TableHead>)}
|
||||
*
|
||||
* // 모달 (JSX 하단)
|
||||
* <TableSettingsModal
|
||||
* open={ts.open}
|
||||
* onOpenChange={ts.setOpen}
|
||||
* tableName={ts.tableName}
|
||||
* settingsId={ts.settingsId}
|
||||
* onSave={ts.applySettings}
|
||||
* />
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback, useMemo } from "react";
|
||||
import { loadTableSettings, type TableSettings } from "@/components/common/TableSettingsModal";
|
||||
|
||||
export function useTableSettings<T extends { key: string }>(
|
||||
settingsId: string,
|
||||
tableName: string,
|
||||
defaultColumns: T[],
|
||||
) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [visibleKeys, setVisibleKeys] = useState<Set<string>>(
|
||||
() => new Set(defaultColumns.map((c) => c.key)),
|
||||
);
|
||||
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
|
||||
const [orderedKeys, setOrderedKeys] = useState<string[]>(
|
||||
() => defaultColumns.map((c) => c.key),
|
||||
);
|
||||
// 초기 filterConfig: GRID_COLUMNS에 있는 컬럼만 필터 가능 (전부 비활성)
|
||||
const [filterConfig, setFilterConfig] = useState<TableSettings["filters"]>(
|
||||
() =>
|
||||
defaultColumns.map((c) => ({
|
||||
columnName: c.key,
|
||||
displayName: (c as any).label || c.key,
|
||||
enabled: false,
|
||||
filterType: "text" as const,
|
||||
width: 25,
|
||||
})),
|
||||
);
|
||||
|
||||
/** TableSettingsModal onSave에 전달할 콜백 */
|
||||
const applySettings = useCallback(
|
||||
(settings: TableSettings) => {
|
||||
const visible = new Set<string>();
|
||||
const widths: Record<string, number> = {};
|
||||
const order: string[] = [];
|
||||
|
||||
for (const cs of settings.columns) {
|
||||
if (cs.visible) {
|
||||
visible.add(cs.columnName);
|
||||
widths[cs.columnName] = cs.width;
|
||||
order.push(cs.columnName);
|
||||
}
|
||||
}
|
||||
|
||||
// settings에 없는 새 컬럼은 보이도록 추가
|
||||
for (const col of defaultColumns) {
|
||||
if (!settings.columns.find((c) => c.columnName === col.key)) {
|
||||
visible.add(col.key);
|
||||
order.push(col.key);
|
||||
}
|
||||
}
|
||||
|
||||
setVisibleKeys(visible);
|
||||
setColumnWidths(widths);
|
||||
setOrderedKeys(order);
|
||||
|
||||
// 화면에 표시된 컬럼만 필터 가능하도록 제한
|
||||
setFilterConfig(
|
||||
settings.filters?.filter((f) => visible.has(f.columnName)),
|
||||
);
|
||||
},
|
||||
[defaultColumns],
|
||||
);
|
||||
|
||||
// 마운트 시 저장된 설정 복원
|
||||
useEffect(() => {
|
||||
const saved = loadTableSettings(settingsId);
|
||||
if (saved) applySettings(saved);
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
/** 설정이 적용된 컬럼 목록 (순서 + 표시 필터 적용) */
|
||||
const visibleColumns = useMemo((): T[] => {
|
||||
const colMap = new Map(defaultColumns.map((c) => [c.key, c]));
|
||||
const result: T[] = [];
|
||||
|
||||
// 저장된 순서대로
|
||||
for (const key of orderedKeys) {
|
||||
if (visibleKeys.has(key)) {
|
||||
const col = colMap.get(key);
|
||||
if (col) result.push(col);
|
||||
}
|
||||
}
|
||||
|
||||
// orderedKeys에 없는 컬럼 (새로 추가된 것)
|
||||
for (const col of defaultColumns) {
|
||||
if (!orderedKeys.includes(col.key) && visibleKeys.has(col.key)) {
|
||||
result.push(col);
|
||||
}
|
||||
}
|
||||
|
||||
return result.length > 0 ? result : defaultColumns;
|
||||
}, [defaultColumns, orderedKeys, visibleKeys]);
|
||||
|
||||
/** 컬럼 표시 여부 확인 */
|
||||
const isVisible = useCallback((key: string) => visibleKeys.has(key), [visibleKeys]);
|
||||
|
||||
/** 컬럼 너비 가져오기 (설정값 or undefined) */
|
||||
const getWidth = useCallback(
|
||||
(key: string): number | undefined => columnWidths[key],
|
||||
[columnWidths],
|
||||
);
|
||||
|
||||
return {
|
||||
/** 모달 open 상태 */
|
||||
open,
|
||||
/** 모달 open 상태 setter */
|
||||
setOpen,
|
||||
/** web-types API 호출용 테이블명 */
|
||||
tableName,
|
||||
/** localStorage 키 */
|
||||
settingsId,
|
||||
/** TableSettingsModal onSave 콜백 */
|
||||
applySettings,
|
||||
/** 설정 적용된 컬럼 배열 (순서 + 표시 필터) */
|
||||
visibleColumns,
|
||||
/** 특정 컬럼 표시 여부 */
|
||||
isVisible,
|
||||
/** 특정 컬럼 너비 (px) */
|
||||
getWidth,
|
||||
/** 필터 설정 */
|
||||
filterConfig,
|
||||
/** GRID_COLUMNS 기본 컬럼 키 목록 (TableSettingsModal defaultVisibleKeys용) */
|
||||
defaultVisibleKeys: defaultColumns.map((c) => c.key),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user