@thefreshop/tb 1.0.15 → 1.0.17

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.
package/dist/cjs/index.js CHANGED
@@ -42,18 +42,17 @@ const tbContext = React.createContext(undefined);
42
42
  const SESSION_STORAGE_KEY = "tbFrameState";
43
43
  const TbProvider = ({ children }) => {
44
44
  const [topkey, setTopkey] = React.useState("");
45
- const [currentTab, setCurrentTab] = React.useState();
45
+ const [tabList, setTabList] = React.useState([]);
46
+ const [currentTabKey, setCurrentTabKey] = React.useState();
47
+ const [startTabKey, setStartTabKey] = React.useState();
46
48
  const [user, setloginUser] = React.useState();
47
- // const [tabs, setTabs] = useState<tabType[]>([]);
48
- const [startpage, setStartpage] = React.useState();
49
49
  const [errMsg, setErrMsg] = React.useState();
50
- const [globalpages, setGlobalpages] = React.useState();
51
- const [menupages, setMenupages] = React.useState();
52
50
  // 1. 초기 상태를 sessionStorage 불러오도록 수정
53
- const [tabs, setTabs] = React.useState(() => {
51
+ const [tabKeys, setTabKeys] = React.useState(() => {
54
52
  try {
55
53
  const savedState = sessionStorage.getItem(SESSION_STORAGE_KEY);
56
- return savedState ? JSON.parse(savedState).tabs : [];
54
+ const tt = savedState ? JSON.parse(savedState).tabs : [];
55
+ return tt === undefined ? [] : tt;
57
56
  }
58
57
  catch (error) {
59
58
  console.error("Failed to parse state from sessionStorage", error);
@@ -62,50 +61,33 @@ const TbProvider = ({ children }) => {
62
61
  });
63
62
  // 2. 상태가 변경될 때마다 sessionStorage 저장하는 useEffect 추가
64
63
  React.useEffect(() => {
65
- // page 속성(React 컴포넌트) 제외하고 sessionStorage에 저장
66
- const tabsToSave = tabs.map(({ page, ...rest }) => rest);
67
- const stateToSave = {
68
- tabs: tabsToSave,
69
- // ... 저장할 다른 상태들 ...
70
- };
71
- sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(stateToSave)); // 순환 구조 오류 방지
72
- }, [tabs, currentTab /* ... 다른 상태 의존성 ... */]);
73
- const addTabs = (tab) => {
74
- setCurrentTab(tab);
75
- if (tabs.find((m) => m.key === tab.key) === undefined) {
76
- setTabs([...tabs, tab]);
64
+ // 불러올 때의 데이터 구조({ tabs: ... }) 일치시키기 위해 객체 형태로 저장
65
+ const stateToSave = { tabs: tabKeys };
66
+ sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(stateToSave));
67
+ }, [tabKeys, currentTabKey /* ... 다른 상태 의존성 ... */]);
68
+ const addTabKey = (key) => {
69
+ setCurrentTabKey(key);
70
+ if (tabKeys.find((m) => m === key) === undefined) {
71
+ setTabKeys([...tabKeys, key]);
77
72
  }
78
73
  };
79
- const removeTabs = (tab) => {
74
+ const removeTabKey = (key) => {
80
75
  // console.log('tab', tab)
81
- let newTabs = [...tabs];
82
- const itemToFind = newTabs.find((m) => m.key === tab.key);
76
+ let newTabs = [...tabKeys];
77
+ const itemToFind = newTabs.find((m) => m === key);
83
78
  if (itemToFind !== undefined) {
84
79
  const idx = newTabs.indexOf(itemToFind);
85
80
  if (idx > -1)
86
81
  newTabs.splice(idx, 1);
87
- setTabs(newTabs);
82
+ setTabKeys(newTabs);
88
83
  // console.log('newTabs', newTabs)
89
- if (currentTab === tab) {
90
- setCurrentTab(newTabs[idx === 0 ? 0 : idx - 1]);
84
+ if (currentTabKey === key) {
85
+ setCurrentTabKey(newTabs[idx === 0 ? 0 : idx - 1]);
91
86
  }
92
87
  }
93
88
  };
94
89
  const loginUser = (user) => {
95
90
  if (user !== null) {
96
- if (startpage) {
97
- addTabs({
98
- title: "HOME",
99
- key: "HOME",
100
- page: startpage,
101
- noremove: true,
102
- });
103
- setCurrentTab({
104
- title: "HOME",
105
- key: "HOME",
106
- page: startpage,
107
- });
108
- }
109
91
  if (user?.user_group?.group_section_start) {
110
92
  setTopkey(user?.user_group?.group_section_start);
111
93
  }
@@ -117,63 +99,49 @@ const TbProvider = ({ children }) => {
117
99
  };
118
100
  const logout = (force = false) => {
119
101
  setloginUser(undefined);
120
- setCurrentTab(undefined);
121
- setTabs([]);
102
+ setCurrentTabKey(undefined);
103
+ setTabKeys([]);
122
104
  setTopkey("");
123
105
  if (force)
124
106
  window.location.reload();
125
107
  };
126
- const addGlobalTabs = (key) => {
127
- // console.log(key)
128
- const newtab = globalpages?.find((m) => {
129
- return m.key === key;
130
- });
131
- // console.log(globalpages, newtab)
132
- if (newtab) {
133
- addTabs(newtab);
134
- }
135
- };
136
- const goTabs = (key) => {
137
- let gotab;
138
- menupages?.menuSet.forEach((item) => {
139
- item.menuSetting.forEach((sub) => {
140
- sub.children?.forEach((page) => {
141
- if (page.tab.key === key)
142
- gotab = page;
143
- });
144
- });
145
- });
146
- if (gotab) {
147
- addTabs(gotab);
148
- }
149
- const newtab = globalpages?.find((m) => {
150
- return m.key === key;
151
- });
152
- // console.log(globalpages, newtab)
153
- if (newtab) {
154
- addTabs(newtab);
155
- }
156
- };
108
+ // const goTabKey = (key: string) => {
109
+ // let gotab;
110
+ // menupages?.menuSet.forEach((item: menuSetType) => {
111
+ // item.menuSetting.forEach((sub) => {
112
+ // sub.children?.forEach((page) => {
113
+ // if (page.tab.key === key) gotab = page;
114
+ // });
115
+ // });
116
+ // });
117
+ // if (gotab) {
118
+ // addTabKey(gotab);
119
+ // }
120
+ // const newtab = globalpages?.find((m) => {
121
+ // return m.key === key;
122
+ // });
123
+ // // console.log(globalpages, newtab)
124
+ // if (newtab) {
125
+ // addTabKey(newtab);
126
+ // }
127
+ // };
157
128
  return (React.createElement(tbContext.Provider, { value: {
158
129
  topkey,
159
130
  setTopkey,
160
- tabs,
161
- addTabs,
162
- removeTabs,
163
- currentTab,
164
- setCurrentTab,
131
+ tabKeys,
132
+ removeTabKey,
133
+ currentTabKey,
134
+ setCurrentTabKey,
135
+ addTabKey,
165
136
  loginUser,
166
137
  logout,
167
138
  user,
168
- startpage,
169
- setStartpage,
139
+ startTabKey,
140
+ setStartTabKey,
170
141
  SetWarning,
171
142
  errMsg,
172
- setGlobalpages,
173
- globalpages,
174
- addGlobalTabs,
175
- setMenupages,
176
- goTabs,
143
+ tabList,
144
+ setTabList,
177
145
  } }, children));
178
146
  };
179
147
  const useTbState = () => {
@@ -223,7 +191,8 @@ var styles$8 = {"topframe":"top-module_topframe__LhKDg","top_left":"top-module_t
223
191
  styleInject(css_248z$a);
224
192
 
225
193
  const Top = ({ setting, top: { title = topbase.title, titleimage, topMenuSetting, menuStyle, imgstyle, titleStyle, topRight }, }) => {
226
- const { logout, user, setCurrentTab, startpage } = useTbState();
194
+ const { logout, user, addTabKey, setCurrentTabKey } = useTbState();
195
+ const navigate = reactRouter.useNavigate();
227
196
  const userTop = () => {
228
197
  let topmenutable = [];
229
198
  if (user?.user_group?.group_key === "master" || setting.islogin === false) {
@@ -243,12 +212,11 @@ const Top = ({ setting, top: { title = topbase.title, titleimage, topMenuSetting
243
212
  };
244
213
  return (React.createElement("div", { className: styles$8.topframe },
245
214
  React.createElement("div", { className: styles$8.top_left, style: { cursor: "pointer" }, onClick: () => {
246
- if (startpage)
247
- setCurrentTab({
248
- title: "startpage",
249
- key: "startpage",
250
- page: startpage,
251
- });
215
+ if (setting?.startTabKey) {
216
+ addTabKey(setting?.startTabKey);
217
+ setCurrentTabKey(setting?.startTabKey);
218
+ navigate("/" + setting?.startTabKey);
219
+ }
252
220
  console.log("home");
253
221
  } },
254
222
  titleimage ? React.createElement("img", { src: titleimage, className: styles$8.toplogo, alt: "logo", style: imgstyle }) : null,
@@ -296,7 +264,7 @@ const Menu = ({ menu_setting: { tab, icon, children, hasPage, defalultOpen }, op
296
264
  const { title, key, page } = tab;
297
265
  const [hover, setHover] = React.useState(false);
298
266
  const [subOpen, setSubOpen] = React.useState(false);
299
- const { addTabs, currentTab, user } = useTbState();
267
+ const { addTabKey, currentTabKey, user } = useTbState();
300
268
  const navigate = reactRouter.useNavigate();
301
269
  React.useEffect(() => {
302
270
  if (defalultOpen) {
@@ -323,18 +291,14 @@ const Menu = ({ menu_setting: { tab, icon, children, hasPage, defalultOpen }, op
323
291
  return usersubmenutable;
324
292
  };
325
293
  return (React.createElement("div", null,
326
- React.createElement("div", { className: `${styles$9.nav_item} ${currentTab?.key === key ? styles$9.menu_select : hover ? styles$9.menu_hover : styles$9.menu_nomal}`, onMouseEnter: () => {
294
+ React.createElement("div", { className: `${styles$9.nav_item} ${currentTabKey === key ? styles$9.menu_select : hover ? styles$9.menu_hover : styles$9.menu_nomal}`, onMouseEnter: () => {
327
295
  setHover(true);
328
296
  }, onMouseLeave: () => {
329
297
  setHover(false);
330
298
  }, onClick: () => {
331
299
  setSubOpen((prev) => !prev);
332
- if (hasPage && currentTab?.key !== key) {
333
- addTabs({
334
- title,
335
- key,
336
- page,
337
- });
300
+ if (hasPage && currentTabKey !== key) {
301
+ addTabKey(key);
338
302
  navigate("/" + key);
339
303
  }
340
304
  // console.log(tabs)
@@ -347,19 +311,15 @@ const Menu = ({ menu_setting: { tab, icon, children, hasPage, defalultOpen }, op
347
311
  const SubMenu = ({ menu_setting: { tab, icon, hasPage } }) => {
348
312
  const { title, key, page } = tab;
349
313
  const [hover, setHover] = React.useState(false);
350
- const { addTabs, currentTab } = useTbState();
314
+ const { addTabKey, currentTabKey } = useTbState();
351
315
  const navigate = reactRouter.useNavigate();
352
- return (React.createElement("div", { className: `${styles$9.sub_item} ${currentTab?.key === key ? styles$9.menu_select : hover ? styles$9.menu_hover : styles$9.menu_nomal}`, onMouseEnter: () => {
316
+ return (React.createElement("div", { className: `${styles$9.sub_item} ${currentTabKey === key ? styles$9.menu_select : hover ? styles$9.menu_hover : styles$9.menu_nomal}`, onMouseEnter: () => {
353
317
  setHover(true);
354
318
  }, onMouseLeave: () => {
355
319
  setHover(false);
356
320
  }, onClick: () => {
357
- if (hasPage && currentTab?.key !== key)
358
- addTabs({
359
- title,
360
- key,
361
- page,
362
- });
321
+ if (hasPage && currentTabKey !== key)
322
+ addTabKey(key);
363
323
  navigate("/" + key);
364
324
  // console.log(tabs)
365
325
  } },
@@ -372,9 +332,10 @@ var styles$7 = {"bottom_item":"bottom-module_bottom_item__fac0H"};
372
332
  styleInject(css_248z$9);
373
333
 
374
334
  const Bottom = ({ bottom }) => {
375
- const { currentTab, user } = useTbState();
335
+ const { currentTabKey, user, tabList } = useTbState();
336
+ const tab = tabList.find((tab) => tab.key === currentTabKey);
376
337
  return (React.createElement("div", { className: styles$7.bottom_item },
377
- React.createElement("div", null, currentTab?.title),
338
+ React.createElement("div", null, tab?.title),
378
339
  React.createElement("div", { style: { display: "flex", gap: 16 } },
379
340
  React.createElement("div", null,
380
341
  user?.user_name ?? "이름없음",
@@ -390,53 +351,44 @@ var styles$6 = {"tabFrame":"tabs-module_tabFrame__qyHsD","tab_item":"tabs-module
390
351
  styleInject(css_248z$8);
391
352
 
392
353
  const Tabs = ({ nav: { menuSet, openIcon, closeIcon } }) => {
393
- const { tabs, removeTabs, setCurrentTab, addTabs, currentTab, globalpages } = useTbState();
354
+ const { tabList, tabKeys, removeTabKey, setCurrentTabKey, addTabKey, currentTabKey } = useTbState();
394
355
  const navigate = reactRouter.useNavigate();
395
356
  const location = reactRouter.useLocation();
396
357
  const findTabs = React.useCallback((pathKey) => {
397
358
  // 1. 현재 열린 탭 중에 있는지 확인
398
- const existingTab = tabs.find((t) => t.key === pathKey);
399
- if (existingTab) {
400
- setCurrentTab(existingTab);
359
+ const existingTabKey = tabKeys.find((key) => key === pathKey);
360
+ if (existingTabKey) {
361
+ setCurrentTabKey(existingTabKey);
401
362
  return;
402
363
  }
403
364
  // 2. 없다면, 전체 페이지 목록에서 찾아서 추가
404
365
  let tabInfo;
405
366
  // 2-1. 메뉴 페이지에서 찾기
406
367
  menuSet.forEach((item) => {
407
- item.menuSetting.forEach((sub) => {
408
- if (sub.tab.key === pathKey)
409
- tabInfo = sub;
410
- else {
411
- sub.children?.forEach((page) => {
412
- if (page.tab.key === pathKey)
413
- tabInfo = page;
414
- });
415
- }
368
+ tabList.forEach((tab) => {
369
+ if (tab.key === pathKey)
370
+ tabInfo = pathKey;
416
371
  });
417
372
  });
418
- // 2-2. 전역 페이지에서 찾기 (메뉴에 없으면)
419
- if (!tabInfo) {
420
- tabInfo = globalpages?.find((m) => m.key === pathKey);
421
- }
422
373
  if (tabInfo) {
423
- addTabs(tabInfo);
374
+ addTabKey(tabInfo);
424
375
  }
425
- }, [tabs, globalpages]);
376
+ }, [tabKeys]);
426
377
  // 3. 페이지 로드 시 URL을 기반으로 currentTab을 설정하는 useEffect 추가
427
378
  React.useEffect(() => {
428
379
  const pathKey = location.pathname.substring(1); // 맨 앞의 '/' 제거
429
380
  findTabs(pathKey);
430
381
  }, []);
431
- return (React.createElement("div", { className: styles$6.tabFrame }, tabs?.map((m) => {
432
- return (React.createElement("div", { key: m.key, className: `${styles$6.tab_item} ${currentTab?.key === m.key ? styles$6.tab_select : styles$6.tab_normal}` },
382
+ return (React.createElement("div", { className: styles$6.tabFrame }, tabKeys?.map((key) => {
383
+ const tab = tabList.find((tab) => tab.key === key);
384
+ return (React.createElement("div", { key: key, className: `${styles$6.tab_item} ${currentTabKey === key ? styles$6.tab_select : styles$6.tab_normal}` },
433
385
  React.createElement("div", { className: styles$6.tab_item_text, onClick: () => {
434
- setCurrentTab(m);
435
- navigate("/" + m.key);
386
+ setCurrentTabKey(key);
387
+ navigate("/" + key);
436
388
  // console.log('setCurrentTab', m)
437
- } }, m.title),
438
- !m.noremove && (React.createElement("div", { className: styles$6.tab_item_button },
439
- React.createElement("button", { className: styles$6.tab_x_button, onClick: () => removeTabs(m) }, "x")))));
389
+ } }, tab?.title),
390
+ !tab?.noremove && (React.createElement("div", { className: styles$6.tab_item_button },
391
+ React.createElement("button", { className: styles$6.tab_x_button, onClick: () => removeTabKey(key) }, "x")))));
440
392
  })));
441
393
  };
442
394
 
@@ -540,25 +492,32 @@ const NullPage = () => {
540
492
  };
541
493
 
542
494
  const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) => {
543
- const { user, startpage, setStartpage, errMsg, setGlobalpages, setMenupages } = useTbState();
495
+ const { user, errMsg, tabList, setTabList, startTabKey, setStartTabKey } = useTbState();
544
496
  React.useEffect(() => {
545
- if (setting.startpage) {
546
- setStartpage(setting.startpage);
547
- }
548
- }, [setting.startpage]);
549
- React.useEffect(() => {
550
- if (setting.globalpages) {
551
- setGlobalpages(setting.globalpages);
552
- }
553
- }, [setting.globalpages]);
554
- React.useEffect(() => {
555
- if (nav) {
556
- setMenupages(nav);
497
+ if (tabList.length === 0) {
498
+ let p_tabList = [];
499
+ nav.menuSet.forEach((item) => {
500
+ item.menuSetting.forEach((sub) => {
501
+ p_tabList.push(sub.tab);
502
+ sub.children?.forEach((page) => {
503
+ p_tabList.push(page.tab);
504
+ });
505
+ });
506
+ });
507
+ nav?.globalTabs?.forEach((item) => {
508
+ p_tabList.push(item);
509
+ });
510
+ setTabList(p_tabList);
557
511
  }
558
- }, [nav]);
512
+ }, [tabList]);
559
513
  React.useEffect(() => {
560
514
  if (!errMsg?.isPopup) ;
561
515
  }, [errMsg]);
516
+ React.useEffect(() => {
517
+ if (!startTabKey && setting?.startTabKey) {
518
+ setStartTabKey(setting?.startTabKey);
519
+ }
520
+ }, [setting.startTabKey]);
562
521
  const route = () => {
563
522
  let route = [];
564
523
  if (setting?.islogin) {
@@ -567,6 +526,12 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) =
567
526
  element: setting?.loginpage ? setting.loginpage : React.createElement(LoginPage, null),
568
527
  });
569
528
  }
529
+ nav.globalTabs?.forEach((item) => {
530
+ route.push({
531
+ path: "/" + item.key,
532
+ element: item.page,
533
+ });
534
+ });
570
535
  nav.menuSet.forEach((item) => {
571
536
  item.menuSetting.forEach((sub) => {
572
537
  route.push({
@@ -581,6 +546,11 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) =
581
546
  });
582
547
  });
583
548
  });
549
+ // 일치하는 라우트가 없을 경우 메인으로 리다이렉트
550
+ route.push({
551
+ path: "*",
552
+ element: React.createElement(reactRouter.Navigate, { to: "/", replace: true }),
553
+ });
584
554
  return route;
585
555
  };
586
556
  const router = React.useMemo(() => {
@@ -588,7 +558,7 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) =
588
558
  return reactRouter.createHashRouter([
589
559
  {
590
560
  path: "/",
591
- element: (React.createElement(MainLayout, { errMsg: errMsg, startpage: startpage, setting: setting, top_banner: top_banner, nav: nav, user: user, top: top, bottom: bottom })),
561
+ element: (React.createElement(MainLayout, { errMsg: errMsg, setting: setting, top_banner: top_banner, nav: nav, user: user, top: top, bottom: bottom })),
592
562
  children: route(),
593
563
  errorElement: React.createElement(NullPage, null),
594
564
  },
@@ -598,7 +568,7 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) =
598
568
  return reactRouter.createBrowserRouter([
599
569
  {
600
570
  path: "/",
601
- element: (React.createElement(MainLayout, { errMsg: errMsg, startpage: startpage, setting: setting, top_banner: top_banner, nav: nav, user: user, top: top, bottom: bottom })),
571
+ element: (React.createElement(MainLayout, { errMsg: errMsg, setting: setting, top_banner: top_banner, nav: nav, user: user, top: top, bottom: bottom })),
602
572
  children: route(),
603
573
  errorElement: React.createElement(NullPage, null),
604
574
  },
@@ -607,13 +577,7 @@ const TbFrame = ({ setting, top, bottom, nav, top_banner, hashmode = false, }) =
607
577
  }, [hashmode, user]);
608
578
  return React.createElement(reactRouter.RouterProvider, { router: router });
609
579
  };
610
- const MainLayout = ({ errMsg, startpage, setting, top_banner, nav, user, top, bottom, }) => {
611
- React.useCallback(() => {
612
- if (startpage)
613
- return setting?.loginpage ? setting.loginpage : React.createElement(LoginPage, null);
614
- else
615
- return null;
616
- }, [setting?.loginpage, startpage]);
580
+ const MainLayout = ({ errMsg, setting, top_banner, nav, user, top, bottom, }) => {
617
581
  const TOPBANNER = React.useCallback(() => {
618
582
  return top_banner ? top_banner : null;
619
583
  }, [top_banner]);