@bwg-ui/core 1.1.11 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/chunks/BwgLargeUploader-CgrJUwFW.cjs +3 -0
  2. package/dist/chunks/BwgLargeUploader-CgrJUwFW.cjs.map +1 -0
  3. package/dist/chunks/{BwgLargeUploader-B5EtYKUz.js → BwgLargeUploader-Nx2-wiD8.js} +802 -776
  4. package/dist/chunks/BwgLargeUploader-Nx2-wiD8.js.map +1 -0
  5. package/dist/chunks/{FileUtils-CaU9Bzu2.js → FileUtils-Bbz3AvQn.js} +2 -2
  6. package/dist/chunks/{FileUtils-CaU9Bzu2.js.map → FileUtils-Bbz3AvQn.js.map} +1 -1
  7. package/dist/chunks/FileUtils-D73GVmB8.cjs +2 -0
  8. package/dist/chunks/{FileUtils-BweAWoJt.cjs.map → FileUtils-D73GVmB8.cjs.map} +1 -1
  9. package/dist/chunks/SSOHandler-CZHPiuEh.js +25397 -0
  10. package/dist/chunks/SSOHandler-CZHPiuEh.js.map +1 -0
  11. package/dist/chunks/SSOHandler-rq0OGrpX.cjs +236 -0
  12. package/dist/chunks/SSOHandler-rq0OGrpX.cjs.map +1 -0
  13. package/dist/chunks/{SearchBoxContext-CY4tAQcg.js → SearchBoxContext-BxtHF9BO.js} +2 -2
  14. package/dist/chunks/{SearchBoxContext-CY4tAQcg.js.map → SearchBoxContext-BxtHF9BO.js.map} +1 -1
  15. package/dist/chunks/SearchBoxContext-Cpr9xa1S.cjs +2 -0
  16. package/dist/chunks/{SearchBoxContext-DDBY44Wr.cjs.map → SearchBoxContext-Cpr9xa1S.cjs.map} +1 -1
  17. package/dist/chunks/TabContainer-B7-6AQXV.js +254 -0
  18. package/dist/chunks/TabContainer-B7-6AQXV.js.map +1 -0
  19. package/dist/chunks/TabContainer-Dx2PVShz.cjs +36 -0
  20. package/dist/chunks/TabContainer-Dx2PVShz.cjs.map +1 -0
  21. package/dist/chunks/_commonjsHelpers-DKOUU3wS.cjs +2 -0
  22. package/dist/chunks/_commonjsHelpers-DKOUU3wS.cjs.map +1 -0
  23. package/dist/chunks/_commonjsHelpers-DaMA6jEr.js +9 -0
  24. package/dist/chunks/_commonjsHelpers-DaMA6jEr.js.map +1 -0
  25. package/dist/chunks/apiUtils-C45AWfu-.js +957 -0
  26. package/dist/chunks/apiUtils-C45AWfu-.js.map +1 -0
  27. package/dist/chunks/apiUtils-Cbg6NQLv.cjs +4 -0
  28. package/dist/chunks/apiUtils-Cbg6NQLv.cjs.map +1 -0
  29. package/dist/chunks/codeStore-BGLhSpAM.cjs +2 -0
  30. package/dist/chunks/{codeStore-KPL92rcv.cjs.map → codeStore-BGLhSpAM.cjs.map} +1 -1
  31. package/dist/chunks/{codeStore-IIp25egq.js → codeStore-BzT5wSd9.js} +2 -2
  32. package/dist/chunks/{codeStore-IIp25egq.js.map → codeStore-BzT5wSd9.js.map} +1 -1
  33. package/dist/chunks/commonUtils-BH6QwGUb.cjs +2 -0
  34. package/dist/chunks/commonUtils-BH6QwGUb.cjs.map +1 -0
  35. package/dist/chunks/{commonUtils-Cvx6_eK2.js → commonUtils-Bb16Yqjk.js} +24 -25
  36. package/dist/chunks/commonUtils-Bb16Yqjk.js.map +1 -0
  37. package/dist/chunks/envUtils-C9Gf5aek.js.map +1 -1
  38. package/dist/chunks/envUtils-CduTHoHu.cjs.map +1 -1
  39. package/dist/chunks/favoriteStore-3YceyayF.cjs +2 -0
  40. package/dist/chunks/favoriteStore-3YceyayF.cjs.map +1 -0
  41. package/dist/chunks/favoriteStore-C9utQ6sm.js +112 -0
  42. package/dist/chunks/favoriteStore-C9utQ6sm.js.map +1 -0
  43. package/dist/chunks/{popupStore-D8RI04bU.js → popupStore-DmFbkkjd.js} +19 -18
  44. package/dist/chunks/popupStore-DmFbkkjd.js.map +1 -0
  45. package/dist/chunks/popupStore-DnWLaQ70.cjs +2 -0
  46. package/dist/chunks/popupStore-DnWLaQ70.cjs.map +1 -0
  47. package/dist/chunks/usePopup-C8FrbrDD.cjs +2 -0
  48. package/dist/chunks/{UtilsContext-JSHHfnWl.js.map → usePopup-C8FrbrDD.cjs.map} +1 -1
  49. package/dist/chunks/{UtilsContext-JSHHfnWl.js → usePopup-pfh-ajfP.js} +82 -82
  50. package/dist/chunks/usePopup-pfh-ajfP.js.map +1 -0
  51. package/dist/components/common/BwgDetail.d.ts +5 -0
  52. package/dist/components/common/BwgDetail.d.ts.map +1 -0
  53. package/dist/components/common/BwgDrawer.d.ts.map +1 -1
  54. package/dist/components/common/BwgEditor.d.ts +7 -0
  55. package/dist/components/common/BwgEditor.d.ts.map +1 -0
  56. package/dist/components/common/BwgView.d.ts.map +1 -1
  57. package/dist/components/common/index.cjs +1 -1
  58. package/dist/components/common/index.d.ts +3 -1
  59. package/dist/components/common/index.d.ts.map +1 -1
  60. package/dist/components/common/index.js +27 -25
  61. package/dist/components/core/BwgDatePicker.d.ts +1 -1
  62. package/dist/components/core/BwgDatePicker.d.ts.map +1 -1
  63. package/dist/components/core/BwgRangePicker.d.ts +1 -1
  64. package/dist/components/core/BwgRangePicker.d.ts.map +1 -1
  65. package/dist/components/core/BwgUploader.d.ts.map +1 -1
  66. package/dist/components/core/index.cjs +1 -1
  67. package/dist/components/core/index.js +1 -1
  68. package/dist/components/layout/ErrorBound.d.ts +29 -0
  69. package/dist/components/layout/ErrorBound.d.ts.map +1 -0
  70. package/dist/components/layout/TabContainer.d.ts +9 -0
  71. package/dist/components/layout/TabContainer.d.ts.map +1 -0
  72. package/dist/components/layout/index.cjs +1 -1
  73. package/dist/components/layout/index.d.ts +3 -1
  74. package/dist/components/layout/index.d.ts.map +1 -1
  75. package/dist/components/layout/index.js +6 -4
  76. package/dist/index.cjs +1 -1
  77. package/dist/index.js +304 -299
  78. package/dist/provider/index.cjs +1 -1
  79. package/dist/provider/index.js +2 -2
  80. package/dist/stores/favoriteStore.d.ts.map +1 -1
  81. package/dist/stores/index.cjs +1 -1
  82. package/dist/stores/index.cjs.map +1 -1
  83. package/dist/stores/index.d.ts +3 -1
  84. package/dist/stores/index.d.ts.map +1 -1
  85. package/dist/stores/index.js +18 -16
  86. package/dist/stores/index.js.map +1 -1
  87. package/dist/stores/loadingStore.d.ts +9 -0
  88. package/dist/stores/loadingStore.d.ts.map +1 -0
  89. package/dist/stores/menuViewStore.d.ts +28 -3
  90. package/dist/stores/menuViewStore.d.ts.map +1 -1
  91. package/dist/stores/popupStore.d.ts.map +1 -1
  92. package/dist/styles/assets/images/header/icon/ico-bell.svg +3 -3
  93. package/dist/styles/assets/images/header/icon/ico-logout.svg +10 -10
  94. package/dist/styles/assets/images/header/icon/ico-setting.svg +4 -4
  95. package/dist/styles/assets/images/header/icon/ico-sidebar-arrow.svg +3 -3
  96. package/dist/utils/apiUtils.d.ts +3 -2
  97. package/dist/utils/apiUtils.d.ts.map +1 -1
  98. package/dist/utils/index.cjs +1 -1
  99. package/dist/utils/index.js +3 -3
  100. package/dist/utils/notificationUtils.d.ts +0 -1
  101. package/dist/utils/notificationUtils.d.ts.map +1 -1
  102. package/package.json +6 -7
  103. package/dist/chunks/BwgLargeUploader-B5EtYKUz.js.map +0 -1
  104. package/dist/chunks/BwgLargeUploader-BPJcShgF.cjs +0 -3
  105. package/dist/chunks/BwgLargeUploader-BPJcShgF.cjs.map +0 -1
  106. package/dist/chunks/FileUtils-BweAWoJt.cjs +0 -2
  107. package/dist/chunks/PublicLayout-3v46YZdi.cjs +0 -36
  108. package/dist/chunks/PublicLayout-3v46YZdi.cjs.map +0 -1
  109. package/dist/chunks/PublicLayout-B4wGo0ut.js +0 -139
  110. package/dist/chunks/PublicLayout-B4wGo0ut.js.map +0 -1
  111. package/dist/chunks/SSOHandler-C72Do3RD.js +0 -15717
  112. package/dist/chunks/SSOHandler-C72Do3RD.js.map +0 -1
  113. package/dist/chunks/SSOHandler-ColywAGZ.cjs +0 -184
  114. package/dist/chunks/SSOHandler-ColywAGZ.cjs.map +0 -1
  115. package/dist/chunks/SearchBoxContext-DDBY44Wr.cjs +0 -2
  116. package/dist/chunks/UtilsContext-C4tlOndT.cjs +0 -2
  117. package/dist/chunks/UtilsContext-C4tlOndT.cjs.map +0 -1
  118. package/dist/chunks/_commonjsHelpers-C6fGbg64.js +0 -7
  119. package/dist/chunks/_commonjsHelpers-C6fGbg64.js.map +0 -1
  120. package/dist/chunks/_commonjsHelpers-DwGv2jUC.cjs +0 -2
  121. package/dist/chunks/_commonjsHelpers-DwGv2jUC.cjs.map +0 -1
  122. package/dist/chunks/codeStore-KPL92rcv.cjs +0 -2
  123. package/dist/chunks/commonUtils-Cvx6_eK2.js.map +0 -1
  124. package/dist/chunks/commonUtils-DaFg0y7C.cjs +0 -2
  125. package/dist/chunks/commonUtils-DaFg0y7C.cjs.map +0 -1
  126. package/dist/chunks/menuViewStore-DuS0VmkB.cjs +0 -3
  127. package/dist/chunks/menuViewStore-DuS0VmkB.cjs.map +0 -1
  128. package/dist/chunks/menuViewStore-OKcSQq-s.js +0 -343
  129. package/dist/chunks/menuViewStore-OKcSQq-s.js.map +0 -1
  130. package/dist/chunks/popupStore-BEoWGajT.cjs +0 -2
  131. package/dist/chunks/popupStore-BEoWGajT.cjs.map +0 -1
  132. package/dist/chunks/popupStore-D8RI04bU.js.map +0 -1
  133. package/dist/chunks/serviceConfig-9dHegQIK.cjs +0 -3
  134. package/dist/chunks/serviceConfig-9dHegQIK.cjs.map +0 -1
  135. package/dist/chunks/serviceConfig-Dhe7neaj.js +0 -709
  136. package/dist/chunks/serviceConfig-Dhe7neaj.js.map +0 -1
  137. package/scripts/gen-component-registry.js +0 -138
@@ -1 +0,0 @@
1
- {"version":3,"file":"menuViewStore-DuS0VmkB.cjs","sources":["../../src/stores/favoriteStore.ts","../../src/stores/menuModelStore.ts","../../src/stores/menuViewStore.ts"],"sourcesContent":["import { create } from \"zustand\";\r\nimport { callService } from \"../utils/apiUtils\";\r\nimport { getServiceCode } from \"../utils/serviceConfig\";\r\nimport type { MenuItem } from \"./menuModelStore\";\r\nimport { isLocal } from \"@/utils\";\r\n\r\n// 즐겨찾기 메뉴 타입 정의\r\nexport interface FavoriteMenuItem extends MenuItem {\r\n addedAt: string; // 즐겨찾기 추가 시간\r\n userId: string; // 사용자 ID\r\n}\r\n\r\n// 즐겨찾기 스토어 타입 정의\r\nexport interface FavoriteStore {\r\n favorites: FavoriteMenuItem[];\r\n isLoading: boolean;\r\n error: string | null;\r\n\r\n // 즐겨찾기 메뉴 가져오기\r\n fetchFavorites: (params: { crprCd: string; userId: string }) => Promise<void>;\r\n\r\n // 즐겨찾기 추가\r\n addFavorite: (menuItem: MenuItem, userId: string) => Promise<void>;\r\n\r\n // 즐겨찾기 제거\r\n removeFavorite: (menuId: string, userId: string) => Promise<void>;\r\n\r\n // 즐겨찾기 여부 확인\r\n isFavorite: (menuId: string) => boolean;\r\n\r\n // 즐겨찾기 초기화\r\n clearFavorites: () => void;\r\n}\r\n\r\n// 즐겨찾기 스토어 생성\r\nexport const useFavoriteStore = create<FavoriteStore>((set, get) => ({\r\n favorites: [],\r\n isLoading: false,\r\n error: null,\r\n\r\n // 즐겨찾기 메뉴 가져오기\r\n fetchFavorites: async ({ crprCd, userId }) => {\r\n console.log(\"즐겨찾기 메뉴 요청:\", { crprCd, userId });\r\n set({ isLoading: true, error: null });\r\n\r\n try {\r\n // 서버에서 즐겨찾기 메뉴 가져오기\r\n const data = await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n crprCd,\r\n userId,\r\n });\r\n\r\n let favoritesList: FavoriteMenuItem[] = [];\r\n\r\n if (data?.favorites && Array.isArray(data.favorites)) {\r\n favoritesList = data.favorites;\r\n } else if (Array.isArray(data)) {\r\n favoritesList = data;\r\n } else {\r\n console.warn(\"즐겨찾기 데이터가 비어있거나 예상과 다른 구조입니다.\");\r\n favoritesList = [];\r\n }\r\n\r\n console.log(\"즐겨찾기 메뉴 로드 완료:\", favoritesList);\r\n\r\n // 개발 모드에서 테스트용 즐겨찾기 데이터 추가\r\n if (isLocal && favoritesList.length === 0) {\r\n const testFavorites: FavoriteMenuItem[] = [\r\n {\r\n crprCd: \"100\",\r\n menuGbCd: \"CMPRGRP\",\r\n menuPrntId: \"FAV001\",\r\n menuId: \"FAV_TEST001\",\r\n menuNm: \"API 테스트\",\r\n scrnId: \"TEST001\",\r\n menuNo: 1,\r\n scrnPath: \"/dev/ApiTest\",\r\n menuLvl: 3,\r\n rootMenu: \"FAV001\",\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n },\r\n {\r\n crprCd: \"100\",\r\n menuGbCd: \"CMPRGRP\",\r\n menuPrntId: \"FAV001\",\r\n menuId: \"FAV_TEST002\",\r\n menuNm: \"프로젝트 개요\",\r\n scrnId: \"DOCS001\",\r\n menuNo: 2,\r\n scrnPath: \"/docs/ProjectOverview\",\r\n menuLvl: 3,\r\n rootMenu: \"FAV001\",\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n },\r\n ];\r\n set({ favorites: testFavorites, isLoading: false, error: null });\r\n console.log(\"개발 모드: 테스트용 즐겨찾기 데이터 추가\");\r\n } else {\r\n set({ favorites: favoritesList, isLoading: false, error: null });\r\n }\r\n } catch (error) {\r\n console.error(\"즐겨찾기 메뉴 로드 실패:\", error);\r\n set({\r\n error: error instanceof Error ? error.message : \"즐겨찾기 로드 실패\",\r\n isLoading: false,\r\n });\r\n }\r\n },\r\n\r\n // 즐겨찾기 추가\r\n addFavorite: async (menuItem: MenuItem, userId: string) => {\r\n const { favorites } = get();\r\n\r\n // 이미 즐겨찾기에 있는지 확인\r\n if (favorites.some((fav) => fav.menuId === menuItem.menuId)) {\r\n console.log(\"이미 즐겨찾기에 추가된 메뉴입니다:\", menuItem.menuNm);\r\n return;\r\n }\r\n\r\n try {\r\n // 서버에 즐겨찾기 추가 요청\r\n await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n action: \"add\",\r\n crprCd: menuItem.crprCd,\r\n userId,\r\n menuId: menuItem.menuId,\r\n menuNm: menuItem.menuNm,\r\n scrnPath: menuItem.scrnPath,\r\n });\r\n\r\n // 로컬 상태 업데이트\r\n const newFavorite: FavoriteMenuItem = {\r\n ...menuItem,\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n };\r\n\r\n set({ favorites: [...favorites, newFavorite] });\r\n console.log(\"즐겨찾기 추가 완료:\", menuItem.menuNm);\r\n } catch (error) {\r\n console.error(\"즐겨찾기 추가 실패:\", error);\r\n throw error;\r\n }\r\n },\r\n\r\n // 즐겨찾기 제거\r\n removeFavorite: async (menuId: string, userId: string) => {\r\n const { favorites } = get();\r\n\r\n try {\r\n // 서버에 즐겨찾기 제거 요청\r\n await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n action: \"remove\",\r\n crprCd: \"100\", // 기본값\r\n userId,\r\n menuId,\r\n });\r\n\r\n // 로컬 상태 업데이트\r\n const updatedFavorites = favorites.filter((fav) => fav.menuId !== menuId);\r\n set({ favorites: updatedFavorites });\r\n console.log(\"즐겨찾기 제거 완료:\", menuId);\r\n } catch (error) {\r\n console.error(\"즐겨찾기 제거 실패:\", error);\r\n throw error;\r\n }\r\n },\r\n\r\n // 즐겨찾기 여부 확인\r\n isFavorite: (menuId: string) => {\r\n const { favorites } = get();\r\n return favorites.some((fav) => fav.menuId === menuId);\r\n },\r\n\r\n // 즐겨찾기 초기화\r\n clearFavorites: () => {\r\n set({ favorites: [], isLoading: false, error: null });\r\n },\r\n}));\r\n","import { create } from \"zustand\";\r\n// 필요에 맞게 경로 조정\r\nimport { callService } from \"@/utils/apiUtils\";\r\nimport { getServiceCode } from \"@/utils/serviceConfig\";\r\n\r\n/* ──── Constants ──── */\r\nconst MENU_CONSTANTS = {\r\n DEFAULT_ACTIVE_MENU: \"1\",\r\n DEFAULT_PRNT_GBCD: 1,\r\n COMPANY_CODE: \"100\",\r\n MENU_PARENT_ROOT: \"-\",\r\n MENU_TYPE: { MAIN: \"CMPRGRM\", SUB: \"CMPRGRS\", PROGRAM: \"CMPRGRP\" } as const,\r\n} as const;\r\n\r\n/* ──── Types (이 파일 전용) ──── */\r\nexport interface MenuItem {\r\n crprCd: string;\r\n menuGbCd: string;\r\n menuPrntId: string;\r\n menuId: string;\r\n menuNm: string;\r\n menuNo?: number;\r\n scrnId?: string;\r\n scrnPath?: string;\r\n prsnInfoYn?: \"Y\" | \"N\";\r\n rootMenu: string;\r\n iconCd?: string;\r\n children?: MenuItem[];\r\n}\r\n\r\nexport type FetchMenuParams = {\r\n crprCd: string;\r\n userId: string;\r\n prntGbcd: number;\r\n};\r\n\r\nexport interface MenuApiResponse {\r\n menus?: MenuItem[];\r\n [k: string]: any;\r\n}\r\n\r\n/* 런타임 타입가드 */\r\nconst isMenuItem = (v: any): v is MenuItem =>\r\n v &&\r\n typeof v === \"object\" &&\r\n typeof v.menuId === \"string\" &&\r\n typeof v.menuNm === \"string\" &&\r\n typeof v.crprCd === \"string\";\r\n\r\nconst isMenuItemArray = (v: any): v is MenuItem[] =>\r\n Array.isArray(v) && v.every(isMenuItem);\r\n\r\n/* ──── State Shape ──── */\r\ntype MenuModelState = {\r\n // 📊 State (상태)\r\n // 계층형 메뉴 트리 구조 (부모-자식 관계)\r\n menuList: MenuItem[];\r\n // 평면화된 메뉴 리스트 (검색/조회용)\r\n flatMenuList: MenuItem[];\r\n // 메뉴 데이터 로딩 상태\r\n isLoading: boolean;\r\n // 에러 메시지\r\n error: string | null;\r\n // 마지막 조회 파라미터 (중복 요청 방지)\r\n _lastFetchParams: FetchMenuParams | null;\r\n\r\n // 🔧 Actions (액션 함수들)\r\n // 서버에서 메뉴 데이터 조회\r\n fetchMenu: (p: FetchMenuParams) => Promise<void>;\r\n // 메뉴 데이터 초기화\r\n clearMenu: () => void;\r\n // 메뉴 ID로 특정 메뉴 찾기\r\n findMenuById: (menuId: string) => MenuItem | null;\r\n};\r\n\r\n/* ──── Local Memoization Cache ──── */\r\nlet _lastFlat: MenuItem[] = [];\r\nlet _cachedTree: MenuItem[] = [];\r\n\r\n/* ──── Helpers ──── */\r\nconst parseMenuResponse = (data: unknown): MenuItem[] => {\r\n if (data && typeof data === \"object\") {\r\n const r = data as MenuApiResponse;\r\n if (r.menus && isMenuItemArray(r.menus)) return r.menus;\r\n if (isMenuItemArray(data)) return data;\r\n }\r\n console.warn(\"⚠️ 메뉴 응답이 비어있거나 예상과 다릅니다.\");\r\n return [];\r\n};\r\n\r\nconst sameParams = (a: FetchMenuParams, b: FetchMenuParams | null) =>\r\n !!b &&\r\n a.crprCd === b.crprCd &&\r\n a.userId === b.userId &&\r\n (a.prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD) ===\r\n (b.prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD);\r\n\r\nconst buildHierarchy = (flat: MenuItem[]): MenuItem[] => {\r\n if (\r\n _lastFlat.length === flat.length &&\r\n _lastFlat.every(\r\n (x, i) =>\r\n x.menuId === flat[i]?.menuId && x.menuPrntId === flat[i]?.menuPrntId\r\n )\r\n )\r\n return _cachedTree;\r\n\r\n if (!flat.length) return [];\r\n\r\n const map = new Map<string, MenuItem>();\r\n const roots: MenuItem[] = [];\r\n\r\n flat.forEach((m) => m?.menuId && map.set(m.menuId, { ...m, children: [] }));\r\n flat.forEach((m) => {\r\n const cur = map.get(m.menuId);\r\n if (!cur) return;\r\n if (m.menuPrntId && m.menuPrntId !== \"\" && m.menuPrntId !== \"-\") {\r\n const p = map.get(m.menuPrntId);\r\n p?.children?.push(cur);\r\n } else {\r\n roots.push(cur);\r\n }\r\n });\r\n\r\n const sortRec = (arr: MenuItem[]): MenuItem[] =>\r\n arr\r\n .sort((a, b) => (a?.menuNo ?? 0) - (b?.menuNo ?? 0))\r\n .map((x) => ({\r\n ...x,\r\n children:\r\n x.children && x.children.length ? sortRec(x.children) : undefined,\r\n }));\r\n\r\n const out = sortRec(roots);\r\n _lastFlat = [...flat];\r\n _cachedTree = out;\r\n return out;\r\n};\r\n\r\n/* ──── Store ──── */\r\nexport const useMenuModelStore = create<MenuModelState>((set, get) => ({\r\n // 📊 초기 상태값\r\n menuList: [],\r\n flatMenuList: [],\r\n isLoading: false,\r\n error: null,\r\n _lastFetchParams: null,\r\n\r\n // 🔧 메뉴 모델 조회\r\n // 서버에서 사용자별 메뉴 권한 데이터를 가져와서 트리/플랫 구조로 저장\r\n fetchMenu: async ({ crprCd, userId, prntGbcd }: FetchMenuParams) => {\r\n const p = {\r\n crprCd,\r\n userId,\r\n prntGbcd: prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD,\r\n };\r\n // 중복 요청 방지\r\n if (sameParams(p, get()._lastFetchParams)) {\r\n console.log(\"✅ 중복 fetch 차단\", p);\r\n return;\r\n }\r\n set({ isLoading: true, error: null, _lastFetchParams: p });\r\n try {\r\n // API 호출하여 메뉴 데이터 가져오기\r\n const data = await callService(getServiceCode(\"AUTH_MENU\"), p);\r\n const flat = parseMenuResponse(data); // 응답 데이터 파싱\r\n const tree = buildHierarchy(flat); // 계층 구조 생성\r\n set({\r\n flatMenuList: flat, // 평면 리스트 저장\r\n menuList: tree, // 트리 구조 저장\r\n isLoading: false,\r\n error: null,\r\n });\r\n } catch (e: any) {\r\n set({ isLoading: false, error: e?.message ?? \"메뉴 로드 실패\" });\r\n }\r\n },\r\n\r\n // 🔧 메뉴 모델 초기화\r\n // 로그아웃 시나 사용자 변경 시 메뉴 모델 클리어\r\n clearMenu: () => {\r\n set({\r\n menuList: [],\r\n flatMenuList: [],\r\n error: null,\r\n _lastFetchParams: null,\r\n });\r\n },\r\n\r\n // 🔧 메뉴 ID로 메뉴 아이템 찾기\r\n // URL 파라미터나 프로그래밍 방식으로 특정 메뉴를 찾을 때 사용\r\n findMenuById: (menuId: string) => {\r\n const { flatMenuList } = get();\r\n return flatMenuList.find((m) => m.menuId === menuId) ?? null;\r\n },\r\n}));\r\n","import { create } from \"zustand\";\r\nimport React from \"react\";\r\nimport { MenuItem, useMenuModelStore } from \"./menuModelStore\";\r\nimport { message } from \"antd\";\r\n\r\n/* ──── Constants (UI 측에도 독립적으로 존재) ──── */\r\nconst MENU_CONSTANTS = {\r\n DEFAULT_ACTIVE_MENU: \"1\",\r\n MAX_TABS: 15,\r\n} as const;\r\n\r\n/* ──── Types (이 파일 전용) ──── */\r\nexport interface TabItem {\r\n key: string; // menuId\r\n label: string; // menuNm\r\n gubun: \"M\" | \"C\"; // menuId or componentPath\r\n menuItem: MenuItem;\r\n\r\n closable: boolean;\r\n}\r\n\r\n/* ──── State Shape ──── */\r\ntype MenuViewState = {\r\n // 📊 UI State (화면 상태)\r\n // 현재 활성화된 메뉴 ID\r\n activeMenuId: string | undefined | null;\r\n // 현재 활성화된 메뉴 정보\r\n activeMenuItem: MenuItem | null;\r\n // 열린 탭 목록\r\n tabs: TabItem[];\r\n // 사이드바 접힘/펼침 상태\r\n sidebarCollapsed: boolean;\r\n // 최대 탭 개수\r\n maxTabs: number;\r\n tabProtectFlag: Record<string, boolean>;\r\n // 탭 파라미터\r\n tabParams: Record<string, Record<string, any>>;\r\n // 컴포넌트 라벨 맵\r\n componentLabelMap: Record<string, string>;\r\n\r\n /* 🛠 UI Actions (UI 액션 함수들) */\r\n // 메뉴 아이템으로 탭 추가\r\n openTabFromMenu: (menuItem: MenuItem, params?: Record<string, any>) => void;\r\n // 메뉴 ID로 탭 추가 (URL 파라미터 처리용)\r\n openTabByMenuId: (menuId: string, params?: Record<string, any>) => void;\r\n // 컴포넌트 ID로 탭 추가\r\n openTabByComponentId: (cpntId: string, params?: Record<string, any>) => void;\r\n // 활성 탭 변경\r\n focusTab: (tabKey: string) => void;\r\n // 탭 제거\r\n closeTab: (tabKey: string) => void;\r\n // 모든 탭 제거\r\n closeAllTabs: () => void;\r\n // 사이드바 토글\r\n toggleSidebar: () => void;\r\n // 탭 순서 변경\r\n reorderTabs: (keys: string[]) => void;\r\n // 개인정보 포함여부에 따른 탭 잠금 Flag 설정\r\n setProtectFlagForKey: (key: string) => void;\r\n // 개인정보 포함여부에 따른 탭 잠금 해제\r\n clearProtectFlagForKey: (key: string) => void;\r\n // 탭 파라미터 설정\r\n setTabParams: (key: string, params: Record<string, any>) => void;\r\n //컴포넌트 라벨 맵 설정\r\n setComponentLabelMap: (map: Record<string, string>, merge?: boolean) => void;\r\n};\r\n\r\n/* ──── Store ──── */\r\nexport const useMenuViewStore = create<MenuViewState>((set, get) => ({\r\n // 📊 초기 상태값\r\n activeMenuId: null,\r\n activeMenuItem: null,\r\n tabs: [],\r\n sidebarCollapsed: false,\r\n maxTabs: MENU_CONSTANTS.MAX_TABS,\r\n tabProtectFlag: {},\r\n tabParams: {},\r\n componentLabelMap: {},\r\n // 🔧 탭 추가 (메뉴 아이템 객체로)\r\n // 사이드바에서 메뉴 클릭 시 호출되는 메인 함수\r\n openTabFromMenu: (menuItem, params) => {\r\n const { tabs, activeMenuId } = get();\r\n const exists = tabs.find((t) => t.key === menuItem.menuId);\r\n\r\n // 새 탭 생성\r\n if (!exists) {\r\n // 2. 최대 탭 개수 확인\r\n if (tabs.length > MENU_CONSTANTS.MAX_TABS) {\r\n console.warn(\"❌ 최대 탭 개수를 초과했습니다.\");\r\n message.warning(\r\n `최대 ${MENU_CONSTANTS.MAX_TABS}개의 탭만 열 수 있습니다.\\n기존 탭을 닫고 다시 시도해주세요.`\r\n );\r\n return;\r\n }\r\n const newTab: TabItem = {\r\n key: menuItem.menuId,\r\n label: menuItem.menuNm,\r\n gubun: \"M\",\r\n menuItem: menuItem as MenuItem,\r\n closable: true,\r\n };\r\n set({\r\n tabs: [...tabs, newTab], // 탭 목록에 추가\r\n activeMenuId: menuItem.menuId, // 새 탭을 활성화\r\n activeMenuItem: menuItem, // 현재 프로그램으로 설정\r\n });\r\n get().setTabParams(menuItem.menuId, params || {});\r\n console.log(\"✅ 새 탭 추가 - activeMenuItem:\", menuItem);\r\n\r\n // 개인정보 메뉴만 Protect\r\n if (menuItem?.prsnInfoYn === \"Y\") {\r\n get().setProtectFlagForKey(menuItem.menuId);\r\n }\r\n } else if (activeMenuId !== menuItem.menuId) {\r\n // 이미 존재하는 탭이면 활성화만\r\n set({ activeMenuId: menuItem.menuId, activeMenuItem: menuItem });\r\n console.log(\"✅ 기존 탭 활성화 - activeMenuItem:\", menuItem);\r\n get().setTabParams(menuItem.menuId, params || {});\r\n // 개인정보 메뉴만 Protect\r\n if (menuItem?.prsnInfoYn === \"Y\") {\r\n get().setProtectFlagForKey(menuItem.menuId);\r\n }\r\n } else {\r\n console.warn(\"❌ 유효하지 않은 메뉴정보\", menuItem.menuId);\r\n message.warning(\"유효하지 않은 메뉴정보입니다.\");\r\n }\r\n },\r\n // 🔧 탭 추가 (메뉴 ID로)\r\n // URL 파라미터로 메뉴 열기 시 사용 (예: ?menuId=CM000301)\r\n openTabByMenuId: (menuId, params) => {\r\n const target = useMenuModelStore.getState().findMenuById(menuId);\r\n if (!target) {\r\n console.warn(\"❌ 메뉴 ID를 찾을 수 없음:\", menuId);\r\n message.warning(\"메뉴 ID를 찾을 수 없습니다.\");\r\n } else {\r\n get().openTabFromMenu(target, params); // 찾은 메뉴로 탭 추가\r\n }\r\n },\r\n openTabByComponentId: (cpntId, params) => {\r\n const { tabs, activeMenuId } = get();\r\n const exists = tabs.find((t) => t.key === cpntId);\r\n const cpntNm = get().componentLabelMap[cpntId] ?? cpntId;\r\n\r\n const menuItem = {\r\n crprCd: \"\",\r\n menuNm: cpntNm,\r\n menuId: cpntId,\r\n scrnId: cpntId,\r\n scrnPath: cpntId,\r\n menuNo: undefined,\r\n menuLvl: 0,\r\n prsnInfoYn: \"N\" as const,\r\n rootMenu: \"\",\r\n iconCd: \"\",\r\n menuGbCd: \"\",\r\n menuPrntId: \"\",\r\n children: [],\r\n };\r\n // 새 탭 생성\r\n if (!exists) {\r\n const newTab: TabItem = {\r\n key: cpntId,\r\n gubun: \"C\",\r\n label: cpntNm,\r\n menuItem,\r\n closable: true,\r\n };\r\n\r\n set({\r\n tabs: [...tabs, newTab], // 탭 목록에 추가\r\n activeMenuId: cpntId, // 새 탭을 활성화\r\n activeMenuItem: menuItem, // 현재 프로그램으로 설정\r\n });\r\n get().setTabParams(cpntId, params || {});\r\n } else if (activeMenuId !== menuItem.menuId) {\r\n // 이미 존재하는 탭이면 활성화만\r\n set({ activeMenuId: menuItem.menuId, activeMenuItem: menuItem });\r\n get().setTabParams(menuItem.menuId, params || {});\r\n } else {\r\n console.warn(\"❌ 유효하지 않은 메뉴정보\", cpntId);\r\n message.warning(\"유효하지 않은 메뉴정보입니다.\");\r\n return;\r\n }\r\n },\r\n // 🔧 탭 제거\r\n // X 버튼 클릭 시 탭을 닫고 관련 상태도 정리\r\n closeTab: (tabKey) => {\r\n const { tabs, activeMenuId } = get();\r\n const removed = tabs.find((t) => t.key === tabKey);\r\n const nextTabs = tabs.filter((t) => t.key !== tabKey);\r\n\r\n // 닫힌 탭이 현재 활성 탭이면 다음 탭으로 이동\r\n let nextActive = activeMenuId;\r\n if (activeMenuId === tabKey) {\r\n const idx = tabs.findIndex((t) => t.key === tabKey);\r\n nextActive = nextTabs.length\r\n ? nextTabs[Math.min(idx, nextTabs.length - 1)]?.key ?? null\r\n : null;\r\n }\r\n\r\n set({\r\n tabs: nextTabs,\r\n });\r\n\r\n if (nextActive) get().focusTab(nextActive);\r\n },\r\n // 🔧 활성 탭 변경\r\n // 탭 헤더 클릭 시 해당 탭으로 전환\r\n focusTab: (tabKey) => {\r\n const { tabs } = get();\r\n const target = tabs.find((t) => t.key === tabKey);\r\n\r\n if (target) {\r\n if (target.menuItem.prsnInfoYn === \"Y\") {\r\n set({\r\n activeMenuId: tabKey,\r\n activeMenuItem: target.menuItem,\r\n });\r\n console.log(\r\n \"✅ 탭 포커스 (개인정보) - activeMenuItem:\",\r\n target.menuItem\r\n );\r\n get().setProtectFlagForKey(tabKey);\r\n } else {\r\n set({\r\n activeMenuId: tabKey,\r\n activeMenuItem: target.menuItem,\r\n });\r\n console.log(\"✅ 탭 포커스 (일반) - activeMenuItem:\", target.menuItem);\r\n get().clearProtectFlagForKey(tabKey);\r\n }\r\n } else {\r\n set({ activeMenuId: tabKey, activeMenuItem: null });\r\n console.warn(\"❌ 탭을 찾을 수 없음:\", tabKey);\r\n }\r\n },\r\n\r\n // 🔧 모든 탭 제거\r\n // 로그아웃이나 전체 초기화 시 사용\r\n closeAllTabs: () =>\r\n set({ tabs: [], activeMenuId: null, activeMenuItem: null }),\r\n\r\n // 🔧 사이드바 토글\r\n // 햄버거 메뉴 클릭 시 사이드바 접기/펼치기\r\n toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })),\r\n\r\n // useMenuViewStore.ts\r\n reorderTabs: (keys: string[]) =>\r\n set((state) => {\r\n const map = new Map(state.tabs.map((t) => [t.key, t]));\r\n return { tabs: keys.map((k) => map.get(k)!).filter(Boolean) };\r\n }),\r\n // 개인정보 포함여부에 따른 탭 잠금 Flag 설정\r\n setProtectFlagForKey: (key: string) =>\r\n set((s) => ({\r\n tabProtectFlag: { ...s.tabProtectFlag, [key]: true },\r\n })),\r\n // 개인정보 포함여부에 따른 탭 잠금 해제\r\n clearProtectFlagForKey: (key: string) =>\r\n set((s) => {\r\n const newFlags = { ...s.tabProtectFlag };\r\n delete newFlags[key];\r\n return { tabProtectFlag: newFlags };\r\n }),\r\n // 탭 파라미터 설정\r\n setTabParams: (key, params) =>\r\n set((state) => {\r\n const prev = state.tabParams[key] || {};\r\n const next = { ...(params || {}) }; // 새 객체 (불변 보장)\r\n\r\n // shallow equal이면 스킵(불필요 렌더 방지)\r\n const isShallowEqual =\r\n Object.keys(prev).length === Object.keys(next).length &&\r\n Object.keys(next).every((k) => prev[k] === next[k]);\r\n if (isShallowEqual) return state;\r\n\r\n return {\r\n tabParams: { ...state.tabParams, [key]: next },\r\n };\r\n }),\r\n // 컴포넌트 라벨 맵 설정\r\n setComponentLabelMap: (map: Record<string, string>, merge?: boolean) =>\r\n set({ componentLabelMap: map }),\r\n}));\r\n"],"names":["useFavoriteStore","create","set","get","crprCd","userId","data","callService","getServiceCode","favoritesList","isLocal","testFavorites","error","menuItem","favorites","fav","newFavorite","menuId","updatedFavorites","MENU_CONSTANTS","isMenuItem","v","isMenuItemArray","_lastFlat","_cachedTree","parseMenuResponse","r","sameParams","a","b","buildHierarchy","flat","x","i","map","roots","m","cur","sortRec","arr","out","useMenuModelStore","prntGbcd","p","tree","e","flatMenuList","useMenuViewStore","params","tabs","activeMenuId","t","message","newTab","target","cpntId","exists","cpntNm","tabKey","nextTabs","nextActive","idx","s","keys","state","k","key","newFlags","prev","next","merge"],"mappings":"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"}
@@ -1,343 +0,0 @@
1
- import { create as b } from "zustand";
2
- import { V as u, am as d } from "./serviceConfig-Dhe7neaj.js";
3
- import { i as P } from "./envUtils-C9Gf5aek.js";
4
- import { message as i } from "antd";
5
- const N = b((r, a) => ({
6
- favorites: [],
7
- isLoading: !1,
8
- error: null,
9
- // 즐겨찾기 메뉴 가져오기
10
- fetchFavorites: async ({ crprCd: e, userId: t }) => {
11
- console.log("즐겨찾기 메뉴 요청:", { crprCd: e, userId: t }), r({ isLoading: !0, error: null });
12
- try {
13
- const o = await u(d("AUTH_BMRK"), {
14
- crprCd: e,
15
- userId: t
16
- });
17
- let n = [];
18
- if (o?.favorites && Array.isArray(o.favorites) ? n = o.favorites : Array.isArray(o) ? n = o : (console.warn("즐겨찾기 데이터가 비어있거나 예상과 다른 구조입니다."), n = []), console.log("즐겨찾기 메뉴 로드 완료:", n), P && n.length === 0) {
19
- const s = [
20
- {
21
- crprCd: "100",
22
- menuGbCd: "CMPRGRP",
23
- menuPrntId: "FAV001",
24
- menuId: "FAV_TEST001",
25
- menuNm: "API 테스트",
26
- scrnId: "TEST001",
27
- menuNo: 1,
28
- scrnPath: "/dev/ApiTest",
29
- menuLvl: 3,
30
- rootMenu: "FAV001",
31
- addedAt: (/* @__PURE__ */ new Date()).toISOString(),
32
- userId: t
33
- },
34
- {
35
- crprCd: "100",
36
- menuGbCd: "CMPRGRP",
37
- menuPrntId: "FAV001",
38
- menuId: "FAV_TEST002",
39
- menuNm: "프로젝트 개요",
40
- scrnId: "DOCS001",
41
- menuNo: 2,
42
- scrnPath: "/docs/ProjectOverview",
43
- menuLvl: 3,
44
- rootMenu: "FAV001",
45
- addedAt: (/* @__PURE__ */ new Date()).toISOString(),
46
- userId: t
47
- }
48
- ];
49
- r({ favorites: s, isLoading: !1, error: null }), console.log("개발 모드: 테스트용 즐겨찾기 데이터 추가");
50
- } else
51
- r({ favorites: n, isLoading: !1, error: null });
52
- } catch (o) {
53
- console.error("즐겨찾기 메뉴 로드 실패:", o), r({
54
- error: o instanceof Error ? o.message : "즐겨찾기 로드 실패",
55
- isLoading: !1
56
- });
57
- }
58
- },
59
- // 즐겨찾기 추가
60
- addFavorite: async (e, t) => {
61
- const { favorites: o } = a();
62
- if (o.some((n) => n.menuId === e.menuId)) {
63
- console.log("이미 즐겨찾기에 추가된 메뉴입니다:", e.menuNm);
64
- return;
65
- }
66
- try {
67
- await u(d("AUTH_BMRK"), {
68
- action: "add",
69
- crprCd: e.crprCd,
70
- userId: t,
71
- menuId: e.menuId,
72
- menuNm: e.menuNm,
73
- scrnPath: e.scrnPath
74
- });
75
- const n = {
76
- ...e,
77
- addedAt: (/* @__PURE__ */ new Date()).toISOString(),
78
- userId: t
79
- };
80
- r({ favorites: [...o, n] }), console.log("즐겨찾기 추가 완료:", e.menuNm);
81
- } catch (n) {
82
- throw console.error("즐겨찾기 추가 실패:", n), n;
83
- }
84
- },
85
- // 즐겨찾기 제거
86
- removeFavorite: async (e, t) => {
87
- const { favorites: o } = a();
88
- try {
89
- await u(d("AUTH_BMRK"), {
90
- action: "remove",
91
- crprCd: "100",
92
- // 기본값
93
- userId: t,
94
- menuId: e
95
- });
96
- const n = o.filter((s) => s.menuId !== e);
97
- r({ favorites: n }), console.log("즐겨찾기 제거 완료:", e);
98
- } catch (n) {
99
- throw console.error("즐겨찾기 제거 실패:", n), n;
100
- }
101
- },
102
- // 즐겨찾기 여부 확인
103
- isFavorite: (e) => {
104
- const { favorites: t } = a();
105
- return t.some((o) => o.menuId === e);
106
- },
107
- // 즐겨찾기 초기화
108
- clearFavorites: () => {
109
- r({ favorites: [], isLoading: !1, error: null });
110
- }
111
- })), v = {
112
- DEFAULT_PRNT_GBCD: 1
113
- }, p = (r) => r && typeof r == "object" && typeof r.menuId == "string" && typeof r.menuNm == "string" && typeof r.crprCd == "string", g = (r) => Array.isArray(r) && r.every(p);
114
- let f = [], I = [];
115
- const T = (r) => {
116
- if (r && typeof r == "object") {
117
- const a = r;
118
- if (a.menus && g(a.menus)) return a.menus;
119
- if (g(r)) return r;
120
- }
121
- return console.warn("⚠️ 메뉴 응답이 비어있거나 예상과 다릅니다."), [];
122
- }, h = (r, a) => !!a && r.crprCd === a.crprCd && r.userId === a.userId && (r.prntGbcd ?? v.DEFAULT_PRNT_GBCD) === (a.prntGbcd ?? v.DEFAULT_PRNT_GBCD), F = (r) => {
123
- if (f.length === r.length && f.every(
124
- (n, s) => n.menuId === r[s]?.menuId && n.menuPrntId === r[s]?.menuPrntId
125
- ))
126
- return I;
127
- if (!r.length) return [];
128
- const a = /* @__PURE__ */ new Map(), e = [];
129
- r.forEach((n) => n?.menuId && a.set(n.menuId, { ...n, children: [] })), r.forEach((n) => {
130
- const s = a.get(n.menuId);
131
- s && (n.menuPrntId && n.menuPrntId !== "" && n.menuPrntId !== "-" ? a.get(n.menuPrntId)?.children?.push(s) : e.push(s));
132
- });
133
- const t = (n) => n.sort((s, c) => (s?.menuNo ?? 0) - (c?.menuNo ?? 0)).map((s) => ({
134
- ...s,
135
- children: s.children && s.children.length ? t(s.children) : void 0
136
- })), o = t(e);
137
- return f = [...r], I = o, o;
138
- }, A = b((r, a) => ({
139
- // 📊 초기 상태값
140
- menuList: [],
141
- flatMenuList: [],
142
- isLoading: !1,
143
- error: null,
144
- _lastFetchParams: null,
145
- // 🔧 메뉴 모델 조회
146
- // 서버에서 사용자별 메뉴 권한 데이터를 가져와서 트리/플랫 구조로 저장
147
- fetchMenu: async ({ crprCd: e, userId: t, prntGbcd: o }) => {
148
- const n = {
149
- crprCd: e,
150
- userId: t,
151
- prntGbcd: o ?? v.DEFAULT_PRNT_GBCD
152
- };
153
- if (h(n, a()._lastFetchParams)) {
154
- console.log("✅ 중복 fetch 차단", n);
155
- return;
156
- }
157
- r({ isLoading: !0, error: null, _lastFetchParams: n });
158
- try {
159
- const s = await u(d("AUTH_MENU"), n), c = T(s), l = F(c);
160
- r({
161
- flatMenuList: c,
162
- // 평면 리스트 저장
163
- menuList: l,
164
- // 트리 구조 저장
165
- isLoading: !1,
166
- error: null
167
- });
168
- } catch (s) {
169
- r({ isLoading: !1, error: s?.message ?? "메뉴 로드 실패" });
170
- }
171
- },
172
- // 🔧 메뉴 모델 초기화
173
- // 로그아웃 시나 사용자 변경 시 메뉴 모델 클리어
174
- clearMenu: () => {
175
- r({
176
- menuList: [],
177
- flatMenuList: [],
178
- error: null,
179
- _lastFetchParams: null
180
- });
181
- },
182
- // 🔧 메뉴 ID로 메뉴 아이템 찾기
183
- // URL 파라미터나 프로그래밍 방식으로 특정 메뉴를 찾을 때 사용
184
- findMenuById: (e) => {
185
- const { flatMenuList: t } = a();
186
- return t.find((o) => o.menuId === e) ?? null;
187
- }
188
- })), M = {
189
- MAX_TABS: 15
190
- }, S = b((r, a) => ({
191
- // 📊 초기 상태값
192
- activeMenuId: null,
193
- activeMenuItem: null,
194
- tabs: [],
195
- sidebarCollapsed: !1,
196
- maxTabs: M.MAX_TABS,
197
- tabProtectFlag: {},
198
- tabParams: {},
199
- componentLabelMap: {},
200
- // 🔧 탭 추가 (메뉴 아이템 객체로)
201
- // 사이드바에서 메뉴 클릭 시 호출되는 메인 함수
202
- openTabFromMenu: (e, t) => {
203
- const { tabs: o, activeMenuId: n } = a();
204
- if (o.find((c) => c.key === e.menuId))
205
- n !== e.menuId ? (r({ activeMenuId: e.menuId, activeMenuItem: e }), console.log("✅ 기존 탭 활성화 - activeMenuItem:", e), a().setTabParams(e.menuId, t || {}), e?.prsnInfoYn === "Y" && a().setProtectFlagForKey(e.menuId)) : (console.warn("❌ 유효하지 않은 메뉴정보", e.menuId), i.warning("유효하지 않은 메뉴정보입니다."));
206
- else {
207
- if (o.length > M.MAX_TABS) {
208
- console.warn("❌ 최대 탭 개수를 초과했습니다."), i.warning(
209
- `최대 ${M.MAX_TABS}개의 탭만 열 수 있습니다.
210
- 기존 탭을 닫고 다시 시도해주세요.`
211
- );
212
- return;
213
- }
214
- const c = {
215
- key: e.menuId,
216
- label: e.menuNm,
217
- gubun: "M",
218
- menuItem: e,
219
- closable: !0
220
- };
221
- r({
222
- tabs: [...o, c],
223
- // 탭 목록에 추가
224
- activeMenuId: e.menuId,
225
- // 새 탭을 활성화
226
- activeMenuItem: e
227
- // 현재 프로그램으로 설정
228
- }), a().setTabParams(e.menuId, t || {}), console.log("✅ 새 탭 추가 - activeMenuItem:", e), e?.prsnInfoYn === "Y" && a().setProtectFlagForKey(e.menuId);
229
- }
230
- },
231
- // 🔧 탭 추가 (메뉴 ID로)
232
- // URL 파라미터로 메뉴 열기 시 사용 (예: ?menuId=CM000301)
233
- openTabByMenuId: (e, t) => {
234
- const o = A.getState().findMenuById(e);
235
- o ? a().openTabFromMenu(o, t) : (console.warn("❌ 메뉴 ID를 찾을 수 없음:", e), i.warning("메뉴 ID를 찾을 수 없습니다."));
236
- },
237
- openTabByComponentId: (e, t) => {
238
- const { tabs: o, activeMenuId: n } = a(), s = o.find((m) => m.key === e), c = a().componentLabelMap[e] ?? e, l = {
239
- crprCd: "",
240
- menuNm: c,
241
- menuId: e,
242
- scrnId: e,
243
- scrnPath: e,
244
- menuNo: void 0,
245
- menuLvl: 0,
246
- prsnInfoYn: "N",
247
- rootMenu: "",
248
- iconCd: "",
249
- menuGbCd: "",
250
- menuPrntId: "",
251
- children: []
252
- };
253
- if (s)
254
- if (n !== l.menuId)
255
- r({ activeMenuId: l.menuId, activeMenuItem: l }), a().setTabParams(l.menuId, t || {});
256
- else {
257
- console.warn("❌ 유효하지 않은 메뉴정보", e), i.warning("유효하지 않은 메뉴정보입니다.");
258
- return;
259
- }
260
- else {
261
- const m = {
262
- key: e,
263
- gubun: "C",
264
- label: c,
265
- menuItem: l,
266
- closable: !0
267
- };
268
- r({
269
- tabs: [...o, m],
270
- // 탭 목록에 추가
271
- activeMenuId: e,
272
- // 새 탭을 활성화
273
- activeMenuItem: l
274
- // 현재 프로그램으로 설정
275
- }), a().setTabParams(e, t || {});
276
- }
277
- },
278
- // 🔧 탭 제거
279
- // X 버튼 클릭 시 탭을 닫고 관련 상태도 정리
280
- closeTab: (e) => {
281
- const { tabs: t, activeMenuId: o } = a();
282
- t.find((c) => c.key === e);
283
- const n = t.filter((c) => c.key !== e);
284
- let s = o;
285
- if (o === e) {
286
- const c = t.findIndex((l) => l.key === e);
287
- s = n.length ? n[Math.min(c, n.length - 1)]?.key ?? null : null;
288
- }
289
- r({
290
- tabs: n
291
- }), s && a().focusTab(s);
292
- },
293
- // 🔧 활성 탭 변경
294
- // 탭 헤더 클릭 시 해당 탭으로 전환
295
- focusTab: (e) => {
296
- const { tabs: t } = a(), o = t.find((n) => n.key === e);
297
- o ? o.menuItem.prsnInfoYn === "Y" ? (r({
298
- activeMenuId: e,
299
- activeMenuItem: o.menuItem
300
- }), console.log(
301
- "✅ 탭 포커스 (개인정보) - activeMenuItem:",
302
- o.menuItem
303
- ), a().setProtectFlagForKey(e)) : (r({
304
- activeMenuId: e,
305
- activeMenuItem: o.menuItem
306
- }), console.log("✅ 탭 포커스 (일반) - activeMenuItem:", o.menuItem), a().clearProtectFlagForKey(e)) : (r({ activeMenuId: e, activeMenuItem: null }), console.warn("❌ 탭을 찾을 수 없음:", e));
307
- },
308
- // 🔧 모든 탭 제거
309
- // 로그아웃이나 전체 초기화 시 사용
310
- closeAllTabs: () => r({ tabs: [], activeMenuId: null, activeMenuItem: null }),
311
- // 🔧 사이드바 토글
312
- // 햄버거 메뉴 클릭 시 사이드바 접기/펼치기
313
- toggleSidebar: () => r((e) => ({ sidebarCollapsed: !e.sidebarCollapsed })),
314
- // useMenuViewStore.ts
315
- reorderTabs: (e) => r((t) => {
316
- const o = new Map(t.tabs.map((n) => [n.key, n]));
317
- return { tabs: e.map((n) => o.get(n)).filter(Boolean) };
318
- }),
319
- // 개인정보 포함여부에 따른 탭 잠금 Flag 설정
320
- setProtectFlagForKey: (e) => r((t) => ({
321
- tabProtectFlag: { ...t.tabProtectFlag, [e]: !0 }
322
- })),
323
- // 개인정보 포함여부에 따른 탭 잠금 해제
324
- clearProtectFlagForKey: (e) => r((t) => {
325
- const o = { ...t.tabProtectFlag };
326
- return delete o[e], { tabProtectFlag: o };
327
- }),
328
- // 탭 파라미터 설정
329
- setTabParams: (e, t) => r((o) => {
330
- const n = o.tabParams[e] || {}, s = { ...t || {} };
331
- return Object.keys(n).length === Object.keys(s).length && Object.keys(s).every((l) => n[l] === s[l]) ? o : {
332
- tabParams: { ...o.tabParams, [e]: s }
333
- };
334
- }),
335
- // 컴포넌트 라벨 맵 설정
336
- setComponentLabelMap: (e, t) => r({ componentLabelMap: e })
337
- }));
338
- export {
339
- S as a,
340
- N as b,
341
- A as u
342
- };
343
- //# sourceMappingURL=menuViewStore-OKcSQq-s.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"menuViewStore-OKcSQq-s.js","sources":["../../src/stores/favoriteStore.ts","../../src/stores/menuModelStore.ts","../../src/stores/menuViewStore.ts"],"sourcesContent":["import { create } from \"zustand\";\r\nimport { callService } from \"../utils/apiUtils\";\r\nimport { getServiceCode } from \"../utils/serviceConfig\";\r\nimport type { MenuItem } from \"./menuModelStore\";\r\nimport { isLocal } from \"@/utils\";\r\n\r\n// 즐겨찾기 메뉴 타입 정의\r\nexport interface FavoriteMenuItem extends MenuItem {\r\n addedAt: string; // 즐겨찾기 추가 시간\r\n userId: string; // 사용자 ID\r\n}\r\n\r\n// 즐겨찾기 스토어 타입 정의\r\nexport interface FavoriteStore {\r\n favorites: FavoriteMenuItem[];\r\n isLoading: boolean;\r\n error: string | null;\r\n\r\n // 즐겨찾기 메뉴 가져오기\r\n fetchFavorites: (params: { crprCd: string; userId: string }) => Promise<void>;\r\n\r\n // 즐겨찾기 추가\r\n addFavorite: (menuItem: MenuItem, userId: string) => Promise<void>;\r\n\r\n // 즐겨찾기 제거\r\n removeFavorite: (menuId: string, userId: string) => Promise<void>;\r\n\r\n // 즐겨찾기 여부 확인\r\n isFavorite: (menuId: string) => boolean;\r\n\r\n // 즐겨찾기 초기화\r\n clearFavorites: () => void;\r\n}\r\n\r\n// 즐겨찾기 스토어 생성\r\nexport const useFavoriteStore = create<FavoriteStore>((set, get) => ({\r\n favorites: [],\r\n isLoading: false,\r\n error: null,\r\n\r\n // 즐겨찾기 메뉴 가져오기\r\n fetchFavorites: async ({ crprCd, userId }) => {\r\n console.log(\"즐겨찾기 메뉴 요청:\", { crprCd, userId });\r\n set({ isLoading: true, error: null });\r\n\r\n try {\r\n // 서버에서 즐겨찾기 메뉴 가져오기\r\n const data = await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n crprCd,\r\n userId,\r\n });\r\n\r\n let favoritesList: FavoriteMenuItem[] = [];\r\n\r\n if (data?.favorites && Array.isArray(data.favorites)) {\r\n favoritesList = data.favorites;\r\n } else if (Array.isArray(data)) {\r\n favoritesList = data;\r\n } else {\r\n console.warn(\"즐겨찾기 데이터가 비어있거나 예상과 다른 구조입니다.\");\r\n favoritesList = [];\r\n }\r\n\r\n console.log(\"즐겨찾기 메뉴 로드 완료:\", favoritesList);\r\n\r\n // 개발 모드에서 테스트용 즐겨찾기 데이터 추가\r\n if (isLocal && favoritesList.length === 0) {\r\n const testFavorites: FavoriteMenuItem[] = [\r\n {\r\n crprCd: \"100\",\r\n menuGbCd: \"CMPRGRP\",\r\n menuPrntId: \"FAV001\",\r\n menuId: \"FAV_TEST001\",\r\n menuNm: \"API 테스트\",\r\n scrnId: \"TEST001\",\r\n menuNo: 1,\r\n scrnPath: \"/dev/ApiTest\",\r\n menuLvl: 3,\r\n rootMenu: \"FAV001\",\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n },\r\n {\r\n crprCd: \"100\",\r\n menuGbCd: \"CMPRGRP\",\r\n menuPrntId: \"FAV001\",\r\n menuId: \"FAV_TEST002\",\r\n menuNm: \"프로젝트 개요\",\r\n scrnId: \"DOCS001\",\r\n menuNo: 2,\r\n scrnPath: \"/docs/ProjectOverview\",\r\n menuLvl: 3,\r\n rootMenu: \"FAV001\",\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n },\r\n ];\r\n set({ favorites: testFavorites, isLoading: false, error: null });\r\n console.log(\"개발 모드: 테스트용 즐겨찾기 데이터 추가\");\r\n } else {\r\n set({ favorites: favoritesList, isLoading: false, error: null });\r\n }\r\n } catch (error) {\r\n console.error(\"즐겨찾기 메뉴 로드 실패:\", error);\r\n set({\r\n error: error instanceof Error ? error.message : \"즐겨찾기 로드 실패\",\r\n isLoading: false,\r\n });\r\n }\r\n },\r\n\r\n // 즐겨찾기 추가\r\n addFavorite: async (menuItem: MenuItem, userId: string) => {\r\n const { favorites } = get();\r\n\r\n // 이미 즐겨찾기에 있는지 확인\r\n if (favorites.some((fav) => fav.menuId === menuItem.menuId)) {\r\n console.log(\"이미 즐겨찾기에 추가된 메뉴입니다:\", menuItem.menuNm);\r\n return;\r\n }\r\n\r\n try {\r\n // 서버에 즐겨찾기 추가 요청\r\n await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n action: \"add\",\r\n crprCd: menuItem.crprCd,\r\n userId,\r\n menuId: menuItem.menuId,\r\n menuNm: menuItem.menuNm,\r\n scrnPath: menuItem.scrnPath,\r\n });\r\n\r\n // 로컬 상태 업데이트\r\n const newFavorite: FavoriteMenuItem = {\r\n ...menuItem,\r\n addedAt: new Date().toISOString(),\r\n userId,\r\n };\r\n\r\n set({ favorites: [...favorites, newFavorite] });\r\n console.log(\"즐겨찾기 추가 완료:\", menuItem.menuNm);\r\n } catch (error) {\r\n console.error(\"즐겨찾기 추가 실패:\", error);\r\n throw error;\r\n }\r\n },\r\n\r\n // 즐겨찾기 제거\r\n removeFavorite: async (menuId: string, userId: string) => {\r\n const { favorites } = get();\r\n\r\n try {\r\n // 서버에 즐겨찾기 제거 요청\r\n await callService(getServiceCode(\"AUTH_BMRK\"), {\r\n action: \"remove\",\r\n crprCd: \"100\", // 기본값\r\n userId,\r\n menuId,\r\n });\r\n\r\n // 로컬 상태 업데이트\r\n const updatedFavorites = favorites.filter((fav) => fav.menuId !== menuId);\r\n set({ favorites: updatedFavorites });\r\n console.log(\"즐겨찾기 제거 완료:\", menuId);\r\n } catch (error) {\r\n console.error(\"즐겨찾기 제거 실패:\", error);\r\n throw error;\r\n }\r\n },\r\n\r\n // 즐겨찾기 여부 확인\r\n isFavorite: (menuId: string) => {\r\n const { favorites } = get();\r\n return favorites.some((fav) => fav.menuId === menuId);\r\n },\r\n\r\n // 즐겨찾기 초기화\r\n clearFavorites: () => {\r\n set({ favorites: [], isLoading: false, error: null });\r\n },\r\n}));\r\n","import { create } from \"zustand\";\r\n// 필요에 맞게 경로 조정\r\nimport { callService } from \"@/utils/apiUtils\";\r\nimport { getServiceCode } from \"@/utils/serviceConfig\";\r\n\r\n/* ──── Constants ──── */\r\nconst MENU_CONSTANTS = {\r\n DEFAULT_ACTIVE_MENU: \"1\",\r\n DEFAULT_PRNT_GBCD: 1,\r\n COMPANY_CODE: \"100\",\r\n MENU_PARENT_ROOT: \"-\",\r\n MENU_TYPE: { MAIN: \"CMPRGRM\", SUB: \"CMPRGRS\", PROGRAM: \"CMPRGRP\" } as const,\r\n} as const;\r\n\r\n/* ──── Types (이 파일 전용) ──── */\r\nexport interface MenuItem {\r\n crprCd: string;\r\n menuGbCd: string;\r\n menuPrntId: string;\r\n menuId: string;\r\n menuNm: string;\r\n menuNo?: number;\r\n scrnId?: string;\r\n scrnPath?: string;\r\n prsnInfoYn?: \"Y\" | \"N\";\r\n rootMenu: string;\r\n iconCd?: string;\r\n children?: MenuItem[];\r\n}\r\n\r\nexport type FetchMenuParams = {\r\n crprCd: string;\r\n userId: string;\r\n prntGbcd: number;\r\n};\r\n\r\nexport interface MenuApiResponse {\r\n menus?: MenuItem[];\r\n [k: string]: any;\r\n}\r\n\r\n/* 런타임 타입가드 */\r\nconst isMenuItem = (v: any): v is MenuItem =>\r\n v &&\r\n typeof v === \"object\" &&\r\n typeof v.menuId === \"string\" &&\r\n typeof v.menuNm === \"string\" &&\r\n typeof v.crprCd === \"string\";\r\n\r\nconst isMenuItemArray = (v: any): v is MenuItem[] =>\r\n Array.isArray(v) && v.every(isMenuItem);\r\n\r\n/* ──── State Shape ──── */\r\ntype MenuModelState = {\r\n // 📊 State (상태)\r\n // 계층형 메뉴 트리 구조 (부모-자식 관계)\r\n menuList: MenuItem[];\r\n // 평면화된 메뉴 리스트 (검색/조회용)\r\n flatMenuList: MenuItem[];\r\n // 메뉴 데이터 로딩 상태\r\n isLoading: boolean;\r\n // 에러 메시지\r\n error: string | null;\r\n // 마지막 조회 파라미터 (중복 요청 방지)\r\n _lastFetchParams: FetchMenuParams | null;\r\n\r\n // 🔧 Actions (액션 함수들)\r\n // 서버에서 메뉴 데이터 조회\r\n fetchMenu: (p: FetchMenuParams) => Promise<void>;\r\n // 메뉴 데이터 초기화\r\n clearMenu: () => void;\r\n // 메뉴 ID로 특정 메뉴 찾기\r\n findMenuById: (menuId: string) => MenuItem | null;\r\n};\r\n\r\n/* ──── Local Memoization Cache ──── */\r\nlet _lastFlat: MenuItem[] = [];\r\nlet _cachedTree: MenuItem[] = [];\r\n\r\n/* ──── Helpers ──── */\r\nconst parseMenuResponse = (data: unknown): MenuItem[] => {\r\n if (data && typeof data === \"object\") {\r\n const r = data as MenuApiResponse;\r\n if (r.menus && isMenuItemArray(r.menus)) return r.menus;\r\n if (isMenuItemArray(data)) return data;\r\n }\r\n console.warn(\"⚠️ 메뉴 응답이 비어있거나 예상과 다릅니다.\");\r\n return [];\r\n};\r\n\r\nconst sameParams = (a: FetchMenuParams, b: FetchMenuParams | null) =>\r\n !!b &&\r\n a.crprCd === b.crprCd &&\r\n a.userId === b.userId &&\r\n (a.prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD) ===\r\n (b.prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD);\r\n\r\nconst buildHierarchy = (flat: MenuItem[]): MenuItem[] => {\r\n if (\r\n _lastFlat.length === flat.length &&\r\n _lastFlat.every(\r\n (x, i) =>\r\n x.menuId === flat[i]?.menuId && x.menuPrntId === flat[i]?.menuPrntId\r\n )\r\n )\r\n return _cachedTree;\r\n\r\n if (!flat.length) return [];\r\n\r\n const map = new Map<string, MenuItem>();\r\n const roots: MenuItem[] = [];\r\n\r\n flat.forEach((m) => m?.menuId && map.set(m.menuId, { ...m, children: [] }));\r\n flat.forEach((m) => {\r\n const cur = map.get(m.menuId);\r\n if (!cur) return;\r\n if (m.menuPrntId && m.menuPrntId !== \"\" && m.menuPrntId !== \"-\") {\r\n const p = map.get(m.menuPrntId);\r\n p?.children?.push(cur);\r\n } else {\r\n roots.push(cur);\r\n }\r\n });\r\n\r\n const sortRec = (arr: MenuItem[]): MenuItem[] =>\r\n arr\r\n .sort((a, b) => (a?.menuNo ?? 0) - (b?.menuNo ?? 0))\r\n .map((x) => ({\r\n ...x,\r\n children:\r\n x.children && x.children.length ? sortRec(x.children) : undefined,\r\n }));\r\n\r\n const out = sortRec(roots);\r\n _lastFlat = [...flat];\r\n _cachedTree = out;\r\n return out;\r\n};\r\n\r\n/* ──── Store ──── */\r\nexport const useMenuModelStore = create<MenuModelState>((set, get) => ({\r\n // 📊 초기 상태값\r\n menuList: [],\r\n flatMenuList: [],\r\n isLoading: false,\r\n error: null,\r\n _lastFetchParams: null,\r\n\r\n // 🔧 메뉴 모델 조회\r\n // 서버에서 사용자별 메뉴 권한 데이터를 가져와서 트리/플랫 구조로 저장\r\n fetchMenu: async ({ crprCd, userId, prntGbcd }: FetchMenuParams) => {\r\n const p = {\r\n crprCd,\r\n userId,\r\n prntGbcd: prntGbcd ?? MENU_CONSTANTS.DEFAULT_PRNT_GBCD,\r\n };\r\n // 중복 요청 방지\r\n if (sameParams(p, get()._lastFetchParams)) {\r\n console.log(\"✅ 중복 fetch 차단\", p);\r\n return;\r\n }\r\n set({ isLoading: true, error: null, _lastFetchParams: p });\r\n try {\r\n // API 호출하여 메뉴 데이터 가져오기\r\n const data = await callService(getServiceCode(\"AUTH_MENU\"), p);\r\n const flat = parseMenuResponse(data); // 응답 데이터 파싱\r\n const tree = buildHierarchy(flat); // 계층 구조 생성\r\n set({\r\n flatMenuList: flat, // 평면 리스트 저장\r\n menuList: tree, // 트리 구조 저장\r\n isLoading: false,\r\n error: null,\r\n });\r\n } catch (e: any) {\r\n set({ isLoading: false, error: e?.message ?? \"메뉴 로드 실패\" });\r\n }\r\n },\r\n\r\n // 🔧 메뉴 모델 초기화\r\n // 로그아웃 시나 사용자 변경 시 메뉴 모델 클리어\r\n clearMenu: () => {\r\n set({\r\n menuList: [],\r\n flatMenuList: [],\r\n error: null,\r\n _lastFetchParams: null,\r\n });\r\n },\r\n\r\n // 🔧 메뉴 ID로 메뉴 아이템 찾기\r\n // URL 파라미터나 프로그래밍 방식으로 특정 메뉴를 찾을 때 사용\r\n findMenuById: (menuId: string) => {\r\n const { flatMenuList } = get();\r\n return flatMenuList.find((m) => m.menuId === menuId) ?? null;\r\n },\r\n}));\r\n","import { create } from \"zustand\";\r\nimport React from \"react\";\r\nimport { MenuItem, useMenuModelStore } from \"./menuModelStore\";\r\nimport { message } from \"antd\";\r\n\r\n/* ──── Constants (UI 측에도 독립적으로 존재) ──── */\r\nconst MENU_CONSTANTS = {\r\n DEFAULT_ACTIVE_MENU: \"1\",\r\n MAX_TABS: 15,\r\n} as const;\r\n\r\n/* ──── Types (이 파일 전용) ──── */\r\nexport interface TabItem {\r\n key: string; // menuId\r\n label: string; // menuNm\r\n gubun: \"M\" | \"C\"; // menuId or componentPath\r\n menuItem: MenuItem;\r\n\r\n closable: boolean;\r\n}\r\n\r\n/* ──── State Shape ──── */\r\ntype MenuViewState = {\r\n // 📊 UI State (화면 상태)\r\n // 현재 활성화된 메뉴 ID\r\n activeMenuId: string | undefined | null;\r\n // 현재 활성화된 메뉴 정보\r\n activeMenuItem: MenuItem | null;\r\n // 열린 탭 목록\r\n tabs: TabItem[];\r\n // 사이드바 접힘/펼침 상태\r\n sidebarCollapsed: boolean;\r\n // 최대 탭 개수\r\n maxTabs: number;\r\n tabProtectFlag: Record<string, boolean>;\r\n // 탭 파라미터\r\n tabParams: Record<string, Record<string, any>>;\r\n // 컴포넌트 라벨 맵\r\n componentLabelMap: Record<string, string>;\r\n\r\n /* 🛠 UI Actions (UI 액션 함수들) */\r\n // 메뉴 아이템으로 탭 추가\r\n openTabFromMenu: (menuItem: MenuItem, params?: Record<string, any>) => void;\r\n // 메뉴 ID로 탭 추가 (URL 파라미터 처리용)\r\n openTabByMenuId: (menuId: string, params?: Record<string, any>) => void;\r\n // 컴포넌트 ID로 탭 추가\r\n openTabByComponentId: (cpntId: string, params?: Record<string, any>) => void;\r\n // 활성 탭 변경\r\n focusTab: (tabKey: string) => void;\r\n // 탭 제거\r\n closeTab: (tabKey: string) => void;\r\n // 모든 탭 제거\r\n closeAllTabs: () => void;\r\n // 사이드바 토글\r\n toggleSidebar: () => void;\r\n // 탭 순서 변경\r\n reorderTabs: (keys: string[]) => void;\r\n // 개인정보 포함여부에 따른 탭 잠금 Flag 설정\r\n setProtectFlagForKey: (key: string) => void;\r\n // 개인정보 포함여부에 따른 탭 잠금 해제\r\n clearProtectFlagForKey: (key: string) => void;\r\n // 탭 파라미터 설정\r\n setTabParams: (key: string, params: Record<string, any>) => void;\r\n //컴포넌트 라벨 맵 설정\r\n setComponentLabelMap: (map: Record<string, string>, merge?: boolean) => void;\r\n};\r\n\r\n/* ──── Store ──── */\r\nexport const useMenuViewStore = create<MenuViewState>((set, get) => ({\r\n // 📊 초기 상태값\r\n activeMenuId: null,\r\n activeMenuItem: null,\r\n tabs: [],\r\n sidebarCollapsed: false,\r\n maxTabs: MENU_CONSTANTS.MAX_TABS,\r\n tabProtectFlag: {},\r\n tabParams: {},\r\n componentLabelMap: {},\r\n // 🔧 탭 추가 (메뉴 아이템 객체로)\r\n // 사이드바에서 메뉴 클릭 시 호출되는 메인 함수\r\n openTabFromMenu: (menuItem, params) => {\r\n const { tabs, activeMenuId } = get();\r\n const exists = tabs.find((t) => t.key === menuItem.menuId);\r\n\r\n // 새 탭 생성\r\n if (!exists) {\r\n // 2. 최대 탭 개수 확인\r\n if (tabs.length > MENU_CONSTANTS.MAX_TABS) {\r\n console.warn(\"❌ 최대 탭 개수를 초과했습니다.\");\r\n message.warning(\r\n `최대 ${MENU_CONSTANTS.MAX_TABS}개의 탭만 열 수 있습니다.\\n기존 탭을 닫고 다시 시도해주세요.`\r\n );\r\n return;\r\n }\r\n const newTab: TabItem = {\r\n key: menuItem.menuId,\r\n label: menuItem.menuNm,\r\n gubun: \"M\",\r\n menuItem: menuItem as MenuItem,\r\n closable: true,\r\n };\r\n set({\r\n tabs: [...tabs, newTab], // 탭 목록에 추가\r\n activeMenuId: menuItem.menuId, // 새 탭을 활성화\r\n activeMenuItem: menuItem, // 현재 프로그램으로 설정\r\n });\r\n get().setTabParams(menuItem.menuId, params || {});\r\n console.log(\"✅ 새 탭 추가 - activeMenuItem:\", menuItem);\r\n\r\n // 개인정보 메뉴만 Protect\r\n if (menuItem?.prsnInfoYn === \"Y\") {\r\n get().setProtectFlagForKey(menuItem.menuId);\r\n }\r\n } else if (activeMenuId !== menuItem.menuId) {\r\n // 이미 존재하는 탭이면 활성화만\r\n set({ activeMenuId: menuItem.menuId, activeMenuItem: menuItem });\r\n console.log(\"✅ 기존 탭 활성화 - activeMenuItem:\", menuItem);\r\n get().setTabParams(menuItem.menuId, params || {});\r\n // 개인정보 메뉴만 Protect\r\n if (menuItem?.prsnInfoYn === \"Y\") {\r\n get().setProtectFlagForKey(menuItem.menuId);\r\n }\r\n } else {\r\n console.warn(\"❌ 유효하지 않은 메뉴정보\", menuItem.menuId);\r\n message.warning(\"유효하지 않은 메뉴정보입니다.\");\r\n }\r\n },\r\n // 🔧 탭 추가 (메뉴 ID로)\r\n // URL 파라미터로 메뉴 열기 시 사용 (예: ?menuId=CM000301)\r\n openTabByMenuId: (menuId, params) => {\r\n const target = useMenuModelStore.getState().findMenuById(menuId);\r\n if (!target) {\r\n console.warn(\"❌ 메뉴 ID를 찾을 수 없음:\", menuId);\r\n message.warning(\"메뉴 ID를 찾을 수 없습니다.\");\r\n } else {\r\n get().openTabFromMenu(target, params); // 찾은 메뉴로 탭 추가\r\n }\r\n },\r\n openTabByComponentId: (cpntId, params) => {\r\n const { tabs, activeMenuId } = get();\r\n const exists = tabs.find((t) => t.key === cpntId);\r\n const cpntNm = get().componentLabelMap[cpntId] ?? cpntId;\r\n\r\n const menuItem = {\r\n crprCd: \"\",\r\n menuNm: cpntNm,\r\n menuId: cpntId,\r\n scrnId: cpntId,\r\n scrnPath: cpntId,\r\n menuNo: undefined,\r\n menuLvl: 0,\r\n prsnInfoYn: \"N\" as const,\r\n rootMenu: \"\",\r\n iconCd: \"\",\r\n menuGbCd: \"\",\r\n menuPrntId: \"\",\r\n children: [],\r\n };\r\n // 새 탭 생성\r\n if (!exists) {\r\n const newTab: TabItem = {\r\n key: cpntId,\r\n gubun: \"C\",\r\n label: cpntNm,\r\n menuItem,\r\n closable: true,\r\n };\r\n\r\n set({\r\n tabs: [...tabs, newTab], // 탭 목록에 추가\r\n activeMenuId: cpntId, // 새 탭을 활성화\r\n activeMenuItem: menuItem, // 현재 프로그램으로 설정\r\n });\r\n get().setTabParams(cpntId, params || {});\r\n } else if (activeMenuId !== menuItem.menuId) {\r\n // 이미 존재하는 탭이면 활성화만\r\n set({ activeMenuId: menuItem.menuId, activeMenuItem: menuItem });\r\n get().setTabParams(menuItem.menuId, params || {});\r\n } else {\r\n console.warn(\"❌ 유효하지 않은 메뉴정보\", cpntId);\r\n message.warning(\"유효하지 않은 메뉴정보입니다.\");\r\n return;\r\n }\r\n },\r\n // 🔧 탭 제거\r\n // X 버튼 클릭 시 탭을 닫고 관련 상태도 정리\r\n closeTab: (tabKey) => {\r\n const { tabs, activeMenuId } = get();\r\n const removed = tabs.find((t) => t.key === tabKey);\r\n const nextTabs = tabs.filter((t) => t.key !== tabKey);\r\n\r\n // 닫힌 탭이 현재 활성 탭이면 다음 탭으로 이동\r\n let nextActive = activeMenuId;\r\n if (activeMenuId === tabKey) {\r\n const idx = tabs.findIndex((t) => t.key === tabKey);\r\n nextActive = nextTabs.length\r\n ? nextTabs[Math.min(idx, nextTabs.length - 1)]?.key ?? null\r\n : null;\r\n }\r\n\r\n set({\r\n tabs: nextTabs,\r\n });\r\n\r\n if (nextActive) get().focusTab(nextActive);\r\n },\r\n // 🔧 활성 탭 변경\r\n // 탭 헤더 클릭 시 해당 탭으로 전환\r\n focusTab: (tabKey) => {\r\n const { tabs } = get();\r\n const target = tabs.find((t) => t.key === tabKey);\r\n\r\n if (target) {\r\n if (target.menuItem.prsnInfoYn === \"Y\") {\r\n set({\r\n activeMenuId: tabKey,\r\n activeMenuItem: target.menuItem,\r\n });\r\n console.log(\r\n \"✅ 탭 포커스 (개인정보) - activeMenuItem:\",\r\n target.menuItem\r\n );\r\n get().setProtectFlagForKey(tabKey);\r\n } else {\r\n set({\r\n activeMenuId: tabKey,\r\n activeMenuItem: target.menuItem,\r\n });\r\n console.log(\"✅ 탭 포커스 (일반) - activeMenuItem:\", target.menuItem);\r\n get().clearProtectFlagForKey(tabKey);\r\n }\r\n } else {\r\n set({ activeMenuId: tabKey, activeMenuItem: null });\r\n console.warn(\"❌ 탭을 찾을 수 없음:\", tabKey);\r\n }\r\n },\r\n\r\n // 🔧 모든 탭 제거\r\n // 로그아웃이나 전체 초기화 시 사용\r\n closeAllTabs: () =>\r\n set({ tabs: [], activeMenuId: null, activeMenuItem: null }),\r\n\r\n // 🔧 사이드바 토글\r\n // 햄버거 메뉴 클릭 시 사이드바 접기/펼치기\r\n toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })),\r\n\r\n // useMenuViewStore.ts\r\n reorderTabs: (keys: string[]) =>\r\n set((state) => {\r\n const map = new Map(state.tabs.map((t) => [t.key, t]));\r\n return { tabs: keys.map((k) => map.get(k)!).filter(Boolean) };\r\n }),\r\n // 개인정보 포함여부에 따른 탭 잠금 Flag 설정\r\n setProtectFlagForKey: (key: string) =>\r\n set((s) => ({\r\n tabProtectFlag: { ...s.tabProtectFlag, [key]: true },\r\n })),\r\n // 개인정보 포함여부에 따른 탭 잠금 해제\r\n clearProtectFlagForKey: (key: string) =>\r\n set((s) => {\r\n const newFlags = { ...s.tabProtectFlag };\r\n delete newFlags[key];\r\n return { tabProtectFlag: newFlags };\r\n }),\r\n // 탭 파라미터 설정\r\n setTabParams: (key, params) =>\r\n set((state) => {\r\n const prev = state.tabParams[key] || {};\r\n const next = { ...(params || {}) }; // 새 객체 (불변 보장)\r\n\r\n // shallow equal이면 스킵(불필요 렌더 방지)\r\n const isShallowEqual =\r\n Object.keys(prev).length === Object.keys(next).length &&\r\n Object.keys(next).every((k) => prev[k] === next[k]);\r\n if (isShallowEqual) return state;\r\n\r\n return {\r\n tabParams: { ...state.tabParams, [key]: next },\r\n };\r\n }),\r\n // 컴포넌트 라벨 맵 설정\r\n setComponentLabelMap: (map: Record<string, string>, merge?: boolean) =>\r\n set({ componentLabelMap: map }),\r\n}));\r\n"],"names":["useFavoriteStore","create","set","get","crprCd","userId","data","callService","getServiceCode","favoritesList","isLocal","testFavorites","error","menuItem","favorites","fav","newFavorite","menuId","updatedFavorites","MENU_CONSTANTS","isMenuItem","v","isMenuItemArray","_lastFlat","_cachedTree","parseMenuResponse","r","sameParams","a","b","buildHierarchy","flat","x","i","map","roots","m","cur","sortRec","arr","out","useMenuModelStore","prntGbcd","p","tree","e","flatMenuList","useMenuViewStore","params","tabs","activeMenuId","t","message","newTab","target","cpntId","exists","cpntNm","tabKey","nextTabs","nextActive","idx","s","keys","state","k","key","newFlags","prev","next","merge"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const g=require("zustand"),a=require("./serviceConfig-9dHegQIK.cjs"),P=g.create((r,i)=>({popups:[],activePopupId:null,isLoading:!1,error:null,openPopup:async(p,s,u)=>{console.log("팝업 열기 요청:",{popupCode:p,data:s,config:u}),r({isLoading:!0,error:null});try{console.log("팝업 열기 시작:",p);let o=null;const n=await a.callService(a.getServiceCode("SRCH_POPU"),{crprCd:a.getUserInfo()?.crprCd,popuCd:p});console.log("팝업 정보 조회 결과:",n),o=n?.mstr;const t=n?.dtls||[];if(console.info("popupInfo:",o),!o||!o.popuUrl){const e=`팝업 정보를 찾을 수 없습니다: ${p}`;throw console.error(e),new Error(e)}console.log("파싱된 팝업 정보:",o),console.log("버튼 목록:",t);const d=(e=>`/src/pages/views/popup/${e}`)(o.popuUrl);console.log("변환된 팝업 URL:",d);const l={popupId:`popup_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,popupCode:p,popupTitle:o.popuNm||"팝업",popupUrl:d,popupParams:s,width:o.popuWdth||800,height:o.popuHght||600,resizable:!0,draggable:!0,buttonList:t,config:u};console.log("생성된 팝업 아이템:",l);const c=i().popups.find(e=>e.popupCode===p);if(c){console.log("기존 팝업 업데이트:",c.popupId),r({activePopupId:c.popupId,popups:i().popups.map(e=>e.popupId===c.popupId?{...e,config:u}:e),isLoading:!1});return}console.log("새 팝업 추가:",l.popupId),r(e=>({popups:[...e.popups,l],activePopupId:l.popupId,isLoading:!1})),console.log("팝업 열기 완료:",l)}catch(o){console.error("팝업 열기 실패:",o),r({error:o instanceof Error?o.message:"팝업 열기 실패",isLoading:!1})}},closePopup:p=>{const{popups:s,activePopupId:u}=i(),o=s.filter(t=>t.popupId!==p);let n=u;u===p&&(n=o.length>0?o[o.length-1].popupId:null),r({popups:o,activePopupId:n})},closeAllPopups:()=>{r({popups:[],activePopupId:null})},setActivePopup:p=>{r({activePopupId:p})},updatePopupConfig:(p,s)=>{r(u=>({popups:u.popups.map(o=>o.popupId===p?{...o,config:{...o.config,...s}}:o)}))}}));exports.usePopupStore=P;
2
- //# sourceMappingURL=popupStore-BEoWGajT.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"popupStore-BEoWGajT.cjs","sources":["../../src/stores/popupStore.ts"],"sourcesContent":["import { create } from \"zustand\";\r\nimport { callService } from \"../utils/apiUtils\";\r\nimport { getServiceCode } from \"../utils/serviceConfig\";\r\nimport { getUserInfo } from \"@/utils\";\r\n\r\n// 팝업 아이템 타입 정의\r\nexport interface PopupItem {\r\n popupId: string; // 팝업 ID\r\n popupCode: string; // 팝업 코드\r\n popupTitle: string; // 팝업 제목\r\n popupUrl: string; // 팝업 프로그램 URL\r\n popupParams?: any; // 팝업 파라미터\r\n buttonList?: any[]; // 버튼 목록\r\n width?: number; // 팝업 너비\r\n height?: number; // 팝업 높이\r\n resizable?: boolean; // 크기 조절 가능 여부\r\n draggable?: boolean; // 드래그 가능 여부\r\n config?: PopupConfig; // 팝업 설정\r\n close?: () => void; // 팝업 닫기 함수\r\n}\r\n\r\n// 팝업 스토어 타입 정의\r\nexport interface PopupStore {\r\n popups: PopupItem[]; // 열린 팝업 목록\r\n activePopupId: string | null; // 현재 활성 팝업 ID\r\n isLoading: boolean; // 로딩 상태\r\n error: string | null; // 에러 상태\r\n\r\n // 팝업 관련 액션들\r\n openPopup: (\r\n popupCode: string,\r\n data?: any,\r\n config?: PopupConfig\r\n ) => Promise<void>;\r\n closePopup: (popupId: string) => void;\r\n closeAllPopups: () => void;\r\n setActivePopup: (popupId: string) => void;\r\n\r\n updatePopupConfig: (popupId: string, config: Partial<PopupConfig>) => void;\r\n}\r\n\r\nexport interface PopupButton {\r\n key: string; // 버튼 고유 키\r\n text: string; // 버튼 텍스트\r\n type?: \"primary\" | \"default\" | \"dashed\" | \"link\" | \"text\"; // 버튼 타입\r\n danger?: boolean; // 위험 버튼 여부\r\n disabled?: boolean; // 비활성화 여부\r\n icon?: string; // 아이콘 (Ant Design 아이콘명)\r\n onClick?: (popupData?: any) => void | Promise<void>; // 클릭 이벤트\r\n}\r\n\r\n/**\r\n * 팝업 설정 타입 정의\r\n */\r\nexport interface PopupConfig {\r\n width?: number; // 팝업 너비\r\n height?: number; // 팝업 높이\r\n title?: string; // 팝업 제목\r\n buttons?: PopupButton[]; // 팝업 버튼들\r\n resizable?: boolean; // 크기 조절 가능 여부\r\n draggable?: boolean; // 드래그 가능 여부\r\n closable?: boolean; // 닫기 버튼 표시 여부\r\n maskClosable?: boolean; // 마스크 클릭 시 닫기 여부\r\n destroyOnClose?: boolean; // 닫을 때 컴포넌트 파괴 여부\r\n searchBox?: {\r\n reqArea: any;\r\n subArea?: any;\r\n style?: any;\r\n };\r\n /**\r\n * 팝업 콜백\r\n * 팝업 콜백은 팝업이 닫힐 때 호출되는 함수입니다.\r\n */\r\n callback?: (callbackParams?: any) => void;\r\n}\r\n\r\n/**\r\n * 팝업 내부 뷰 컴포넌트 타입\r\n */\r\nexport interface PopupViewProps {\r\n /**\r\n * 팝업정보\r\n */\r\n popup?: PopupItem;\r\n /** 팝업 이벤트 전달 프로퍼티 */\r\n popupEvent?: any;\r\n /** 팝업 닫기 이벤트 전달 프로퍼티 */\r\n onClose?: () => void;\r\n}\r\n\r\n// 팝업 스토어 생성\r\nexport const usePopupStore = create<PopupStore>((set, get) => ({\r\n popups: [],\r\n activePopupId: null,\r\n isLoading: false,\r\n error: null,\r\n\r\n // 팝업 열기\r\n openPopup: async (popupCode: string, data?: any, config?: PopupConfig) => {\r\n console.log(\"팝업 열기 요청:\", { popupCode, data, config });\r\n set({ isLoading: true, error: null });\r\n\r\n try {\r\n console.log(\"팝업 열기 시작:\", popupCode);\r\n\r\n // 개발 환경에서는 모의 데이터 사용\r\n let popupInfo: any = null;\r\n\r\n const response = await callService(getServiceCode(\"SRCH_POPU\"), {\r\n crprCd: getUserInfo()?.crprCd,\r\n popuCd: popupCode,\r\n });\r\n console.log(\"팝업 정보 조회 결과:\", response);\r\n\r\n // 응답 구조 파싱: { mstr: {...}, dtls: [...] }\r\n popupInfo = response?.mstr;\r\n const buttonList = response?.dtls || [];\r\n\r\n console.info(\"popupInfo:\", popupInfo);\r\n\r\n if (!popupInfo || !popupInfo.popuUrl) {\r\n const errorMsg = `팝업 정보를 찾을 수 없습니다: ${popupCode}`;\r\n console.error(errorMsg);\r\n throw new Error(errorMsg);\r\n }\r\n\r\n console.log(\"파싱된 팝업 정보:\", popupInfo);\r\n console.log(\"버튼 목록:\", buttonList);\r\n\r\n // 팝업 URL 경로 변환: 서버 경로 -> 클라이언트 경로\r\n const convertPopupUrl = (serverUrl: string): string => {\r\n // 서버에서 받은 경로: \"cm/CMAuthMstrP01\"\r\n // 클라이언트에서 사용할 경로: \"/src/pages/views/popup/cm/CMAuthMstrP01\"\r\n return `/src/pages/views/popup/${serverUrl}`;\r\n };\r\n\r\n const convertedPopupUrl = convertPopupUrl(popupInfo.popuUrl);\r\n console.log(\"변환된 팝업 URL:\", convertedPopupUrl);\r\n\r\n // 팝업 아이템 생성\r\n const popupItem: PopupItem = {\r\n popupId: `popup_${Date.now()}_${Math.random()\r\n .toString(36)\r\n .substr(2, 9)}`,\r\n popupCode: popupCode,\r\n popupTitle: popupInfo.popuNm || \"팝업\",\r\n popupUrl: convertedPopupUrl,\r\n popupParams: data,\r\n width: popupInfo.popuWdth || 800,\r\n height: popupInfo.popuHght || 600,\r\n resizable: true,\r\n draggable: true,\r\n buttonList: buttonList, // 버튼 목록 추가\r\n config: config,\r\n };\r\n\r\n console.log(\"생성된 팝업 아이템:\", popupItem);\r\n\r\n // 이미 같은 팝업이 열려있는지 확인\r\n const existingPopup = get().popups.find((p) => p.popupCode === popupCode);\r\n if (existingPopup) {\r\n console.log(\"기존 팝업 업데이트:\", existingPopup.popupId);\r\n // 기존 팝업을 활성화하고 데이터 업데이트\r\n set({\r\n activePopupId: existingPopup.popupId,\r\n popups: get().popups.map((p) =>\r\n p.popupId === existingPopup.popupId ? { ...p, config: config } : p\r\n ),\r\n isLoading: false,\r\n });\r\n return;\r\n }\r\n\r\n // 새 팝업 추가\r\n console.log(\"새 팝업 추가:\", popupItem.popupId);\r\n set((state) => ({\r\n popups: [...state.popups, popupItem],\r\n activePopupId: popupItem.popupId,\r\n isLoading: false,\r\n }));\r\n\r\n console.log(\"팝업 열기 완료:\", popupItem);\r\n } catch (error) {\r\n console.error(\"팝업 열기 실패:\", error);\r\n set({\r\n error: error instanceof Error ? error.message : \"팝업 열기 실패\",\r\n isLoading: false,\r\n });\r\n }\r\n },\r\n\r\n // 팝업 닫기\r\n closePopup: (popupId: string) => {\r\n const { popups, activePopupId } = get();\r\n const newPopups = popups.filter((p) => p.popupId !== popupId);\r\n\r\n // 닫힌 팝업이 현재 활성 팝업이었다면 다른 팝업을 활성화\r\n let newActivePopupId = activePopupId;\r\n if (activePopupId === popupId) {\r\n newActivePopupId =\r\n newPopups.length > 0 ? newPopups[newPopups.length - 1].popupId : null;\r\n }\r\n\r\n set({\r\n popups: newPopups,\r\n activePopupId: newActivePopupId,\r\n });\r\n },\r\n\r\n // 모든 팝업 닫기\r\n closeAllPopups: () => {\r\n set({\r\n popups: [],\r\n activePopupId: null,\r\n });\r\n },\r\n\r\n // 활성 팝업 설정\r\n setActivePopup: (popupId: string) => {\r\n set({ activePopupId: popupId });\r\n },\r\n\r\n // 팝업 설정 업데이트\r\n updatePopupConfig: (popupId: string, config: Partial<PopupConfig>) => {\r\n set((state) => ({\r\n popups: state.popups.map((p) =>\r\n p.popupId === popupId ? { ...p, config: { ...p.config, ...config } } : p\r\n ),\r\n }));\r\n },\r\n}));\r\n"],"names":["usePopupStore","create","set","get","popupCode","data","config","popupInfo","response","callService","getServiceCode","getUserInfo","buttonList","errorMsg","convertedPopupUrl","serverUrl","popupItem","existingPopup","p","state","error","popupId","popups","activePopupId","newPopups","newActivePopupId"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"popupStore-D8RI04bU.js","sources":["../../src/stores/popupStore.ts"],"sourcesContent":["import { create } from \"zustand\";\r\nimport { callService } from \"../utils/apiUtils\";\r\nimport { getServiceCode } from \"../utils/serviceConfig\";\r\nimport { getUserInfo } from \"@/utils\";\r\n\r\n// 팝업 아이템 타입 정의\r\nexport interface PopupItem {\r\n popupId: string; // 팝업 ID\r\n popupCode: string; // 팝업 코드\r\n popupTitle: string; // 팝업 제목\r\n popupUrl: string; // 팝업 프로그램 URL\r\n popupParams?: any; // 팝업 파라미터\r\n buttonList?: any[]; // 버튼 목록\r\n width?: number; // 팝업 너비\r\n height?: number; // 팝업 높이\r\n resizable?: boolean; // 크기 조절 가능 여부\r\n draggable?: boolean; // 드래그 가능 여부\r\n config?: PopupConfig; // 팝업 설정\r\n close?: () => void; // 팝업 닫기 함수\r\n}\r\n\r\n// 팝업 스토어 타입 정의\r\nexport interface PopupStore {\r\n popups: PopupItem[]; // 열린 팝업 목록\r\n activePopupId: string | null; // 현재 활성 팝업 ID\r\n isLoading: boolean; // 로딩 상태\r\n error: string | null; // 에러 상태\r\n\r\n // 팝업 관련 액션들\r\n openPopup: (\r\n popupCode: string,\r\n data?: any,\r\n config?: PopupConfig\r\n ) => Promise<void>;\r\n closePopup: (popupId: string) => void;\r\n closeAllPopups: () => void;\r\n setActivePopup: (popupId: string) => void;\r\n\r\n updatePopupConfig: (popupId: string, config: Partial<PopupConfig>) => void;\r\n}\r\n\r\nexport interface PopupButton {\r\n key: string; // 버튼 고유 키\r\n text: string; // 버튼 텍스트\r\n type?: \"primary\" | \"default\" | \"dashed\" | \"link\" | \"text\"; // 버튼 타입\r\n danger?: boolean; // 위험 버튼 여부\r\n disabled?: boolean; // 비활성화 여부\r\n icon?: string; // 아이콘 (Ant Design 아이콘명)\r\n onClick?: (popupData?: any) => void | Promise<void>; // 클릭 이벤트\r\n}\r\n\r\n/**\r\n * 팝업 설정 타입 정의\r\n */\r\nexport interface PopupConfig {\r\n width?: number; // 팝업 너비\r\n height?: number; // 팝업 높이\r\n title?: string; // 팝업 제목\r\n buttons?: PopupButton[]; // 팝업 버튼들\r\n resizable?: boolean; // 크기 조절 가능 여부\r\n draggable?: boolean; // 드래그 가능 여부\r\n closable?: boolean; // 닫기 버튼 표시 여부\r\n maskClosable?: boolean; // 마스크 클릭 시 닫기 여부\r\n destroyOnClose?: boolean; // 닫을 때 컴포넌트 파괴 여부\r\n searchBox?: {\r\n reqArea: any;\r\n subArea?: any;\r\n style?: any;\r\n };\r\n /**\r\n * 팝업 콜백\r\n * 팝업 콜백은 팝업이 닫힐 때 호출되는 함수입니다.\r\n */\r\n callback?: (callbackParams?: any) => void;\r\n}\r\n\r\n/**\r\n * 팝업 내부 뷰 컴포넌트 타입\r\n */\r\nexport interface PopupViewProps {\r\n /**\r\n * 팝업정보\r\n */\r\n popup?: PopupItem;\r\n /** 팝업 이벤트 전달 프로퍼티 */\r\n popupEvent?: any;\r\n /** 팝업 닫기 이벤트 전달 프로퍼티 */\r\n onClose?: () => void;\r\n}\r\n\r\n// 팝업 스토어 생성\r\nexport const usePopupStore = create<PopupStore>((set, get) => ({\r\n popups: [],\r\n activePopupId: null,\r\n isLoading: false,\r\n error: null,\r\n\r\n // 팝업 열기\r\n openPopup: async (popupCode: string, data?: any, config?: PopupConfig) => {\r\n console.log(\"팝업 열기 요청:\", { popupCode, data, config });\r\n set({ isLoading: true, error: null });\r\n\r\n try {\r\n console.log(\"팝업 열기 시작:\", popupCode);\r\n\r\n // 개발 환경에서는 모의 데이터 사용\r\n let popupInfo: any = null;\r\n\r\n const response = await callService(getServiceCode(\"SRCH_POPU\"), {\r\n crprCd: getUserInfo()?.crprCd,\r\n popuCd: popupCode,\r\n });\r\n console.log(\"팝업 정보 조회 결과:\", response);\r\n\r\n // 응답 구조 파싱: { mstr: {...}, dtls: [...] }\r\n popupInfo = response?.mstr;\r\n const buttonList = response?.dtls || [];\r\n\r\n console.info(\"popupInfo:\", popupInfo);\r\n\r\n if (!popupInfo || !popupInfo.popuUrl) {\r\n const errorMsg = `팝업 정보를 찾을 수 없습니다: ${popupCode}`;\r\n console.error(errorMsg);\r\n throw new Error(errorMsg);\r\n }\r\n\r\n console.log(\"파싱된 팝업 정보:\", popupInfo);\r\n console.log(\"버튼 목록:\", buttonList);\r\n\r\n // 팝업 URL 경로 변환: 서버 경로 -> 클라이언트 경로\r\n const convertPopupUrl = (serverUrl: string): string => {\r\n // 서버에서 받은 경로: \"cm/CMAuthMstrP01\"\r\n // 클라이언트에서 사용할 경로: \"/src/pages/views/popup/cm/CMAuthMstrP01\"\r\n return `/src/pages/views/popup/${serverUrl}`;\r\n };\r\n\r\n const convertedPopupUrl = convertPopupUrl(popupInfo.popuUrl);\r\n console.log(\"변환된 팝업 URL:\", convertedPopupUrl);\r\n\r\n // 팝업 아이템 생성\r\n const popupItem: PopupItem = {\r\n popupId: `popup_${Date.now()}_${Math.random()\r\n .toString(36)\r\n .substr(2, 9)}`,\r\n popupCode: popupCode,\r\n popupTitle: popupInfo.popuNm || \"팝업\",\r\n popupUrl: convertedPopupUrl,\r\n popupParams: data,\r\n width: popupInfo.popuWdth || 800,\r\n height: popupInfo.popuHght || 600,\r\n resizable: true,\r\n draggable: true,\r\n buttonList: buttonList, // 버튼 목록 추가\r\n config: config,\r\n };\r\n\r\n console.log(\"생성된 팝업 아이템:\", popupItem);\r\n\r\n // 이미 같은 팝업이 열려있는지 확인\r\n const existingPopup = get().popups.find((p) => p.popupCode === popupCode);\r\n if (existingPopup) {\r\n console.log(\"기존 팝업 업데이트:\", existingPopup.popupId);\r\n // 기존 팝업을 활성화하고 데이터 업데이트\r\n set({\r\n activePopupId: existingPopup.popupId,\r\n popups: get().popups.map((p) =>\r\n p.popupId === existingPopup.popupId ? { ...p, config: config } : p\r\n ),\r\n isLoading: false,\r\n });\r\n return;\r\n }\r\n\r\n // 새 팝업 추가\r\n console.log(\"새 팝업 추가:\", popupItem.popupId);\r\n set((state) => ({\r\n popups: [...state.popups, popupItem],\r\n activePopupId: popupItem.popupId,\r\n isLoading: false,\r\n }));\r\n\r\n console.log(\"팝업 열기 완료:\", popupItem);\r\n } catch (error) {\r\n console.error(\"팝업 열기 실패:\", error);\r\n set({\r\n error: error instanceof Error ? error.message : \"팝업 열기 실패\",\r\n isLoading: false,\r\n });\r\n }\r\n },\r\n\r\n // 팝업 닫기\r\n closePopup: (popupId: string) => {\r\n const { popups, activePopupId } = get();\r\n const newPopups = popups.filter((p) => p.popupId !== popupId);\r\n\r\n // 닫힌 팝업이 현재 활성 팝업이었다면 다른 팝업을 활성화\r\n let newActivePopupId = activePopupId;\r\n if (activePopupId === popupId) {\r\n newActivePopupId =\r\n newPopups.length > 0 ? newPopups[newPopups.length - 1].popupId : null;\r\n }\r\n\r\n set({\r\n popups: newPopups,\r\n activePopupId: newActivePopupId,\r\n });\r\n },\r\n\r\n // 모든 팝업 닫기\r\n closeAllPopups: () => {\r\n set({\r\n popups: [],\r\n activePopupId: null,\r\n });\r\n },\r\n\r\n // 활성 팝업 설정\r\n setActivePopup: (popupId: string) => {\r\n set({ activePopupId: popupId });\r\n },\r\n\r\n // 팝업 설정 업데이트\r\n updatePopupConfig: (popupId: string, config: Partial<PopupConfig>) => {\r\n set((state) => ({\r\n popups: state.popups.map((p) =>\r\n p.popupId === popupId ? { ...p, config: { ...p.config, ...config } } : p\r\n ),\r\n }));\r\n },\r\n}));\r\n"],"names":["usePopupStore","create","set","get","popupCode","data","config","popupInfo","response","callService","getServiceCode","getUserInfo","buttonList","errorMsg","convertedPopupUrl","serverUrl","popupItem","existingPopup","p","state","error","popupId","popups","activePopupId","newPopups","newActivePopupId"],"mappings":";;AA2FO,MAAMA,IAAgBC,EAAmB,CAACC,GAAKC,OAAS;AAAA,EAC7D,QAAQ,CAAA;AAAA,EACR,eAAe;AAAA,EACf,WAAW;AAAA,EACX,OAAO;AAAA;AAAA,EAGP,WAAW,OAAOC,GAAmBC,GAAYC,MAAyB;AACxE,YAAQ,IAAI,aAAa,EAAE,WAAAF,GAAW,MAAAC,GAAM,QAAAC,GAAQ,GACpDJ,EAAI,EAAE,WAAW,IAAM,OAAO,MAAM;AAEpC,QAAI;AACF,cAAQ,IAAI,aAAaE,CAAS;AAGlC,UAAIG,IAAiB;AAErB,YAAMC,IAAW,MAAMC,EAAYC,EAAe,WAAW,GAAG;AAAA,QAC9D,QAAQC,KAAe;AAAA,QACvB,QAAQP;AAAA,MAAA,CACT;AACD,cAAQ,IAAI,gBAAgBI,CAAQ,GAGpCD,IAAYC,GAAU;AACtB,YAAMI,IAAaJ,GAAU,QAAQ,CAAA;AAIrC,UAFA,QAAQ,KAAK,cAAcD,CAAS,GAEhC,CAACA,KAAa,CAACA,EAAU,SAAS;AACpC,cAAMM,IAAW,qBAAqBT,CAAS;AAC/C,sBAAQ,MAAMS,CAAQ,GAChB,IAAI,MAAMA,CAAQ;AAAA,MAC1B;AAEA,cAAQ,IAAI,cAAcN,CAAS,GACnC,QAAQ,IAAI,UAAUK,CAAU;AAShC,YAAME,KANkB,CAACC,MAGhB,0BAA0BA,CAAS,IAGFR,EAAU,OAAO;AAC3D,cAAQ,IAAI,eAAeO,CAAiB;AAG5C,YAAME,IAAuB;AAAA,QAC3B,SAAS,SAAS,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAClC,SAAS,EAAE,EACX,OAAO,GAAG,CAAC,CAAC;AAAA,QACf,WAAAZ;AAAA,QACA,YAAYG,EAAU,UAAU;AAAA,QAChC,UAAUO;AAAA,QACV,aAAaT;AAAA,QACb,OAAOE,EAAU,YAAY;AAAA,QAC7B,QAAQA,EAAU,YAAY;AAAA,QAC9B,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAAK;AAAA;AAAA,QACA,QAAAN;AAAA,MAAA;AAGF,cAAQ,IAAI,eAAeU,CAAS;AAGpC,YAAMC,IAAgBd,IAAM,OAAO,KAAK,CAACe,MAAMA,EAAE,cAAcd,CAAS;AACxE,UAAIa,GAAe;AACjB,gBAAQ,IAAI,eAAeA,EAAc,OAAO,GAEhDf,EAAI;AAAA,UACF,eAAee,EAAc;AAAA,UAC7B,QAAQd,IAAM,OAAO;AAAA,YAAI,CAACe,MACxBA,EAAE,YAAYD,EAAc,UAAU,EAAE,GAAGC,GAAG,QAAAZ,MAAmBY;AAAA,UAAA;AAAA,UAEnE,WAAW;AAAA,QAAA,CACZ;AACD;AAAA,MACF;AAGA,cAAQ,IAAI,YAAYF,EAAU,OAAO,GACzCd,EAAI,CAACiB,OAAW;AAAA,QACd,QAAQ,CAAC,GAAGA,EAAM,QAAQH,CAAS;AAAA,QACnC,eAAeA,EAAU;AAAA,QACzB,WAAW;AAAA,MAAA,EACX,GAEF,QAAQ,IAAI,aAAaA,CAAS;AAAA,IACpC,SAASI,GAAO;AACd,cAAQ,MAAM,aAAaA,CAAK,GAChClB,EAAI;AAAA,QACF,OAAOkB,aAAiB,QAAQA,EAAM,UAAU;AAAA,QAChD,WAAW;AAAA,MAAA,CACZ;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAGA,YAAY,CAACC,MAAoB;AAC/B,UAAM,EAAE,QAAAC,GAAQ,eAAAC,EAAA,IAAkBpB,EAAA,GAC5BqB,IAAYF,EAAO,OAAO,CAACJ,MAAMA,EAAE,YAAYG,CAAO;AAG5D,QAAII,IAAmBF;AACvB,IAAIA,MAAkBF,MACpBI,IACED,EAAU,SAAS,IAAIA,EAAUA,EAAU,SAAS,CAAC,EAAE,UAAU,OAGrEtB,EAAI;AAAA,MACF,QAAQsB;AAAA,MACR,eAAeC;AAAA,IAAA,CAChB;AAAA,EACH;AAAA;AAAA,EAGA,gBAAgB,MAAM;AACpB,IAAAvB,EAAI;AAAA,MACF,QAAQ,CAAA;AAAA,MACR,eAAe;AAAA,IAAA,CAChB;AAAA,EACH;AAAA;AAAA,EAGA,gBAAgB,CAACmB,MAAoB;AACnC,IAAAnB,EAAI,EAAE,eAAemB,GAAS;AAAA,EAChC;AAAA;AAAA,EAGA,mBAAmB,CAACA,GAAiBf,MAAiC;AACpE,IAAAJ,EAAI,CAACiB,OAAW;AAAA,MACd,QAAQA,EAAM,OAAO;AAAA,QAAI,CAACD,MACxBA,EAAE,YAAYG,IAAU,EAAE,GAAGH,GAAG,QAAQ,EAAE,GAAGA,EAAE,QAAQ,GAAGZ,EAAA,MAAaY;AAAA,MAAA;AAAA,IACzE,EACA;AAAA,EACJ;AACF,EAAE;"}
@@ -1,3 +0,0 @@
1
- "use strict";const j=require("axios"),c=require("crypto-js"),N=require("antd"),We=require("zustand"),P=require("./envUtils-CduTHoHu.cjs"),x=e=>typeof e!="string"?!e:e.trim().length===0,q=(e,t)=>x(e)?t:e||"",$e=e=>!x(e),F=(e,t,r="...")=>e.length<=t?e:e.substring(0,t)+r,H=e=>x(e)?e:e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),z=e=>x(e)?e:e.split(" ").map(t=>H(t)).join(" "),J=e=>e.replace(/-([a-z])/g,t=>t[1].toUpperCase()),V=e=>e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`),Z=e=>e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`),X=e=>{const r=e.replace(/\D/g,"").match(/^(\d{3})(\d{4})(\d{4})$/);return r?`${r[1]}-${r[2]}-${r[3]}`:e},Y=e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e),Q=e=>{try{return new URL(e),!0}catch{return!1}},ee=e=>e.replace(/\D/g,""),te=e=>e.replace(/[^a-zA-Z0-9가-힣\s]/g,""),re=e=>e.replace(/<[^>]*>/g,""),ne=e=>e.replace(/\n/g,"<br>"),se=e=>e.replace(/<br\s*\/?>/gi,`
2
- `),oe=(e,t)=>{const r=e.match(t);return r||[]},He=(e,t)=>e.repeat(t),ae=(e,t,r=" ")=>e.padStart(t,r),ce=(e,t,r=" ")=>e.padEnd(t,r),ie=(e,t,r=" ")=>{const n=t-e.length;if(n<=0)return e;const s=Math.floor(n/2),o=n-s;return r.repeat(s)+e+r.repeat(o)},A=(e,t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")=>{let r="";for(let n=0;n<e;n++)r+=t.charAt(Math.floor(Math.random()*t.length));return r},ue=e=>e.split("").reverse().join(""),le=(e,t)=>(e.match(new RegExp(t,"g"))||[]).length,de=e=>e.trim().split(/\s+/).length,ge=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)}),R=(e=32)=>{const r=ge().replace(/-/g,"");return e>=32?r+A(e-32,"0123456789abcdef"):r.substring(0,e)},me=()=>R(16),pe=()=>R(64),he=(e=16)=>A(e,"0123456789"),fe=(e=16)=>A(e,"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),B=()=>ge(),G=()=>B().replace(/-/g,""),Se=()=>{const e=Date.now().toString(36),t=A(8,"0123456789abcdef");return e+t},Ce=(e,t="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")=>e.replace(/[X-Z]/g,()=>t.charAt(Math.floor(Math.random()*t.length))),ye=e=>{const t=c.SHA256(e);return c.enc.Base64.stringify(t)},k=()=>"abcdefghij1234567890!@#$%^&*();;",Ie=()=>"123456098765!@#$",Ue=e=>{if(!e)return"";try{const t=c.enc.Utf8.parse(k()),r=c.enc.Utf8.parse(Ie());return c.AES.encrypt(e,t,{iv:r,padding:c.pad.Pkcs7,mode:c.mode.CBC}).toString()}catch(t){return console.error("암호화 오류:",t),""}},Ne=e=>{if(!e)return"";try{const t=c.enc.Utf8.parse(k()),r=c.enc.Utf8.parse(Ie());return c.AES.decrypt(e,t,{iv:r,padding:c.pad.Pkcs7,mode:c.mode.CBC}).toString(c.enc.Utf8)}catch(t){return console.error("복호화 오류:",t),""}},De=(e,t)=>{if(!e)return"";try{const r=t||k();return c.AES.encrypt(e,r).toString()}catch(r){return console.error("간단한 암호화 오류:",r),""}},Ee=(e,t)=>{if(!e)return"";try{const r=t||k();return c.AES.decrypt(e,r).toString(c.enc.Utf8)}catch(r){return console.error("간단한 복호화 오류:",r),""}},we=e=>e?c.MD5(e).toString():"",ve=e=>e?c.SHA256(e).toString():"",be=e=>e?c.enc.Base64.stringify(c.enc.Utf8.parse(e)):"",xe=e=>{if(!e)return"";try{return c.enc.Base64.parse(e).toString(c.enc.Utf8)}catch(t){return console.error("Base64 디코딩 오류:",t),""}},Be=Object.freeze(Object.defineProperty({__proto__:null,base64Decode:xe,base64Encode:be,br2nl:se,bxmDecrypt:Ne,bxmEncrypt:Ue,capitalize:H,capitalizeWords:z,center:ie,countChar:le,countWords:de,encryptSha256:ye,extractNumbers:ee,findPattern:oe,formatPhoneNumber:X,generateAlphanumericUID:fe,generateCustomUID:Ce,generateGUID:B,generateGUIDWithoutHyphens:G,generateLongUID:pe,generateNumericUID:he,generateRandomString:A,generateShortUID:me,generateTimestampUID:Se,generateUID:R,isEmpty:x,isNotEmpty:$e,isSafeEmpty:q,isValidEmail:Y,isValidUrl:Q,md5Hash:we,nl2br:ne,padLeft:ae,padRight:ce,removeHtmlTags:re,removeSpecialChars:te,repeat:He,reverse:ue,sha256Hash:ve,simpleDecrypt:Ee,simpleEncrypt:De,toCamelCase:J,toKebabCase:Z,toSnakeCase:V,truncate:F},Symbol.toStringTag,{value:"Module"})),f={duration:4.5,placement:"topRight"};class v{constructor(){}static getInstance(){return v.instance||(v.instance=new v),v.instance}showBwgError(t){const{message:r,description:n,errorCode:s,duration:o=f.duration,placement:m=f.placement}=t;s?.startsWith("BXM")?N.notification.error({message:`${r}`,description:n||"오류가 발생했습니다. 다시 시도해주세요.",duration:o,placement:m,style:{borderLeft:"4px solid #ff4d4f",backgroundColor:"#fff2f0"}}):N.notification.warning({message:`${r}`,description:n||"오류가 발생했습니다. 다시 시도해주세요.",duration:o,placement:m,style:{borderLeft:"4px solid #ff4d4f",backgroundColor:"#fff2f0"}})}showSuccess(t,r,n){N.notification.success({message:`${t}`,description:r,duration:n||f.duration,placement:f.placement})}showInfo(t,r,n){N.notification.info({message:`${t}`,description:r,duration:n||f.duration,placement:f.placement})}showWarning(t,r,n){N.notification.warning({message:`${t}`,description:r,duration:n||f.duration,placement:f.placement})}showError(t,r,n){N.notification.error({message:`${t}`,description:r,duration:n||f.duration,placement:f.placement})}destroy(){N.notification.destroy()}close(t){N.notification.destroy()}}const D=v.getInstance(),Ge=e=>{D.showBwgError(e)},Ke=(e,t,r)=>{D.showSuccess(e,t,r)},je=(e,t,r)=>{D.showInfo(e,t,r)},qe=(e,t,r)=>{D.showWarning(e,t,r)},Fe=(e,t,r)=>{D.showError(e,t,r)},ze=()=>{D.destroy()},Je=e=>{D.close(e)};(void 0).DEV;function Ve(e,t){let r;try{r=e()}catch{return}return{getItem:s=>{var o;const m=h=>h===null?null:JSON.parse(h,void 0),S=(o=r.getItem(s))!=null?o:null;return S instanceof Promise?S.then(m):m(S)},setItem:(s,o)=>r.setItem(s,JSON.stringify(o,void 0)),removeItem:s=>r.removeItem(s)}}const W=e=>t=>{try{const r=e(t);return r instanceof Promise?r:{then(n){return W(n)(r)},catch(n){return this}}}catch(r){return{then(n){return this},catch(n){return W(n)(r)}}}},Ze=(e,t)=>(r,n,s)=>{let o={storage:Ve(()=>localStorage),partialize:a=>a,version:0,merge:(a,U)=>({...U,...a}),...t},m=!1;const S=new Set,h=new Set;let i=o.storage;if(!i)return e((...a)=>{console.warn(`[zustand persist middleware] Unable to update item '${o.name}', the given storage is currently unavailable.`),r(...a)},n,s);const C=()=>{const a=o.partialize({...n()});return i.setItem(o.name,{state:a,version:o.version})},l=s.setState;s.setState=(a,U)=>(l(a,U),C());const u=e((...a)=>(r(...a),C()),n,s);s.getInitialState=()=>u;let d;const I=()=>{var a,U;if(!i)return;m=!1,S.forEach(g=>{var y;return g((y=n())!=null?y:u)});const w=((U=o.onRehydrateStorage)==null?void 0:U.call(o,(a=n())!=null?a:u))||void 0;return W(i.getItem.bind(i))(o.name).then(g=>{if(g)if(typeof g.version=="number"&&g.version!==o.version){if(o.migrate){const y=o.migrate(g.state,g.version);return y instanceof Promise?y.then(_=>[!0,_]):[!0,y]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,g.state];return[!1,void 0]}).then(g=>{var y;const[_,_e]=g;if(d=o.merge(_e,(y=n())!=null?y:u),r(d,!0),_)return C()}).then(()=>{w?.(d,void 0),d=n(),m=!0,h.forEach(g=>g(d))}).catch(g=>{w?.(void 0,g)})};return s.persist={setOptions:a=>{o={...o,...a},a.storage&&(i=a.storage)},clearStorage:()=>{i?.removeItem(o.name)},getOptions:()=>o,rehydrate:()=>I(),hasHydrated:()=>m,onHydrate:a=>(S.add(a),()=>{S.delete(a)}),onFinishHydration:a=>(h.add(a),()=>{h.delete(a)})},o.skipHydration||I(),d||u},Ae=Ze,p=We.create()(Ae((e,t)=>({user:null,isLoggedIn:!1,login:r=>{e({user:r,isLoggedIn:!0}),console.log("사용자 로그인:",r)},logout:()=>{e({user:null,isLoggedIn:!1}),console.log("사용자 로그아웃")},updateUser:r=>{const n=t().user;n&&e({user:{...n,...r}})}}),{name:"user-storage",partialize:e=>({user:e.user,isLoggedIn:e.isLoggedIn})})),Xe=()=>p.getState().user?.crprCd||null,Te=()=>p.getState().user?.userId||null,Le=()=>p.getState().user?.userNm||null,Ye=()=>p.getState().user?.userDvsn||null,Qe=()=>p.getState().user?.emplNo||null,Pe=()=>p.getState().user?.dprtCd||null,Oe=()=>p.getState().user?.dprtNm||null,M=()=>p.getState().user?.roleList||null,et=e=>{const t=M();return t?t.includes(e):!1},tt=e=>{const t=M();return t?e.some(r=>t.includes(r)):!1},rt=e=>{const t=M();return t?e.every(r=>t.includes(r)):!1},nt=()=>p.getState().isLoggedIn,K=()=>p.getState().user,st=()=>K()!==null,ot=()=>{const e=Le(),t=Te();return e||t||null},at=()=>{const e=Oe(),t=Pe();return e||(t?String(t):null)};let O=null;const ct=e=>{O===null&&(O=e)},it=()=>O,ut=async()=>(console.log("IP 검증 비활성화됨 (성능 최적화)"),O||"unknown");class E extends Error{constructor(t,r,n,s){super(t),this.name="ApiError",this.detailMsg=r,this.response=n,this.msgCd=s,Error.captureStackTrace&&Error.captureStackTrace(this,E)}}const $={method:"POST",timeout:3e4,withCredentials:!0,showLoading:!0,showError:!0,retryCount:3,retryDelay:1e3},b=j.create({timeout:$.timeout,withCredentials:$.withCredentials,headers:{"Content-Type":"application/json; charset=utf-8",Accept:"application/json; charset=utf-8"}});P.isLocal&&(console.log("🔧 API Client Configuration:"),console.log(" - Timeout:",b.defaults.timeout),console.log(" - With Credentials:",b.defaults.withCredentials),console.log(" - Environment:",P.getEnvCode()));b.interceptors.request.use(e=>{let t="UNKNOWN",r="UNKNOWN";new Date().getTime();try{e.data&&e.data.header?(t=e.data.header.trxCd||"UNKNOWN",r=e.data.header.guid||"UNKNOWN"):e.params&&e.params.header&&(t=e.params.header.trxCd||"UNKNOWN",r=e.params.header.guid||"UNKNOWN")}catch(s){console.warn("trxCd/guid 추출 실패:",s)}e.trxCd=t,e.guid=r,e.requestStartTime=Date.now(),console.log(`🚀 API 요청 시작 [거래코드: ${t} / GUID: ${r}]`);const n=localStorage.getItem("accessToken");return n&&(e.headers.Authorization=`Bearer ${n}`),e.headers["Content-Type"]="application/json; charset=UTF-8",e.headers.Accept="application/json; charset=UTF-8",e},e=>(console.error("❌ 요청 인터셉터 에러:",e),Promise.reject(e)));b.interceptors.response.use(e=>{let t="UNKNOWN",r="UNKNOWN";const n=new Date().getTime();try{e.config.trxCd&&(t=e.config.trxCd),e.config.guid?r=e.config.guid:e.data&&e.data.header&&e.data.header.trxCd?(t=e.data.header.trxCd,r=e.data.header.guid||"UNKNOWN"):e.config.data&&e.config.data.header?(t=e.config.data.header.trxCd||"UNKNOWN",r=e.config.data.header.guid||"UNKNOWN"):e.config.params&&e.config.params.header&&(t=e.config.params.header.trxCd||"UNKNOWN",r=e.config.params.header.guid||"UNKNOWN")}catch(o){console.warn("trxCd/guid 추출 실패:",o)}let s=0;return e.config.requestStartTime&&(s=n-e.config.requestStartTime),console.log(`✅ API 응답 성공 [거래코드: ${t} / GUID : ${r}] - (소요시간: ${s}ms)`),e},async e=>{if(console.error("❌ API 응답 에러:",e),P.isLocal&&console.error("🚨 Error Details:",{message:e.message,status:e.response?.status,statusText:e.response?.statusText,data:e.response?.data,config:{url:e.config?.url,method:e.config?.method,baseURL:e.config?.baseURL}}),e.response?.status===401){const t=localStorage.getItem("refreshToken");if(t)try{const r=await j.post("/auth/refresh",{refreshToken:t});if(r.data.accessToken){localStorage.setItem("accessToken",r.data.accessToken);const n=e.config;if(n)return n.headers.Authorization=`Bearer ${r.data.accessToken}`,b(n)}}catch{localStorage.removeItem("accessToken"),localStorage.removeItem("refreshToken"),window.location.href="/login"}}return Promise.reject(e)});const Re=()=>G(),T=async(e,t,r)=>{try{const n={...$,...r},s={method:n.method,url:"/api/service",timeout:n.timeout,withCredentials:n.withCredentials};n.headers&&(s.headers=n.headers);const o=O||"unknown",m=__APP_CD__,S=__SYS_CD__;console.log("@@ request param :: ",t);const h={header:{trxCd:e,guid:Re(),userInfo:K(),clientIp:o,domainId:"DEFAULT",appCd:m,sysCd:S},data:t};P.isLocal&&(console.log("__BWG_LOCAL__ 테스트 입니다. ",P.isLocal),console.log("📤 Request Data:",h)),n.method==="GET"?s.params=h||n.params:(s.data=h||n.data,n.params&&(s.params=n.params));let i;for(let C=0;C<=(n.retryCount||0);C++)try{const l=await b(s);if(l.data.header?.resCd==0){for(const u in l.data)if(u!=="header")return l.data[u];return{}}else{const u=l.data.header,d=u?.msgs?.basicMsg||"요청 처리 중 오류가 발생했습니다.",I=u?.msgs?.detailMsgs||d,a=u?.msgCd;throw new E(d,I,l,a)}}catch(l){if(l.isAxiosError&&l.response){const u=l,d=u.response,I=d.data,a=I?.header?.msgs?.basicMsg||u.message||"서버에서 오류가 발생했습니다.",U=I?.header?.msgs?.detailMsgs||(typeof d.data=="string"?d.data:JSON.stringify(d.data))||a,w=I?.header?.msgCd;i=new E(a,U,d,w)}else i=l;if(l.isAxiosError&&lt(l)&&C<(n.retryCount||0)){await dt(n.retryDelay||1e3);continue}break}if(i){if(n.showError){const C=i instanceof E?i.message:"요청 처리 중 오류가 발생했습니다.",l=i instanceof E?i.msgCd:"요청 처리 중 오류가 발생했습니다.",u=i instanceof E?i.detailMsg:i.message;Ge({message:C,errorCode:l,description:u,duration:5})}throw i}throw new Error("알 수 없는 API 오류가 발생했습니다.")}catch(n){throw console.error("callService 최종 에러:",n),n}},lt=e=>!e.response||e.response.status>=500&&e.response.status<600,dt=e=>new Promise(t=>setTimeout(t,e)),gt=(e,t,r)=>T(e,t,{...r,method:"GET"}),mt=(e,t,r)=>T(e,t,{...r,method:"POST"}),pt=(e,t,r)=>T(e,t,{...r,method:"PUT"}),ht=(e,t,r)=>T(e,t,{...r,method:"DELETE"}),ft=(e,t,r)=>T(e,t,{...r,method:"PATCH"}),ke={AUTH_BTNS:"SCMSIGN00202",AUTH_MENU:"SCMSIGN00201",SRCH_CODE:"SCMSIGN00301",SRCH_POPU:"SCMPOPU00101",AUTH_BMRK:"SCMBMRK00101"};let L={};function St(e){L=e,console.log("🔧 Provider 서비스코드 오버라이드 설정:",e)}function Me(e){if(L[e]&&L[e].trim()!=="")return console.log(`🔧 Provider 설정 사용: ${e} = ${L[e]}`),L[e];const t=ke[e];return console.log(`🔧 기본값 사용: ${e} = ${t}`),t}function Ct(){const e={};for(const t of Object.keys(ke))e[t]=Me(t);return e}exports.apiDelete=ht;exports.apiGet=gt;exports.apiPatch=ft;exports.apiPost=mt;exports.apiPut=pt;exports.base64Decode=xe;exports.base64Encode=be;exports.br2nl=se;exports.bxmDecrypt=Ne;exports.bxmEncrypt=Ue;exports.callService=T;exports.capitalize=H;exports.capitalizeWords=z;exports.center=ie;exports.closeNotification=Je;exports.countChar=le;exports.countWords=de;exports.destroyNotifications=ze;exports.encryptSha256=ye;exports.extractNumbers=ee;exports.findPattern=oe;exports.formatPhoneNumber=X;exports.generateAlphanumericUID=fe;exports.generateCustomUID=Ce;exports.generateGUID=B;exports.generateGUIDWithoutHyphens=G;exports.generateLongUID=pe;exports.generateNumericUID=he;exports.generateRandomString=A;exports.generateShortUID=me;exports.generateTimestampUID=Se;exports.generateUID=R;exports.getAllServiceCodes=Ct;exports.getClientIp=it;exports.getCrprCd=Xe;exports.getDepartmentInfo=at;exports.getDisplayName=ot;exports.getDprtCd=Pe;exports.getDprtNm=Oe;exports.getEmplNo=Qe;exports.getGuid=Re;exports.getRoleList=M;exports.getServiceCode=Me;exports.getUserDvsn=Ye;exports.getUserId=Te;exports.getUserInfo=K;exports.getUserNm=Le;exports.hasAllRoles=rt;exports.hasAnyRole=tt;exports.hasRole=et;exports.hasUserInfo=st;exports.isEmpty=x;exports.isLoggedIn=nt;exports.isSafeEmpty=q;exports.isValidEmail=Y;exports.isValidUrl=Q;exports.md5Hash=we;exports.nl2br=ne;exports.notificationService=D;exports.padLeft=ae;exports.padRight=ce;exports.persist=Ae;exports.removeHtmlTags=re;exports.removeSpecialChars=te;exports.reverse=ue;exports.setClientIp=ct;exports.setServiceCodeOverrides=St;exports.sha256Hash=ve;exports.showError=Fe;exports.showInfo=je;exports.showSuccess=Ke;exports.showWarning=qe;exports.simpleDecrypt=Ee;exports.simpleEncrypt=De;exports.stringUtils=Be;exports.toCamelCase=J;exports.toKebabCase=Z;exports.toSnakeCase=V;exports.truncate=F;exports.useUserStore=p;exports.verifyClientIp=ut;
3
- //# sourceMappingURL=serviceConfig-9dHegQIK.cjs.map