- Introduced a new controller for managing custom input values in report cells, allowing users to retrieve and upsert values associated with specific reports and targets. - Implemented API routes for fetching and saving report cell values, ensuring proper authentication and data handling. - Enhanced the frontend components to support the new report cell input functionality, including the ability to edit and save input values in a modal. - Updated inventory and equipment management pages to include new features for handling missing items and managing warehouse locations effectively.
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { usePathname } from "next/navigation";
|
|
import { useMemo } from "react";
|
|
import { useMenu } from "@/contexts/MenuContext";
|
|
import { useTabStore, selectTabs, selectActiveTabId } from "@/stores/tabStore";
|
|
|
|
function stripCompanyPrefix(pathname: string): string {
|
|
return pathname.replace(/^\/COMPANY_\d+/, "") || "/";
|
|
}
|
|
|
|
/**
|
|
* 현재 경로가 속한 "대분류" 메뉴의 objid 반환.
|
|
* - 메뉴 트리에서 parent_obj_id를 따라 올라가며, 트리에 부모가 더 이상 존재하지 않는 루트 바로 직전의 노드를 반환
|
|
* - lev 필드에 의존하지 않음 (백엔드 재귀 쿼리 결과와 무관)
|
|
* - 탭 시스템(/main에서 탭으로 페이지를 띄우는 경우) 대응: usePathname이 '/main'을 반환하므로
|
|
* 활성 탭의 adminUrl을 fallback으로 사용
|
|
*/
|
|
export function useCurrent2ndLevelMenuObjid(): number | null {
|
|
const pathname = usePathname();
|
|
const { userMenus, adminMenus } = useMenu();
|
|
const tabs = useTabStore(selectTabs);
|
|
const activeTabId = useTabStore(selectActiveTabId);
|
|
|
|
return useMemo(() => {
|
|
if (!pathname) return null;
|
|
|
|
const all: any[] = [...(userMenus as any[]), ...(adminMenus as any[])];
|
|
if (all.length === 0) return null;
|
|
|
|
// 1차: 실제 pathname 기준. 2차(탭 컨테이너 경로 등): 활성 탭 URL 기준
|
|
let targetUrl = stripCompanyPrefix(pathname);
|
|
const isRootLikePath = pathname === "/main" || pathname === "/" || pathname === "";
|
|
if (isRootLikePath) {
|
|
const activeTab = tabs.find((t) => t.id === activeTabId);
|
|
if (activeTab?.adminUrl) {
|
|
targetUrl = stripCompanyPrefix(activeTab.adminUrl);
|
|
}
|
|
}
|
|
|
|
const byObjid = new Map<string, any>();
|
|
for (const m of all) {
|
|
byObjid.set(String(m.objid), m);
|
|
}
|
|
|
|
const current = all.find((m) => m.menu_url === targetUrl);
|
|
if (!current) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn("[useCurrent2ndLevelMenuObjid] 메뉴 매칭 실패", { targetUrl, sample: all.slice(0, 3) });
|
|
return null;
|
|
}
|
|
|
|
let node: any = current;
|
|
let prev: any = null;
|
|
let safety = 20;
|
|
while (node && safety-- > 0) {
|
|
const parentId = node.parent_obj_id;
|
|
if (parentId === null || parentId === undefined || parentId === 0 || parentId === "0") {
|
|
break;
|
|
}
|
|
const parent = byObjid.get(String(parentId));
|
|
if (!parent) break;
|
|
prev = node;
|
|
node = parent;
|
|
}
|
|
|
|
const resultObjid = prev ? Number(prev.objid) : Number(node.objid);
|
|
// eslint-disable-next-line no-console
|
|
console.log("[useCurrent2ndLevelMenuObjid]", {
|
|
targetUrl,
|
|
currentObjid: current.objid,
|
|
currentName: current.menu_name_kor,
|
|
resultObjid,
|
|
resultName: prev ? prev.menu_name_kor : node.menu_name_kor,
|
|
});
|
|
return resultObjid;
|
|
}, [pathname, userMenus, adminMenus, tabs, activeTabId]);
|
|
}
|