- Real Grid 컴포넌트 @rsone/components 로 모듈화 - 컴포넌트 동적 import 경로 수정(engName -> urlPath)
138 lines
3.9 KiB
TypeScript
138 lines
3.9 KiB
TypeScript
import { create } from "zustand";
|
|
|
|
// MenuItem 타입 정의 (필요한 필드만 포함)
|
|
export interface MenuItem {
|
|
menuCd: number;
|
|
menuKornNm: string;
|
|
menuEngNm: string;
|
|
parentId: number | null;
|
|
sortSeq: number;
|
|
iconNm?: string;
|
|
children: MenuItem[] | null;
|
|
levelNo: number;
|
|
urlPath: string;
|
|
menuLnkgTypeCd: string;
|
|
menuLnkgSn: number;
|
|
menuPath: string;
|
|
qrcd: string;
|
|
useYn: string;
|
|
otptYn: string;
|
|
newWndwYn: string;
|
|
requiredUrlPath: boolean;
|
|
menuHlpCn: string;
|
|
}
|
|
|
|
export interface Tab {
|
|
id: string; // 고유 ID (menuEngNm)
|
|
label: string; // 탭에 표시될 이름
|
|
path: string; // 메뉴 경로
|
|
urlPath: string; // url 경로
|
|
parentEngNm: string; // 부모 menuEngNm
|
|
menuItem: MenuItem; // 메뉴 정보
|
|
}
|
|
|
|
interface TabStore {
|
|
tabs: Tab[];
|
|
activeTabId: string | null;
|
|
menuList: MenuItem[] | null;
|
|
addTab: (menuItem: MenuItem) => boolean;
|
|
removeTab: (tabId: string) => void;
|
|
setActiveTab: (tabId: string) => void;
|
|
setMenuList: (menuList: MenuItem[] | null) => void;
|
|
closeAllTabs: () => void;
|
|
closeOtherTabs: (tabId: string) => void;
|
|
}
|
|
|
|
const useTabStoreHook = create<TabStore>((set, get) => ({
|
|
tabs: [],
|
|
activeTabId: null,
|
|
menuList: null,
|
|
addTab: (menuItem: MenuItem) => {
|
|
const { tabs, menuList } = get();
|
|
const tabId = menuItem.menuEngNm || '';
|
|
|
|
// 이미 존재하는 탭인지 확인
|
|
const existingTab = tabs.find((tab) => tab.id === tabId);
|
|
|
|
if (existingTab) {
|
|
// 이미 존재하면 활성화만
|
|
set({ activeTabId: tabId });
|
|
return true;
|
|
}
|
|
|
|
if (tabs.length < 100) {
|
|
const newTab: Tab = {
|
|
id: tabId,
|
|
label: menuItem.menuKornNm,
|
|
path: menuItem.menuPath,
|
|
urlPath: menuItem.urlPath,
|
|
parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '',
|
|
menuItem,
|
|
};
|
|
|
|
set({
|
|
tabs: [...tabs, newTab],
|
|
activeTabId: tabId,
|
|
});
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
removeTab: (tabId: string): void => {
|
|
const { tabs, activeTabId } = get();
|
|
const newTabs = tabs.filter((tab) => tab.id !== tabId);
|
|
|
|
// 닫는 탭이 현재 활성 탭이면 다른 탭으로 전환
|
|
let newActiveTabId = activeTabId;
|
|
if (activeTabId === tabId) {
|
|
const closedTabIndex = tabs.findIndex((tab) => tab.id === tabId);
|
|
if (newTabs.length > 0) {
|
|
// 닫힌 탭의 이전 탭을 활성화, 없으면 다음 탭
|
|
if (closedTabIndex > 0) {
|
|
const prevTab = tabs[closedTabIndex - 1];
|
|
newActiveTabId = prevTab ? prevTab.id : null;
|
|
} else {
|
|
const firstTab = newTabs[0];
|
|
newActiveTabId = firstTab ? firstTab.id : null;
|
|
}
|
|
} else {
|
|
newActiveTabId = null;
|
|
}
|
|
}
|
|
|
|
set({
|
|
tabs: newTabs,
|
|
activeTabId: newActiveTabId,
|
|
});
|
|
},
|
|
setActiveTab: (tabId: string) => {
|
|
set({ activeTabId: tabId });
|
|
},
|
|
setMenuList: (menuList: MenuItem[] | null) => {
|
|
set({ menuList });
|
|
},
|
|
closeAllTabs: () => {
|
|
set({
|
|
tabs: [],
|
|
activeTabId: null,
|
|
});
|
|
},
|
|
closeOtherTabs: (tabId: string) => {
|
|
const { tabs } = get();
|
|
const tabToKeep = tabs.find((tab) => tab.id === tabId);
|
|
|
|
if (tabToKeep) {
|
|
set({
|
|
tabs: [tabToKeep],
|
|
activeTabId: tabId,
|
|
});
|
|
}
|
|
},
|
|
}));
|
|
|
|
export const useTabStore = useTabStoreHook;
|
|
export const getTabStoreState = () => useTabStoreHook.getState();
|
|
|