@topthink/common 1.4.0 → 1.5.0

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/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMenu as r,MenuItem as n}from"rc-menu";import{useNavigate as o,Outlet as s,UNSAFE_RouteContext as a,useMatches as l,useRoutes as d,useLocation as h,Link as g,useParams as u,Navigate as m,createBrowserRouter as p,RouterProvider as f}from"react-router-dom";export{Link,Navigate,Outlet,useLoaderData,useLocation,useMatches,useNavigate,useOutlet,useParams,useRevalidator,useRouteError,useRouteLoaderData,useRoutes,useSearchParams}from"react-router-dom";import*as v from"react";import x,{useState as b,useContext as w,useMemo as y,createContext as _,memo as k,useEffect as N,useCallback as z,Fragment as L}from"react";import{useAsync as A,isRequestError as M,Loader as I,styled as R,useWindowSize as S,Offcanvas as E,css as $,Button as C,useRequest as q,isRecord as j,Card as O,Result as U,request as P,ToastProvider as T,Modal as B,getAbsoluteUrl as H}from"@topthink/components";export*from"@topthink/components";import{intersection as V}from"lodash";import{Nav as D,Dropdown as F,Container as W,Row as K,Col as G}from"react-bootstrap";import J from"classnames";import Q from"query-string";import*as X from"path";var Y;function Z(){return Z=Object.assign?Object.assign.bind():function(e){for(var c=1;c<arguments.length;c++){var t=arguments[c];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e},Z.apply(this,arguments)}const ee=e=>v.createElement("svg",Z({xmlns:"http://www.w3.org/2000/svg",width:16,height:16},e),Y||(Y=v.createElement("g",{fill:"#888"},v.createElement("path",{d:"m8 3 1.793 1.793L6 8.586 7.414 10l3.793-3.793L13 8V3z"}),v.createElement("path",{d:"M11 11H5V5h2V3H3v10h10V9h-2z"})))),ce=function(c,t){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"/";const r=[];for(const n of t){let{meta:t={},path:o="",children:s=[]}=n;if(t.hideInMenu)continue;if(t.access){let e=t.access,i=!1;if("function"==typeof e?i=e(c):"number"==typeof e?i=c.access_level>=e:(Array.isArray(e)||(e=[e]),i=V(c.roles,e).length>0),!i)continue}const a=t.title;if(!a)continue;let l=!1;t.href?(l=!0,o=t.href):o=`${i}/${o}`.replace(/\/{2,}/g,"/").replace(/\/$/,"");const d={title:a,icon:"string"==typeof t.icon?e("i",{className:`bi bi-${t.icon}`}):t.icon,path:o,isExternal:l,children:[]};!t.hideChildrenInMenu&&!l&&s.length>0&&(d.children=ce(c,s,o)),r.push(d)}return r};const te=x.createContext(null),ie=function(c){let{userResolver:t,onResolved:i}=c;const[r,n]=b(null),a=o(),{execute:l}=A((async()=>{if(t){const e=await t();return i(e),e}}),[],{async onError(e){if(M(e)&&401===e.response?.status){const e=window.location.pathname+window.location.search;a("/login",{state:{from:e}})}},onSuccess(e){e&&n(e)}});if(!r)return e(I,{});const d=[r,n,l];return d.user=r,d.setUser=n,d.refresh=l,e(te.Provider,{value:d,children:e(s,{})})};function re(){const e=w(te);if(!e)throw new Error("please use `useUser` in UserContext");return e}function ne(e){const{matches:c}=w(a),{user:t}=re(),i=c[c.length-1],r=i.pathnameBase||"/",n=e||i.route.children||[],o=y((()=>function(e,c){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"/";return ce(e,c,t)}(t,n,r)),[t,n,r]);return[o,y((()=>c.reduceRight(((e,c)=>e||c.route.handle?.title),void 0)),[c])]}function oe(e,c){return e.map((e=>{e.children&&(e.children=oe(e.children,e.meta?.hideChildrenInMenu)),e.handle=e.handle||{};const t=e.meta?.title;void 0!==t&&(e.handle.title=t),void 0!==(c=e.meta?.hideInMenu||c&&!e.index)&&(e.handle.hideInMenu=c);const i=e.meta?.hideMenu;void 0!==i&&(e.handle.hideMenu=i);const r=e.meta?.access;return void 0!==r&&(e.handle.access=r),e}))}const se=_(void 0),ae=()=>w(se);function le(){const c=ae();return e(de,{onClick:()=>c?.setShow(!0),children:e("i",{className:"bi bi-list"})})}const de=R.div`
1
+ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import r,{SubMenu as i,MenuItem as n}from"rc-menu";import{UNSAFE_RouteContext as o,useMatches as s,useRoutes as l,useLocation as a,Outlet as d,Link as h,useNavigate as u,useParams as g,Navigate as m,createBrowserRouter as p,RouterProvider as f}from"react-router-dom";export{Link,Navigate,Outlet,useLoaderData,useLocation,useMatches,useNavigate,useOutlet,useParams,useRevalidator,useRouteError,useRouteLoaderData,useRoutes,useSearchParams}from"react-router-dom";import*as v from"react";import x,{createContext as b,useState as w,useContext as y,useMemo as _,memo as k,useEffect as N,useCallback as z,Fragment as L}from"react";import{useAsync as A,Loader as R,styled as M,useWindowSize as I,Offcanvas as S,css as E,isRequestError as $,Button as C,useRequest as q,isRecord as P,Card as j,Result as O,request as U,ToastProvider as T,Modal as B,getAbsoluteUrl as H}from"@topthink/components";export*from"@topthink/components";import{intersection as V}from"lodash";import{Nav as D,Dropdown as F,Container as W,Row as K,Col as G}from"react-bootstrap";import J from"classnames";import Q from"query-string";import*as X from"path";var Y;function Z(){return Z=Object.assign?Object.assign.bind():function(e){for(var c=1;c<arguments.length;c++){var t=arguments[c];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Z.apply(this,arguments)}const ee=e=>v.createElement("svg",Z({xmlns:"http://www.w3.org/2000/svg",width:16,height:16},e),Y||(Y=v.createElement("g",{fill:"#888"},v.createElement("path",{d:"m8 3 1.793 1.793L6 8.586 7.414 10l3.793-3.793L13 8V3z"}),v.createElement("path",{d:"M11 11H5V5h2V3H3v10h10V9h-2z"})))),ce=function(c,t){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"/";const i=[];for(const n of t){let{meta:t={},path:o="",children:s=[]}=n;if(t.hideInMenu)continue;if(t.access){let e=t.access,r=!1;if("function"==typeof e?r=e(c):"number"==typeof e?r=(c.user?.access_level||0)>=e:(Array.isArray(e)||(e=[e]),r=V(c.user?.roles||[],e).length>0),!r)continue}const l=t.title;if(!l)continue;let a=!1;t.href?(a=!0,o=t.href):o=`${r}/${o}`.replace(/\/{2,}/g,"/").replace(/\/$/,"");const d={title:l,icon:"string"==typeof t.icon?e("i",{className:`bi bi-${t.icon}`}):t.icon,path:o,isExternal:a,children:[]};!t.hideChildrenInMenu&&!a&&s.length>0&&(d.children=ce(c,s,o)),i.push(d)}return i};const te=b(null);function re(c){let{appResolver:t,children:r}=c;const[i,n]=w(null);return A((async()=>{if(t)return t()}),[],{onSuccess(e){n(e||{})}}),i?e(te.Provider,{value:[i,n],children:r}):e(R,{})}function ie(){const e=y(te);if(!e)throw new Error("useApp must be used within a AppProvider");return e}function ne(){const[e]=ie();return e}function oe(e){const{matches:c}=y(o),t=ne(),r=c[c.length-1],i=r.pathnameBase||"/",n=e||r.route.children||[],s=_((()=>function(e,c){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"/";return ce(e,c,t)}(t,n,i)),[t,n,i]);return[s,_((()=>c.reduceRight(((e,c)=>e||c.route.handle?.title),void 0)),[c])]}function se(e,c){return e.map((e=>{e.children&&(e.children=se(e.children,e.meta?.hideChildrenInMenu)),e.handle=e.handle||{};const t=e.meta?.title;void 0!==t&&(e.handle.title=t),void 0!==(c=e.meta?.hideInMenu||c&&!e.index)&&(e.handle.hideInMenu=c);const r=e.meta?.hideMenu;void 0!==r&&(e.handle.hideMenu=r);const i=e.meta?.access;return void 0!==i&&(e.handle.access=i),e}))}const le=b(void 0),ae=()=>y(le);function de(){const c=ae();return e(he,{onClick:()=>c?.setShow(!0),children:e("i",{className:"bi bi-list"})})}const he=M.div`
2
2
  width: 40px;
3
3
  height: 40px;
4
4
  display: flex;
@@ -6,7 +6,7 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
6
6
  align-items: center;
7
7
  justify-content: center;
8
8
  cursor: pointer;
9
- `;const he=t=>t.map((t=>{const i=c(ke,{children:[t.icon,t.title,t.isExternal&&e(ee,{})]});return t.children.length>0?e(r,{title:i,children:he(t.children)},t.path):e(n,{children:t.isExternal?e("a",{href:t.path,target:"_blank",children:i}):e(g,{to:t.path,children:i})},t.path)})),ge=()=>({height:0}),ue=e=>({height:e.scrollHeight}),me={motionName:"rc-menu-collapse",motionAppear:!0,onAppearStart:ge,onAppearActive:ue,onEnterStart:ge,onEnterActive:ue,onLeaveStart:ue,onLeaveActive:ge};function pe(t){let{className:i,title:r,header:n,headerAs:o,footer:a,footerAs:d,top:g=54,routes:u}=t;const{isMobile:m}=S(),[p,f]=ne(u),[v,x]=b(!1),{pathname:w,key:_}=h(),{hideMenu:k=!1}=l().reduce(((e,c)=>({...e,...c.handle})),{}),L=y((()=>{const e=[];return w.split("/").reduce(((c,t)=>(c.length>1&&e.push(c.join("/")),[...c,t])),[]),e.push(w),e}),[w]),[A,M]=b([]);N((()=>{x(!1)}),[_]),N((()=>{M(L.slice(0,-1))}),[L]);const I=z((e=>{const c=e[e.length-1];M(e.filter((e=>c.startsWith(e))))}),[A,M]),R=u?e(fe,{routes:u}):e(s,{});if(k)return R;n||(n=e(xe,{children:r||f}));const $=d||we,C=c(ve,{className:i,children:[e(o||be,{children:n}),e(Ne,{mode:"inline",motion:me,openKeys:A,onOpenChange:I,selectedKeys:L,children:he(p)}),e($,{children:a})]}),q=m?e(le,{}):null;return e(se.Provider,{value:{show:v,setShow:x,toggle:q,headless:0==g},children:c(ze,{$top:g,children:[m?e(E,{show:v,onHide:()=>{x(!1)},placement:"start",style:{width:"230px"},children:C}):C,e(ye,{children:e(_e,{children:R})})]})})}const fe=k((function(e){let{routes:c}=e;return d(y((()=>oe(c)),[c]))})),ve=R.nav`
9
+ `;const ue=t=>t.map((t=>{const r=c(Ne,{children:[t.icon,t.title,t.isExternal&&e(ee,{})]});return t.children.length>0?e(i,{title:r,children:ue(t.children)},t.path):e(n,{children:t.isExternal?e("a",{href:t.path,target:"_blank",children:r}):e(h,{to:t.path,children:r})},t.path)})),ge=()=>({height:0}),me=e=>({height:e.scrollHeight}),pe={motionName:"rc-menu-collapse",motionAppear:!0,onAppearStart:ge,onAppearActive:me,onEnterStart:ge,onEnterActive:me,onLeaveStart:me,onLeaveActive:ge};function fe(t){let{className:r,title:i,header:n,headerAs:o,footer:l,footerAs:h,top:u=54,routes:g}=t;const{isMobile:m}=I(),[p,f]=oe(g),[v,x]=w(!1),{pathname:b,key:y}=a(),{hideMenu:k=!1}=s().reduce(((e,c)=>({...e,...c.handle})),{}),L=_((()=>{const e=[];return b.split("/").reduce(((c,t)=>(c.length>1&&e.push(c.join("/")),[...c,t])),[]),e.push(b),e}),[b]),[A,R]=w([]);N((()=>{x(!1)}),[y]),N((()=>{R(L.slice(0,-1))}),[L]);const M=z((e=>{const c=e[e.length-1];R(e.filter((e=>c.startsWith(e))))}),[A,R]),E=g?e(ve,{routes:g}):e(d,{});if(k)return E;n||(n=e(be,{children:i||f}));const $=h||ye,C=c(xe,{className:r,children:[e(o||we,{children:n}),e(ze,{mode:"inline",motion:pe,openKeys:A,onOpenChange:M,selectedKeys:L,children:ue(p)}),e($,{children:l})]}),q=m?e(de,{}):null;return e(le.Provider,{value:{show:v,setShow:x,toggle:q,headless:0==u},children:c(Le,{$top:u,children:[m?e(S,{show:v,onHide:()=>{x(!1)},placement:"start",style:{width:"230px"},children:C}):C,e(_e,{children:e(ke,{children:E})})]})})}const ve=k((function(e){let{routes:c}=e;return l(_((()=>se(c)),[c]))})),xe=M.nav`
10
10
  position: fixed;
11
11
  top: 0;
12
12
  bottom: 0;
@@ -18,12 +18,12 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
18
18
  background-color: #f5f5f5;
19
19
  display: flex;
20
20
  flex-direction: column;
21
- `,xe=R.div`
21
+ `,be=M.div`
22
22
  text-overflow: ellipsis;
23
23
  white-space: nowrap;
24
24
  overflow: hidden;
25
25
  font-size: 16px;
26
- `,be=R.div`
26
+ `,we=M.div`
27
27
  height: 64px;
28
28
  display: flex;
29
29
  align-items: center;
@@ -31,18 +31,18 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
31
31
  border-bottom: 1px solid #e3e3e3;
32
32
  flex-grow: 0;
33
33
  flex-shrink: 0;
34
- `,we=R.div`
34
+ `,ye=M.div`
35
35
  flex-grow: 0;
36
36
  flex-shrink: 0;
37
- `,ye=R.div`
37
+ `,_e=M.div`
38
38
  flex: 1;
39
39
  @media (min-width: 992px) {
40
40
  margin-left: 230px;
41
41
  }
42
- `,_e=R.main`
42
+ `,ke=M.main`
43
43
  min-height: calc(var(--100vh, 100vh) - var(--bs-header-height));
44
44
  position: relative;
45
- `,ke=R.div`
45
+ `,Ne=M.div`
46
46
  display: inline-flex;
47
47
  align-items: center;
48
48
  gap: 0.5rem;
@@ -53,7 +53,7 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
53
53
  min-width: 19px;
54
54
  text-align: center;
55
55
  }
56
- `,Ne=R(i)`
56
+ `,ze=M(r)`
57
57
  border: none;
58
58
  box-shadow: none;
59
59
  padding: 10px 0;
@@ -192,25 +192,25 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
192
192
  }
193
193
  }
194
194
 
195
- `,ze=R.div`
195
+ `,Le=M.div`
196
196
  --bs-header-height: ${e=>e.$top}px;
197
197
  display: flex;
198
198
  flex-wrap: nowrap;
199
199
  width: 100%;
200
200
 
201
201
  &:has(&) {
202
- > ${ve} {
202
+ > ${xe} {
203
203
  display: none;
204
204
  }
205
205
 
206
- > ${ye} {
206
+ > ${_e} {
207
207
  margin-left: 0;
208
208
  }
209
209
  }
210
- `;function Le(t){let{title:i,header:r,nav:n,children:s,extra:l,showBack:d,className:g,bodyAs:u,fixed:m=!0}=t;const{matches:p}=w(a),f=y((()=>p.reduceRight(((e,c)=>e||c.route.index?e:c.route),void 0)),[p]),v=ae(),x=!0===f?.handle?.hideInMenu,b=f?.handle?.title,_=o(),k=h();return void 0===d&&(d=x),void 0===r&&(r=e(Se,{className:"fs-4 text-truncate",children:i||b})),c(Me,{className:g,children:[e(Ie,{$fixed:m,children:c("div",{className:"container",children:[v?.headless&&v.toggle,d&&("default"!==k.key||"string"==typeof d)&&e(Ae,{onClick:()=>_("string"==typeof d?d:-1),children:e("i",{className:"bi bi-arrow-left-short"})}),r,n,e(Ee,{children:l})]})}),e(Re,{className:"container",as:u,children:s})]})}const Ae=R.div`
210
+ `;function Ae(t){let{title:r,header:i,nav:n,children:s,extra:l,showBack:d,className:h,bodyAs:g,fixed:m=!0}=t;const{matches:p}=y(o),f=_((()=>p.reduceRight(((e,c)=>e||c.route.index?e:c.route),void 0)),[p]),v=ae(),x=!0===f?.handle?.hideInMenu,b=f?.handle?.title,w=u(),k=a();return void 0===d&&(d=x),void 0===i&&(i=e(Ee,{className:"fs-4 text-truncate",children:r||b})),c(Me,{className:h,children:[e(Ie,{$fixed:m,children:c("div",{className:"container",children:[v?.headless&&v.toggle,d&&("default"!==k.key||"string"==typeof d)&&e(Re,{onClick:()=>w("string"==typeof d?d:-1),children:e("i",{className:"bi bi-arrow-left-short"})}),i,n,e($e,{children:l})]})}),e(Se,{className:"container",as:g,children:s})]})}const Re=M.div`
211
211
  font-size: 32px;
212
212
  cursor: pointer;
213
- `,Me=R.div`
213
+ `,Me=M.div`
214
214
  width: 100%;
215
215
  container-type: inline-size;
216
216
 
@@ -225,14 +225,14 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
225
225
  max-width: 100cqw;
226
226
  }
227
227
  }
228
- `,Ie=R.div`
228
+ `,Ie=M.div`
229
229
  background-color: #fff;
230
230
  display: flex;
231
231
  border-bottom: 1px solid rgb(227, 227, 227);
232
232
  align-items: center;
233
233
  height: 65px;
234
234
 
235
- ${e=>e.$fixed&&$`
235
+ ${e=>e.$fixed&&E`
236
236
  position: sticky;
237
237
  top: 0;
238
238
  z-index: 1000;
@@ -244,7 +244,7 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
244
244
  align-items: center;
245
245
  gap: .5rem;
246
246
  }
247
- `,Re=R.div`
247
+ `,Se=M.div`
248
248
  margin-top: 24px;
249
249
  margin-bottom: 24px;
250
250
 
@@ -252,18 +252,18 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
252
252
  margin-top: 1rem;
253
253
  margin-bottom: 1rem;
254
254
  }
255
- `,Se=R.div`
255
+ `,Ee=M.div`
256
256
  overflow: hidden;
257
257
  text-overflow: ellipsis;
258
258
  white-space: nowrap;
259
259
  min-width: 50px;
260
260
  flex-shrink: 0;
261
- `,Ee=R.div`
261
+ `,$e=M.div`
262
262
  margin-left: auto;
263
- `;function $e(t){let{title:i,header:r,showBack:n,extra:o}=t;const[a,l]=ne(),{pathname:d}=h(),{isMobile:u}=S(),m=u?c(F,{className:"ms-2 d-flex align-items-center",children:[e(F.Toggle,{variant:"light",size:"sm"}),e(F.Menu,{children:a.map((e=>c(F.Item,{active:d.startsWith(e.path),as:g,to:e.path,replace:!0,children:[e.icon,e.title]},e.path)))})]}):e(Ce,{children:a.map((t=>e(D.Item,{children:c(qe,{className:J("nav-link",{active:d.startsWith(t.path)}),to:t.path,replace:!0,children:[t.icon,t.title]})},t.path)))});return e(Le,{title:i||l,header:r,nav:m,showBack:n,extra:o,children:e(s,{})})}const Ce=R(D)`
263
+ `;function Ce(t){let{title:r,header:i,showBack:n,extra:o}=t;const[s,l]=oe(),{pathname:u}=a(),{isMobile:g}=I(),m=g?c(F,{className:"ms-2 d-flex align-items-center",children:[e(F.Toggle,{variant:"light",size:"sm"}),e(F.Menu,{children:s.map((e=>c(F.Item,{active:u.startsWith(e.path),as:h,to:e.path,replace:!0,children:[e.icon,e.title]},e.path)))})]}):e(qe,{children:s.map((t=>e(D.Item,{children:c(Pe,{className:J("nav-link",{active:u.startsWith(t.path)}),to:t.path,replace:!0,children:[t.icon,t.title]})},t.path)))});return e(Ae,{title:r||l,header:i,nav:m,showBack:n,extra:o,children:e(d,{})})}const qe=M(D)`
264
264
  flex-wrap: nowrap;
265
265
  margin-left: 1.25rem;
266
- `,qe=R(g)`
266
+ `,Pe=M(h)`
267
267
  display: flex;
268
268
  align-items: center;
269
269
  gap: 0.5rem;
@@ -286,9 +286,9 @@ import{jsx as e,jsxs as c,Fragment as t}from"react/jsx-runtime";import i,{SubMen
286
286
  bottom: -2px;
287
287
  }
288
288
  }
289
- `;const je=R.a`
289
+ `;const je=x.createContext(null),Oe=function(c){let{userResolver:t,onResolved:r}=c;const[,i]=ie(),[n,o]=w(null);N((()=>{i((e=>({...e,user:n})))}),[n]);const s=u(),{execute:l}=A((async()=>{if(t){const e=await t();return r(e),e}}),[],{async onError(e){if($(e)&&401===e.response?.status){const e=window.location.pathname+window.location.search;s("/login",{state:{from:e}})}},onSuccess(e){e&&o(e)}});if(!n)return e(R,{});const a=[n,o,l];return a.user=n,a.setUser=o,a.refresh=l,e(je.Provider,{value:a,children:e(d,{})})};function Ue(){const e=y(je);if(!e)throw new Error("please use `useUser` in UserContext");return e}const Te=M.a`
290
290
  cursor: pointer;
291
- `;function Oe(t){let{children:i,menus:r,className:n,logo:o=!0}=t;const[s]=re();return e(Ue,{className:J("navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top",n),children:c("div",{className:"container-fluid",children:[o&&e("a",{className:"navbar-brand",href:"https://www.topthink.com",children:e("img",{src:"data:image/svg+xml,%3csvg width='485' height='132' xmlns='http://www.w3.org/2000/svg' xml:space='preserve' style='enable-background:new 0 0 531.69 198.43%3b' version='1.1'%3e %3cstyle type='text/css'%3e.st0%7bfill:%233C60FF%3b%7d%3c/style%3e %3cg%3e %3ctitle%3ebackground%3c/title%3e %3crect fill='none' id='canvas_background' height='134' width='487' y='-1' x='-1'/%3e %3c/g%3e %3cg%3e %3ctitle%3eLayer 1%3c/title%3e %3cpath id='svg_1' d='m132.29%2c62.34c-1.19%2c-18.77 -10.34%2c-35.36 -24.11%2c-46.46c-11.15%2c-8.99 -25.34%2c-14.38 -40.79%2c-14.38c-0.55%2c0 -1.09%2c0.01 -1.63%2c0.02c-3.32%2c0.08 -6.57%2c0.41 -9.75%2c0.98c-30.49%2c5.38 -53.65%2c32 -53.65%2c64.04c0%2c1.87 0.08%2c3.73 0.24%2c5.57c2.5%2c29.51 24.7%2c53.4 53.41%2c58.47c2.38%2c0.42 4.8%2c0.72 7.26%2c0.86c0.83%2c0.05 1.66%2c0.09 2.5%2c0.11c0.54%2c0.01 1.08%2c0.02 1.63%2c0.02c34.04%2c0 61.97%2c-26.16 64.79%2c-59.46c0.16%2c-1.83 0.24%2c-3.69 0.24%2c-5.57c0%2c-1.42 -0.05%2c-2.82 -0.14%2c-4.2zm-76.27%2c32.5c-0.26%2c0.01 -0.53%2c0.01 -0.79%2c0.01c-14.56%2c0 -26.88%2c-9.57 -31.03%2c-22.76c-0.97%2c-3.08 -1.49%2c-6.35 -1.49%2c-9.75c0%2c-17.95 14.56%2c-32.52 32.51%2c-32.52c0.26%2c0 0.53%2c0 0.79%2c0.01c3.41%2c0.08 6.69%2c0.68 9.75%2c1.74c6.5%2c2.22 12.06%2c6.45 15.97%2c11.94c1.98%2c2.78 3.54%2c5.9 4.57%2c9.25c0.94%2c3.03 1.44%2c6.24 1.44%2c9.58l-9.75%2c0c0%2c-2.18 -0.31%2c-4.29 -0.88%2c-6.28c-0.92%2c-3.23 -2.55%2c-6.17 -4.69%2c-8.64c-1.86%2c-2.14 -4.12%2c-3.93 -6.65%2c-5.25c-2.93%2c-1.54 -6.24%2c-2.46 -9.75%2c-2.58c-0.26%2c-0.01 -0.52%2c-0.01 -0.79%2c-0.01c-12.57%2c0 -22.76%2c10.19 -22.76%2c22.76c0%2c3.49 0.79%2c6.8 2.19%2c9.75c3.65%2c7.69 11.49%2c13.01 20.57%2c13.01c0.27%2c0 0.53%2c-0.01 0.79%2c-0.01l0%2c9.75zm55.7%2c-17.92c-3.35%2c10.5 -13.18%2c18.09 -24.78%2c18.09c-3.13%2c0 -6.13%2c-0.55 -8.91%2c-1.57c-2.18%2c-0.8 -4.24%2c-1.88 -6.11%2c-3.21c-2.38%2c-1.68 -4.47%2c-3.76 -6.16%2c-6.13c-0.28%2c-0.39 -0.55%2c-0.79 -0.81%2c-1.2c-2.03%2c-3.2 -3.38%2c-6.87 -3.85%2c-10.82l9.87%2c0c0.33%2c1.71 0.92%2c3.32 1.74%2c4.8c1.61%2c2.91 4.09%2c5.26 7.09%2c6.72c0.57%2c0.28 1.15%2c0.53 1.76%2c0.73c1.68%2c0.6 3.49%2c0.92 5.37%2c0.92c7.92%2c0 14.52%2c-5.67 15.96%2c-13.17c0.2%2c-1 0.3%2c-2.04 0.3%2c-3.09c0%2c-2.37 -0.51%2c-4.63 -1.43%2c-6.67c-1.66%2c-3.71 -4.68%2c-6.68 -8.43%2c-8.28l3.54%2c-9.1c7.43%2c3.08 13.13%2c9.49 15.21%2c17.38c0.44%2c1.64 0.72%2c3.34 0.81%2c5.09c0.04%2c0.52 0.05%2c1.05 0.05%2c1.58c0%2c1.05 -0.07%2c2.07 -0.18%2c3.09c-0.18%2c1.68 -0.54%2c3.3 -1.04%2c4.84z' class='st0'/%3e %3cg id='svg_2'%3e %3cg id='svg_3'%3e %3crect id='svg_4' height='6.34' width='94.12' class='st0' y='20.46' x='163.29'/%3e %3c/g%3e %3cg id='svg_5'%3e %3cpath id='svg_6' d='m169.31%2c113.72l0%2c-6.34c6.49%2c0 11.77%2c-5.28 11.77%2c-11.77l0%2c-71.98l6.34%2c0l0%2c71.98c0%2c9.98 -8.12%2c18.11 -18.11%2c18.11z' class='st0'/%3e %3c/g%3e %3cg id='svg_7'%3e %3cpath id='svg_8' d='m255.49%2c91.27l-6.34%2c0l0%2c-38.2c0%2c-5.06 -4.12%2c-9.18 -9.18%2c-9.18l-19.37%2c0c-5.06%2c0 -9.18%2c4.12 -9.18%2c9.18l0%2c38.2l-6.34%2c0l0%2c-38.2c0%2c-8.55 6.96%2c-15.51 15.51%2c-15.51l19.38%2c0c8.55%2c0 15.51%2c6.96 15.51%2c15.51l0%2c38.2l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_9'%3e %3crect id='svg_10' height='17.09' width='6.34' class='st0' y='23.63' x='227.12'/%3e %3c/g%3e %3cg id='svg_11'%3e %3cpath id='svg_12' d='m206.43%2c113.84l-3.34%2c0l0%2c-6.34l3.34%2c0c6.3%2c0 12.9%2c-3.56 15.35%2c-8.29c3.49%2c-6.71 5.33%2c-14.25 5.33%2c-21.81l0%2c-26.13l6.34%2c0l0%2c26.13c0%2c8.58 -2.09%2c17.13 -6.05%2c24.74c-3.98%2c7.68 -13.57%2c11.7 -20.97%2c11.7z' class='st0'/%3e %3c/g%3e %3cg id='svg_13'%3e %3cpath id='svg_14' d='m257.48%2c113.84l-3.34%2c0c-7.4%2c0 -16.98%2c-4.02 -20.98%2c-11.7c-3.96%2c-7.61 -6.05%2c-16.16 -6.05%2c-24.74l6.34%2c0c0%2c7.56 1.84%2c15.1 5.33%2c21.81c2.46%2c4.73 9.06%2c8.29 15.35%2c8.29l3.34%2c0l0%2c6.34l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_15'%3e %3crect id='svg_16' height='6.34' width='42.87' class='st0' y='27.89' x='274.07'/%3e %3c/g%3e %3cg id='svg_17'%3e %3crect id='svg_18' height='61.38' width='6.34' class='st0' y='14.89' x='293.05'/%3e %3c/g%3e %3cg id='svg_19'%3e %3crect id='svg_20' height='6.34' width='33.26' class='st0' transform='matrix(0.11%2c-0.9939%2c0.9939%2c0.11%2c194.7608%2c392.0006) ' y='46.985071' x='325.728637'/%3e %3c/g%3e %3cg id='svg_21'%3e %3crect id='svg_22' height='33.26' width='6.34' class='st0' transform='matrix(0.9939%2c-0.11%2c0.11%2c0.9939%2c-7.5075%2c38.3801) ' y='37.060893' x='310.495485'/%3e %3c/g%3e %3cg id='svg_23'%3e %3cpath id='svg_24' d='m352.9%2c77.14l-15.15%2c0c-7.52%2c0 -13.64%2c-6.12 -13.64%2c-13.63l0%2c-29.61c0%2c-7.52 6.12%2c-13.64 13.64%2c-13.64l15.15%2c0c7.52%2c0 13.64%2c6.12 13.64%2c13.64l0%2c29.61c0%2c7.52 -6.12%2c13.63 -13.64%2c13.63zm-15.15%2c-50.54c-4.02%2c0 -7.3%2c3.27 -7.3%2c7.3l0%2c29.61c0%2c4.02 3.27%2c7.3 7.3%2c7.3l15.15%2c0c4.02%2c0 7.3%2c-3.27 7.3%2c-7.3l0%2c-29.61c0%2c-4.02 -3.27%2c-7.3 -7.3%2c-7.3l-15.15%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_25'%3e %3cg id='svg_26'%3e %3crect id='svg_27' height='6.34' width='17.8' class='st0' y='37.2' x='336.43'/%3e %3c/g%3e %3cg id='svg_28'%3e %3crect id='svg_29' height='6.34' width='17.8' class='st0' y='53.87' x='336.43'/%3e %3c/g%3e %3c/g%3e %3cg id='svg_30'%3e %3cpath id='svg_31' d='m352.7%2c113.84l-37.98%2c0c-8%2c0 -14.5%2c-6.51 -14.5%2c-14.5l0%2c-16.14l6.34%2c0l0%2c16.13c0%2c4.5 3.66%2c8.17 8.17%2c8.17l37.98%2c0l0%2c6.34l-0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_32'%3e %3crect id='svg_33' height='6.34' width='23.57' class='st0' transform='matrix(0.2529%2c-0.9675%2c0.9675%2c0.2529%2c114.4986%2c402.9877) ' y='83.698593' x='326.836101'/%3e %3c/g%3e %3cg id='svg_34'%3e %3crect id='svg_35' height='6.34' width='20.52' class='st0' y='86.2' x='321.58'/%3e %3c/g%3e %3cg id='svg_36'%3e %3crect id='svg_37' height='24.75' width='6.34' class='st0' transform='matrix(0.9556%2c-0.2946%2c0.2946%2c0.9556%2c-19.7967%2c122.424) ' y='75.874073' x='369.686666'/%3e %3c/g%3e %3cg id='svg_38'%3e %3crect id='svg_39' height='6.34' width='71.83' class='st0' y='20.46' x='395.51'/%3e %3c/g%3e %3cg id='svg_40'%3e %3crect id='svg_41' height='6.34' width='90.81' class='st0' y='57.44' x='386.02'/%3e %3c/g%3e %3cg id='svg_42'%3e %3cpath id='svg_43' d='m463.12%2c113.64l-56%2c0c-4.5%2c0 -8.59%2c-2.29 -10.94%2c-6.14c-2.35%2c-3.84 -2.52%2c-8.53 -0.46%2c-12.53l17.68%2c-35.81l5.64%2c2.89l-17.68%2c35.81c-1.04%2c2.02 -0.95%2c4.39 0.23%2c6.33c1.19%2c1.94 3.25%2c3.1 5.53%2c3.1l56%2c0c1.51%2c0 2.88%2c-0.71 3.74%2c-1.95c0.81%2c-1.16 1.03%2c-2.57 0.63%2c-3.91l-7.8%2c-12.34l5.36%2c-3.39l8.18%2c12.94l0.12%2c0.31c1.24%2c3.34 0.76%2c7.08 -1.28%2c10.01c-2.04%2c2.94 -5.39%2c4.68 -8.95%2c4.68z' class='st0'/%3e %3c/g%3e %3c/g%3e %3c/g%3e%3c/svg%3e",height:"30"})}),i,c(F,{navbar:!0,children:[e(F.Toggle,{as:je,className:"nav-link",children:e("img",{className:"rounded-circle",width:"25",height:"25",src:s.avatar})}),e(F.Menu,{className:"shadow",children:r})]})]})})}const Ue=R.header`
291
+ `;function Be(t){let{children:r,menus:i,className:n,logo:o=!0}=t;const[s]=Ue();return e(He,{className:J("navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top",n),children:c("div",{className:"container-fluid",children:[o&&e("a",{className:"navbar-brand",href:"https://www.topthink.com",children:e("img",{src:"data:image/svg+xml,%3csvg width='485' height='132' xmlns='http://www.w3.org/2000/svg' xml:space='preserve' style='enable-background:new 0 0 531.69 198.43%3b' version='1.1'%3e %3cstyle type='text/css'%3e.st0%7bfill:%233C60FF%3b%7d%3c/style%3e %3cg%3e %3ctitle%3ebackground%3c/title%3e %3crect fill='none' id='canvas_background' height='134' width='487' y='-1' x='-1'/%3e %3c/g%3e %3cg%3e %3ctitle%3eLayer 1%3c/title%3e %3cpath id='svg_1' d='m132.29%2c62.34c-1.19%2c-18.77 -10.34%2c-35.36 -24.11%2c-46.46c-11.15%2c-8.99 -25.34%2c-14.38 -40.79%2c-14.38c-0.55%2c0 -1.09%2c0.01 -1.63%2c0.02c-3.32%2c0.08 -6.57%2c0.41 -9.75%2c0.98c-30.49%2c5.38 -53.65%2c32 -53.65%2c64.04c0%2c1.87 0.08%2c3.73 0.24%2c5.57c2.5%2c29.51 24.7%2c53.4 53.41%2c58.47c2.38%2c0.42 4.8%2c0.72 7.26%2c0.86c0.83%2c0.05 1.66%2c0.09 2.5%2c0.11c0.54%2c0.01 1.08%2c0.02 1.63%2c0.02c34.04%2c0 61.97%2c-26.16 64.79%2c-59.46c0.16%2c-1.83 0.24%2c-3.69 0.24%2c-5.57c0%2c-1.42 -0.05%2c-2.82 -0.14%2c-4.2zm-76.27%2c32.5c-0.26%2c0.01 -0.53%2c0.01 -0.79%2c0.01c-14.56%2c0 -26.88%2c-9.57 -31.03%2c-22.76c-0.97%2c-3.08 -1.49%2c-6.35 -1.49%2c-9.75c0%2c-17.95 14.56%2c-32.52 32.51%2c-32.52c0.26%2c0 0.53%2c0 0.79%2c0.01c3.41%2c0.08 6.69%2c0.68 9.75%2c1.74c6.5%2c2.22 12.06%2c6.45 15.97%2c11.94c1.98%2c2.78 3.54%2c5.9 4.57%2c9.25c0.94%2c3.03 1.44%2c6.24 1.44%2c9.58l-9.75%2c0c0%2c-2.18 -0.31%2c-4.29 -0.88%2c-6.28c-0.92%2c-3.23 -2.55%2c-6.17 -4.69%2c-8.64c-1.86%2c-2.14 -4.12%2c-3.93 -6.65%2c-5.25c-2.93%2c-1.54 -6.24%2c-2.46 -9.75%2c-2.58c-0.26%2c-0.01 -0.52%2c-0.01 -0.79%2c-0.01c-12.57%2c0 -22.76%2c10.19 -22.76%2c22.76c0%2c3.49 0.79%2c6.8 2.19%2c9.75c3.65%2c7.69 11.49%2c13.01 20.57%2c13.01c0.27%2c0 0.53%2c-0.01 0.79%2c-0.01l0%2c9.75zm55.7%2c-17.92c-3.35%2c10.5 -13.18%2c18.09 -24.78%2c18.09c-3.13%2c0 -6.13%2c-0.55 -8.91%2c-1.57c-2.18%2c-0.8 -4.24%2c-1.88 -6.11%2c-3.21c-2.38%2c-1.68 -4.47%2c-3.76 -6.16%2c-6.13c-0.28%2c-0.39 -0.55%2c-0.79 -0.81%2c-1.2c-2.03%2c-3.2 -3.38%2c-6.87 -3.85%2c-10.82l9.87%2c0c0.33%2c1.71 0.92%2c3.32 1.74%2c4.8c1.61%2c2.91 4.09%2c5.26 7.09%2c6.72c0.57%2c0.28 1.15%2c0.53 1.76%2c0.73c1.68%2c0.6 3.49%2c0.92 5.37%2c0.92c7.92%2c0 14.52%2c-5.67 15.96%2c-13.17c0.2%2c-1 0.3%2c-2.04 0.3%2c-3.09c0%2c-2.37 -0.51%2c-4.63 -1.43%2c-6.67c-1.66%2c-3.71 -4.68%2c-6.68 -8.43%2c-8.28l3.54%2c-9.1c7.43%2c3.08 13.13%2c9.49 15.21%2c17.38c0.44%2c1.64 0.72%2c3.34 0.81%2c5.09c0.04%2c0.52 0.05%2c1.05 0.05%2c1.58c0%2c1.05 -0.07%2c2.07 -0.18%2c3.09c-0.18%2c1.68 -0.54%2c3.3 -1.04%2c4.84z' class='st0'/%3e %3cg id='svg_2'%3e %3cg id='svg_3'%3e %3crect id='svg_4' height='6.34' width='94.12' class='st0' y='20.46' x='163.29'/%3e %3c/g%3e %3cg id='svg_5'%3e %3cpath id='svg_6' d='m169.31%2c113.72l0%2c-6.34c6.49%2c0 11.77%2c-5.28 11.77%2c-11.77l0%2c-71.98l6.34%2c0l0%2c71.98c0%2c9.98 -8.12%2c18.11 -18.11%2c18.11z' class='st0'/%3e %3c/g%3e %3cg id='svg_7'%3e %3cpath id='svg_8' d='m255.49%2c91.27l-6.34%2c0l0%2c-38.2c0%2c-5.06 -4.12%2c-9.18 -9.18%2c-9.18l-19.37%2c0c-5.06%2c0 -9.18%2c4.12 -9.18%2c9.18l0%2c38.2l-6.34%2c0l0%2c-38.2c0%2c-8.55 6.96%2c-15.51 15.51%2c-15.51l19.38%2c0c8.55%2c0 15.51%2c6.96 15.51%2c15.51l0%2c38.2l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_9'%3e %3crect id='svg_10' height='17.09' width='6.34' class='st0' y='23.63' x='227.12'/%3e %3c/g%3e %3cg id='svg_11'%3e %3cpath id='svg_12' d='m206.43%2c113.84l-3.34%2c0l0%2c-6.34l3.34%2c0c6.3%2c0 12.9%2c-3.56 15.35%2c-8.29c3.49%2c-6.71 5.33%2c-14.25 5.33%2c-21.81l0%2c-26.13l6.34%2c0l0%2c26.13c0%2c8.58 -2.09%2c17.13 -6.05%2c24.74c-3.98%2c7.68 -13.57%2c11.7 -20.97%2c11.7z' class='st0'/%3e %3c/g%3e %3cg id='svg_13'%3e %3cpath id='svg_14' d='m257.48%2c113.84l-3.34%2c0c-7.4%2c0 -16.98%2c-4.02 -20.98%2c-11.7c-3.96%2c-7.61 -6.05%2c-16.16 -6.05%2c-24.74l6.34%2c0c0%2c7.56 1.84%2c15.1 5.33%2c21.81c2.46%2c4.73 9.06%2c8.29 15.35%2c8.29l3.34%2c0l0%2c6.34l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_15'%3e %3crect id='svg_16' height='6.34' width='42.87' class='st0' y='27.89' x='274.07'/%3e %3c/g%3e %3cg id='svg_17'%3e %3crect id='svg_18' height='61.38' width='6.34' class='st0' y='14.89' x='293.05'/%3e %3c/g%3e %3cg id='svg_19'%3e %3crect id='svg_20' height='6.34' width='33.26' class='st0' transform='matrix(0.11%2c-0.9939%2c0.9939%2c0.11%2c194.7608%2c392.0006) ' y='46.985071' x='325.728637'/%3e %3c/g%3e %3cg id='svg_21'%3e %3crect id='svg_22' height='33.26' width='6.34' class='st0' transform='matrix(0.9939%2c-0.11%2c0.11%2c0.9939%2c-7.5075%2c38.3801) ' y='37.060893' x='310.495485'/%3e %3c/g%3e %3cg id='svg_23'%3e %3cpath id='svg_24' d='m352.9%2c77.14l-15.15%2c0c-7.52%2c0 -13.64%2c-6.12 -13.64%2c-13.63l0%2c-29.61c0%2c-7.52 6.12%2c-13.64 13.64%2c-13.64l15.15%2c0c7.52%2c0 13.64%2c6.12 13.64%2c13.64l0%2c29.61c0%2c7.52 -6.12%2c13.63 -13.64%2c13.63zm-15.15%2c-50.54c-4.02%2c0 -7.3%2c3.27 -7.3%2c7.3l0%2c29.61c0%2c4.02 3.27%2c7.3 7.3%2c7.3l15.15%2c0c4.02%2c0 7.3%2c-3.27 7.3%2c-7.3l0%2c-29.61c0%2c-4.02 -3.27%2c-7.3 -7.3%2c-7.3l-15.15%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_25'%3e %3cg id='svg_26'%3e %3crect id='svg_27' height='6.34' width='17.8' class='st0' y='37.2' x='336.43'/%3e %3c/g%3e %3cg id='svg_28'%3e %3crect id='svg_29' height='6.34' width='17.8' class='st0' y='53.87' x='336.43'/%3e %3c/g%3e %3c/g%3e %3cg id='svg_30'%3e %3cpath id='svg_31' d='m352.7%2c113.84l-37.98%2c0c-8%2c0 -14.5%2c-6.51 -14.5%2c-14.5l0%2c-16.14l6.34%2c0l0%2c16.13c0%2c4.5 3.66%2c8.17 8.17%2c8.17l37.98%2c0l0%2c6.34l-0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_32'%3e %3crect id='svg_33' height='6.34' width='23.57' class='st0' transform='matrix(0.2529%2c-0.9675%2c0.9675%2c0.2529%2c114.4986%2c402.9877) ' y='83.698593' x='326.836101'/%3e %3c/g%3e %3cg id='svg_34'%3e %3crect id='svg_35' height='6.34' width='20.52' class='st0' y='86.2' x='321.58'/%3e %3c/g%3e %3cg id='svg_36'%3e %3crect id='svg_37' height='24.75' width='6.34' class='st0' transform='matrix(0.9556%2c-0.2946%2c0.2946%2c0.9556%2c-19.7967%2c122.424) ' y='75.874073' x='369.686666'/%3e %3c/g%3e %3cg id='svg_38'%3e %3crect id='svg_39' height='6.34' width='71.83' class='st0' y='20.46' x='395.51'/%3e %3c/g%3e %3cg id='svg_40'%3e %3crect id='svg_41' height='6.34' width='90.81' class='st0' y='57.44' x='386.02'/%3e %3c/g%3e %3cg id='svg_42'%3e %3cpath id='svg_43' d='m463.12%2c113.64l-56%2c0c-4.5%2c0 -8.59%2c-2.29 -10.94%2c-6.14c-2.35%2c-3.84 -2.52%2c-8.53 -0.46%2c-12.53l17.68%2c-35.81l5.64%2c2.89l-17.68%2c35.81c-1.04%2c2.02 -0.95%2c4.39 0.23%2c6.33c1.19%2c1.94 3.25%2c3.1 5.53%2c3.1l56%2c0c1.51%2c0 2.88%2c-0.71 3.74%2c-1.95c0.81%2c-1.16 1.03%2c-2.57 0.63%2c-3.91l-7.8%2c-12.34l5.36%2c-3.39l8.18%2c12.94l0.12%2c0.31c1.24%2c3.34 0.76%2c7.08 -1.28%2c10.01c-2.04%2c2.94 -5.39%2c4.68 -8.95%2c4.68z' class='st0'/%3e %3c/g%3e %3c/g%3e %3c/g%3e%3c/svg%3e",height:"30"})}),r,c(F,{navbar:!0,children:[e(F.Toggle,{as:Te,className:"nav-link",children:e("img",{className:"rounded-circle",width:"25",height:"25",src:s.avatar})}),e(F.Menu,{className:"shadow",children:i})]})]})})}const He=M.header`
292
292
  height: 54px;
293
- `;function Pe(c){let{require:i,children:r,fallback:n}=c;const[o]=re();let s=!1;return"function"==typeof i?s=i(o):("string"==typeof i&&(i=[i]),s=V(o.roles,i).length>0),s||(r=n),e(t,{children:r})}function Te(c){let{to:t,replace:i,...r}=c,n=o();return e(C,{...r,onClick:e=>{e.preventDefault(),n(t,{replace:i})}})}const Be=_(void 0),He=function(c){let{request:t,children:i}=c;const{result:r}=q(t);return r?e(Be.Provider,{value:r,children:i}):e(I,{wrap:!0})};function Ve(c){let{request:t,children:i}=c;const r=u();return"string"==typeof t?t={url:t.replace(/:(\w+)/g,((e,c)=>r[c]||e))}:t.url&&(t.url=t.url.replace(/:(\w+)/g,((e,c)=>r[c]||e))),e(He,{request:t,children:i},t.url)}function De(){return w(Be)}function Fe(c){let{onLogined:t,onAuthorize:i,implicit:r=!0}=c;const{result:n,error:o}=A((async()=>{let e;if(r){const c=Q.parse(window.location.hash);c.access_token&&(e=c.access_token)}else{const c=Q.parse(window.location.search);c&&(e=c,e.redirect_uri=sessionStorage.getItem("redirect_uri"))}if(i)try{const c=await i(e);c&&(e=c)}catch(e){if(M(e)){const c=e.response?.data;if(j(c))throw new Error(c.message)}throw e}return t(e)}),[]);return o?e(W,{className:"mt-5",children:e(O,{children:e(U,{status:"error",title:o.message})})}):n?e(m,{to:n,replace:!0}):e(I,{})}function We(c){let{onLogout:t}=c;const i=o();return A((async()=>{await t(),i("/login",{state:{from:"logout"}})}),[]),e(I,{})}function Ke(c){let{onLogin:t,onLogined:i,onAuthorize:r}=c;return e(W,{className:"vh-100 d-flex align-items-center",children:e(K,{className:"flex-fill",children:e(G,{lg:{span:6,offset:3},xxl:{span:4,offset:4},children:e(O,{className:"p-5",children:t({onAuthorize:r,onLogined:i})})})})})}function Ge(t){const{basename:i="/",onAuthorize:r,onLogout:n,onLogin:o,authentication:s="token",implicit:a,baseURL:l,userResolver:d,routes:h,RootComponent:g=L,extraRoutes:u=[]}=t;l&&(P.defaults.baseURL=l);const m=e=>{"token"===s&&P.defaults.authTokenName&&(e?localStorage.setItem(P.defaults.authTokenName,e):localStorage.removeItem(P.defaults.authTokenName))},v=e=>{m(e);const c=sessionStorage.getItem("restore_uri");return c&&sessionStorage.removeItem("restore_uri"),c||"/"},x=p([{path:"*",element:e(ie,{userResolver:d,onResolved:e=>{e.token&&m(e.token)}}),children:oe(h)},{path:"social",element:e(Fe,{implicit:a,onAuthorize:r,onLogined:v})},{path:"logout",element:e(We,{onLogout:async()=>{if(n)try{await n()}catch(e){}m()}})},{path:"login",element:e(Ke,{onLogin:o,onAuthorize:(e,c)=>{const{from:t}=window.history.state.usr||{};t&&"logout"!==t&&sessionStorage.setItem("restore_uri",function(e,c){return"/"===c?e:e.slice(c.length)}(t,i));const r=Q.stringifyUrl({url:H(X.join(i,"/social")),query:c});a||sessionStorage.setItem("redirect_uri",r),window.location.href=Q.stringifyUrl({url:e,query:{redirect_uri:r}})},onLogined:v})},...u],{basename:i});return function(){return c(T,{children:[e(g,{children:e(f,{router:x})}),e(B.Message,{})]})}}export{Pe as Access,Le as Content,Oe as Header,Te as LinkButton,pe as SiderLayout,$e as TabLayout,Ve as WithRequest,Ge as createApplication,De as useRequestData,re as useUser};
293
+ `;function Ve(c){let{require:r,children:i,fallback:n}=c;const[o]=Ue();let s=!1;return"function"==typeof r?s=r(o):("string"==typeof r&&(r=[r]),s=V(o.roles,r).length>0),s||(i=n),e(t,{children:i})}function De(c){let{to:t,replace:r,...i}=c,n=u();return e(C,{...i,onClick:e=>{e.preventDefault(),n(t,{replace:r})}})}const Fe=b(void 0),We=function(c){let{request:t,children:r}=c;const{result:i}=q(t);return i?e(Fe.Provider,{value:i,children:r}):e(R,{wrap:!0})};function Ke(c){let{request:t,children:r}=c;const i=g();return"string"==typeof t?t={url:t.replace(/:(\w+)/g,((e,c)=>i[c]||e))}:t.url&&(t.url=t.url.replace(/:(\w+)/g,((e,c)=>i[c]||e))),e(We,{request:t,children:r},t.url)}function Ge(){return y(Fe)}function Je(c){let{onLogined:t,onAuthorize:r,implicit:i=!0}=c;const{result:n,error:o}=A((async()=>{let e;if(i){const c=Q.parse(window.location.hash);c.access_token&&(e=c.access_token)}else{const c=Q.parse(window.location.search);c&&(e=c,e.redirect_uri=sessionStorage.getItem("redirect_uri"))}if(r)try{const c=await r(e);c&&(e=c)}catch(e){if($(e)){const c=e.response?.data;if(P(c))throw new Error(c.message)}throw e}return t(e)}),[]);return o?e(W,{className:"mt-5",children:e(j,{children:e(O,{status:"error",title:o.message})})}):n?e(m,{to:n,replace:!0}):e(R,{})}function Qe(c){let{onLogout:t}=c;const r=u();return A((async()=>{await t(),r("/login",{state:{from:"logout"}})}),[]),e(R,{})}function Xe(c){let{onLogin:t,onLogined:r,onAuthorize:i}=c;return e(W,{className:"vh-100 d-flex align-items-center",children:e(K,{className:"flex-fill",children:e(G,{lg:{span:6,offset:3},xxl:{span:4,offset:4},children:e(j,{className:"p-5",children:t({onAuthorize:i,onLogined:r})})})})})}function Ye(t){const{basename:r="/",onAuthorize:i,onLogout:n,onLogin:o,authentication:s="token",implicit:l,baseURL:a,appResolver:d,userResolver:h,routes:u,RootComponent:g=L,extraRoutes:m=[]}=t;a&&(U.defaults.baseURL=a);const v=e=>{"token"===s&&U.defaults.authTokenName&&(e?localStorage.setItem(U.defaults.authTokenName,e):localStorage.removeItem(U.defaults.authTokenName))},x=e=>{v(e);const c=sessionStorage.getItem("restore_uri");return c&&sessionStorage.removeItem("restore_uri"),c||"/"},b=p([{path:"*",element:e(Oe,{userResolver:h,onResolved:e=>{e.token&&v(e.token)}}),children:se(u)},{path:"social",element:e(Je,{implicit:l,onAuthorize:i,onLogined:x})},{path:"logout",element:e(Qe,{onLogout:async()=>{if(n)try{await n()}catch(e){}v()}})},{path:"login",element:e(Xe,{onLogin:o,onAuthorize:(e,c)=>{const{from:t}=window.history.state.usr||{};t&&"logout"!==t&&sessionStorage.setItem("restore_uri",function(e,c){return"/"===c?e:e.slice(c.length)}(t,r));const i=Q.stringifyUrl({url:H(X.join(r,"/social")),query:c});l||sessionStorage.setItem("redirect_uri",i),window.location.href=Q.stringifyUrl({url:e,query:{redirect_uri:i}})},onLogined:x})},...m],{basename:r});return function(){return c(T,{children:[e(g,{children:e(re,{appResolver:d,children:e(f,{router:b})})}),e(B.Message,{})]})}}export{Ve as Access,Ae as Content,Be as Header,De as LinkButton,fe as SiderLayout,Ce as TabLayout,Ke as WithRequest,Ye as createApplication,ne as useApp,ie as useAppState,Ge as useRequestData,Ue as useUser};
294
294
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/images/external.svg","../src/utils/get-menu-data.tsx","../src/components/user-provider.tsx","../src/layout/use-menu.tsx","../src/utils/transform-routes.ts","../src/layout/sider/context.tsx","../src/layout/sider/toggle.tsx","../src/layout/sider/index.tsx","../src/hooks/use-route-handle.ts","../src/components/content.tsx","../src/layout/tab.tsx","../src/components/header.tsx","../src/images/logo.svg","../src/components/access.tsx","../src/components/link-button.tsx","../src/components/with-request.tsx","../src/pages/social.tsx","../src/pages/logout.tsx","../src/pages/login.tsx","../src/utils/create-application.tsx"],"sourcesContent":["var img = \"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3e %3cg fill='%23888'%3e %3cpath d='M8 3l1.793 1.793L6 8.586 7.414 10l3.793-3.793L13 8V3z'/%3e %3cpath d='M11 11H5V5h2V3H3v10h10V9h-2z'/%3e %3c/g%3e%3c/svg%3e\";\n export default img;","import type { RouteObject } from 'react-router-dom';\r\nimport { ReactNode } from 'react';\r\nimport { User } from './types';\r\nimport { intersection } from 'lodash';\r\n\r\nexport interface MenuData {\r\n path: string;\r\n title: string;\r\n icon?: ReactNode;\r\n isExternal?: boolean;\r\n children: MenuData[];\r\n}\r\n\r\nconst formatRelativePath = (user: User, routes: RouteObject[], parent: string = '/'): MenuData[] => {\r\n\r\n const menus: MenuData[] = [];\r\n\r\n for (const route of routes) {\r\n\r\n let { meta = {}, path = '', children = [] } = route;\r\n\r\n if (meta.hideInMenu) {\r\n continue;\r\n }\r\n\r\n if (meta.access) {\r\n let access = meta.access;\r\n let passed = false;\r\n if (typeof access === 'function') {\r\n passed = access(user);\r\n } else if (typeof access === 'number') {\r\n passed = user.access_level >= access;\r\n } else {\r\n if (!Array.isArray(access)) {\r\n access = [access];\r\n }\r\n\r\n passed = intersection(user.roles, access).length > 0;\r\n }\r\n if (!passed) {\r\n continue;\r\n }\r\n }\r\n\r\n const title = meta.title;\r\n\r\n if (!title) {\r\n continue;\r\n }\r\n\r\n let isExternal = false;\r\n\r\n if (meta.href) {\r\n isExternal = true;\r\n path = meta.href;\r\n } else {\r\n path = `${parent}/${path}`.replace(/\\/{2,}/g, '/').replace(/\\/$/, '');\r\n }\r\n\r\n const icon = typeof meta.icon === 'string' ?\r\n <i className={`bi bi-${meta.icon}`} /> : meta.icon;\r\n\r\n const menu: MenuData = {\r\n title,\r\n icon,\r\n path,\r\n isExternal,\r\n children: []\r\n };\r\n\r\n if (!meta.hideChildrenInMenu && !isExternal && children.length > 0) {\r\n menu.children = formatRelativePath(user, children, path);\r\n }\r\n\r\n menus.push(menu);\r\n }\r\n\r\n return menus;\r\n};\r\n\r\nexport default function getMenuData(user: User, routes: RouteObject[], base: string = '/'): MenuData[] {\r\n return formatRelativePath(user, routes, base);\r\n}\r\n","import React, { Dispatch, SetStateAction, useContext, useState } from 'react';\r\nimport { User, UserResolver } from '../utils/types';\r\nimport { isRequestError, Loader, useAsync } from '@topthink/components';\r\nimport { Outlet, useNavigate } from 'react-router-dom';\r\n\r\ntype UserContextType = [User, Dispatch<SetStateAction<User>>, () => void] & {\r\n user: User,\r\n setUser: Dispatch<SetStateAction<User>>,\r\n refresh: () => void\r\n};\r\n\r\nexport const UserContext = React.createContext<UserContextType | null>(null);\r\n\r\ninterface Props {\r\n userResolver: UserResolver;\r\n onResolved: (user: User) => void;\r\n}\r\n\r\nconst UserProvider = function({ userResolver, onResolved }: Props) {\r\n const [state, setState] = useState<User | null>(null);\r\n\r\n const navigate = useNavigate();\r\n\r\n const { execute } = useAsync(async () => {\r\n if (userResolver) {\r\n const user = await userResolver();\r\n onResolved(user);\r\n return user;\r\n }\r\n }, [], {\r\n async onError(e) {\r\n if (isRequestError(e) && e.response?.status === 401) {\r\n const redirectUri = window.location.pathname + window.location.search;\r\n navigate(`/login`, { state: { from: redirectUri } });\r\n }\r\n },\r\n onSuccess(user) {\r\n if (user) {\r\n setState(user);\r\n }\r\n }\r\n });\r\n\r\n if (!state) {\r\n return <Loader />;\r\n }\r\n\r\n const value: any = [state, setState, execute];\r\n\r\n value.user = state;\r\n value.setUser = setState;\r\n value.refresh = execute;\r\n\r\n return <UserContext.Provider value={value}>\r\n <Outlet />\r\n </UserContext.Provider>;\r\n};\r\n\r\nexport function useUser() {\r\n const context = useContext(UserContext);\r\n if (!context) {\r\n throw new Error('please use `useUser` in UserContext');\r\n }\r\n\r\n return context;\r\n}\r\n\r\nexport default UserProvider;\r\n","import { useContext, useMemo } from 'react';\r\nimport { RouteObject, UNSAFE_RouteContext } from 'react-router-dom';\r\nimport getMenuData, { MenuData } from '../utils/get-menu-data';\r\nimport { useUser } from '../components/user-provider';\r\n\r\nexport default function useMenu(routes?: RouteObject[]): [MenuData[], string | undefined] {\r\n\r\n const { matches } = useContext(UNSAFE_RouteContext);\r\n const { user } = useUser();\r\n const routeMatch = matches[matches.length - 1];\r\n const pathnameBase = routeMatch.pathnameBase || '/';\r\n\r\n const routesMatch = routes || routeMatch.route.children || [];\r\n\r\n const menu = useMemo(() => getMenuData(user, routesMatch, pathnameBase), [user, routesMatch, pathnameBase]);\r\n\r\n const title = useMemo(() => {\r\n return matches.reduceRight((title, match) => {\r\n if (title) return title;\r\n return match.route.handle?.title;\r\n }, undefined);\r\n }, [matches]);\r\n\r\n return [menu, title];\r\n}\r\n","import { RouteObject } from 'react-router-dom';\r\n\r\nexport default function transformRoutes(routes: RouteObject[], hideInMenu?: boolean) {\r\n return routes.map((route) => {\r\n if (route.children) {\r\n route.children = transformRoutes(route.children, route.meta?.hideChildrenInMenu);\r\n }\r\n\r\n route.handle = route.handle || {};\r\n\r\n const title = route.meta?.title;\r\n if (title !== undefined) {\r\n route.handle.title = title;\r\n }\r\n\r\n hideInMenu = route.meta?.hideInMenu || (hideInMenu && !route.index);\r\n if (hideInMenu !== undefined) {\r\n route.handle.hideInMenu = hideInMenu;\r\n }\r\n\r\n const hideMenu = route.meta?.hideMenu;\r\n if (hideMenu !== undefined) {\r\n route.handle.hideMenu = hideMenu;\r\n }\r\n\r\n const access = route.meta?.access;\r\n if (access !== undefined) {\r\n route.handle.access = access;\r\n }\r\n\r\n return route;\r\n });\r\n}\r\n","import { createContext, ReactNode, useContext } from 'react';\r\n\r\nexport const SiderContext = createContext<{\r\n toggle: ReactNode,\r\n show: boolean,\r\n setShow: (show: boolean) => void,\r\n headless: boolean\r\n} | undefined>(undefined);\r\n\r\nexport const useSider = () => {\r\n return useContext(SiderContext);\r\n};\r\n","import { styled } from '@topthink/components';\r\nimport { useSider } from './context';\r\n\r\nexport default function Toggle() {\r\n const sider = useSider();\r\n return <Trigger onClick={() => sider?.setShow(true)}><i className='bi bi-list' /></Trigger>;\r\n}\r\n\r\nconst Trigger = styled.div`\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n font-size: 2rem;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n`;\r\n","import RcMenu, { MenuItem, SubMenu } from 'rc-menu';\r\nimport { Link, Outlet, RouteObject, useLocation, useRoutes } from 'react-router-dom';\r\nimport { ElementType, memo, ReactNode, useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { MenuData } from '../../utils/get-menu-data';\r\nimport type { CSSMotionProps } from 'rc-motion';\r\nimport { Offcanvas, styled, useWindowSize } from '@topthink/components';\r\nimport { ReactComponent as ExternalIcon } from '../../images/external.svg';\r\nimport useMenu from '../use-menu';\r\nimport transformRoutes from '../../utils/transform-routes';\r\nimport Toggle from './toggle';\r\nimport { SiderContext } from './context';\r\nimport useRouteHandle from '../../hooks/use-route-handle';\r\n\r\nconst renderMenuItems = (items: MenuData[]) => {\r\n return items.map((item) => {\r\n\r\n const title = <MenuTitle>\r\n {item.icon}\r\n {item.title}\r\n {item.isExternal && <ExternalIcon />}\r\n </MenuTitle>;\r\n\r\n if (item.children.length > 0) {\r\n return <SubMenu title={title} key={item.path}>\r\n {renderMenuItems(item.children)}\r\n </SubMenu>;\r\n } else {\r\n return <MenuItem key={item.path}>\r\n {item.isExternal ?\r\n <a href={item.path} target='_blank'>{title}</a> :\r\n <Link to={item.path}>{title}</Link>\r\n }\r\n </MenuItem>;\r\n }\r\n });\r\n};\r\n\r\nconst collapseNode = () => {\r\n return { height: 0 };\r\n};\r\nconst expandNode = (node: HTMLElement) => {\r\n return { height: node.scrollHeight };\r\n};\r\n\r\nconst motion: CSSMotionProps = {\r\n motionName: 'rc-menu-collapse',\r\n motionAppear: true,\r\n onAppearStart: collapseNode,\r\n onAppearActive: expandNode,\r\n onEnterStart: collapseNode,\r\n onEnterActive: expandNode,\r\n onLeaveStart: expandNode,\r\n onLeaveActive: collapseNode,\r\n};\r\n\r\ninterface Props<As extends ElementType = ElementType> {\r\n className?: string;\r\n title?: string;\r\n header?: ReactNode;\r\n headerAs?: As;\r\n footer?: ReactNode;\r\n footerAs?: As;\r\n routes?: RouteObject[];\r\n top?: number;\r\n}\r\n\r\nexport default function SiderLayout({ className, title, header, headerAs, footer, footerAs, top = 54, routes }: Props) {\r\n const { isMobile } = useWindowSize();\r\n const [menu, defaultTitle] = useMenu(routes);\r\n const [showToggle, setShowToggle] = useState(false);\r\n const { pathname, key } = useLocation();\r\n\r\n const { hideMenu = false } = useRouteHandle();\r\n\r\n const selectedKeys = useMemo(() => {\r\n const keys: string[] = [];\r\n const parts = pathname.split('/');\r\n parts.reduce<string[]>((pre, curr) => {\r\n if (pre.length > 1) {\r\n keys.push(pre.join('/'));\r\n }\r\n return [...pre, curr];\r\n }, []);\r\n keys.push(pathname);\r\n return keys;\r\n }, [pathname]);\r\n\r\n const [openKeys, setOpenKeys] = useState<string[]>([]);\r\n\r\n useEffect(() => {\r\n setShowToggle(false);\r\n }, [key]);\r\n\r\n useEffect(() => {\r\n setOpenKeys(selectedKeys.slice(0, -1));\r\n }, [selectedKeys]);\r\n\r\n const onOpenChange = useCallback((openKeys: string[]) => {\r\n const currentKey = openKeys[openKeys.length - 1];\r\n setOpenKeys(openKeys.filter(key => currentKey.startsWith(key)));\r\n }, [openKeys, setOpenKeys]);\r\n\r\n const children = routes ? <Routes routes={routes} /> : <Outlet />;\r\n\r\n if (hideMenu) {\r\n return children;\r\n }\r\n\r\n if (!header) {\r\n header = <Title>{title || defaultTitle}</Title>;\r\n }\r\n\r\n const HeaderComp = headerAs || Header;\r\n\r\n const FooterComp = footerAs || Footer;\r\n\r\n const sidebar = <Sidebar className={className}>\r\n <HeaderComp>{header}</HeaderComp>\r\n <Menu\r\n mode='inline'\r\n motion={motion}\r\n openKeys={openKeys}\r\n onOpenChange={onOpenChange}\r\n selectedKeys={selectedKeys}\r\n >\r\n {renderMenuItems(menu)}\r\n </Menu>\r\n <FooterComp>{footer}</FooterComp>\r\n </Sidebar>;\r\n\r\n const siderToggle = isMobile ? <Toggle /> : null;\r\n\r\n return <SiderContext.Provider value={{\r\n show: showToggle,\r\n setShow: setShowToggle,\r\n toggle: siderToggle,\r\n headless: top == 0\r\n }}>\r\n <Container $top={top}>\r\n {isMobile ? <Offcanvas\r\n show={showToggle}\r\n onHide={() => {\r\n setShowToggle(false);\r\n }}\r\n placement={'start'}\r\n style={{\r\n width: '230px',\r\n }}\r\n >\r\n {sidebar}\r\n </Offcanvas> : sidebar}\r\n <Content>\r\n <Main>\r\n {children}\r\n </Main>\r\n </Content>\r\n </Container>\r\n </SiderContext.Provider>;\r\n}\r\n\r\nconst Routes = memo(function({ routes }: { routes: RouteObject[] }) {\r\n return useRoutes(useMemo(() => transformRoutes(routes), [routes]));\r\n});\r\n\r\nconst Sidebar = styled.nav`\r\n position: fixed;\r\n top: 0;\r\n bottom: 0;\r\n left: 0;\r\n z-index: 100;\r\n padding: var(--bs-header-height) 0 0;\r\n border-right: 1px solid #e3e3e3;\r\n width: 230px;\r\n background-color: #f5f5f5;\r\n display: flex;\r\n flex-direction: column;\r\n`;\r\n\r\nconst Title = styled.div`\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n font-size: 16px;\r\n`;\r\n\r\nconst Header = styled.div`\r\n height: 64px;\r\n display: flex;\r\n align-items: center;\r\n padding: 10px 8px 10px 24px;\r\n border-bottom: 1px solid #e3e3e3;\r\n flex-grow: 0;\r\n flex-shrink: 0;\r\n`;\r\n\r\nconst Footer = styled.div`\r\n flex-grow: 0;\r\n flex-shrink: 0;\r\n`;\r\nconst Content = styled.div`\r\n flex: 1;\r\n @media (min-width: 992px) {\r\n margin-left: 230px;\r\n }\r\n`;\r\n\r\nconst Main = styled.main`\r\n min-height: calc(var(--100vh, 100vh) - var(--bs-header-height));\r\n position: relative;\r\n`;\r\n\r\nconst MenuTitle = styled.div`\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n\r\n .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n min-width: 19px;\r\n text-align: center;\r\n }\r\n`;\r\n\r\nconst Menu = styled(RcMenu)`\r\n border: none;\r\n box-shadow: none;\r\n padding: 10px 0;\r\n flex: 1;\r\n overflow: auto;\r\n\r\n .rc-menu-item {\r\n display: flex;\r\n\r\n &:hover {\r\n background-color: #f0f0f0;\r\n }\r\n\r\n a {\r\n flex: 1;\r\n text-decoration: none;\r\n color: dimgray;\r\n }\r\n }\r\n\r\n .rc-menu-sub {\r\n background-color: #eee;\r\n border-top: 1px solid #eee;\r\n border-bottom: 1px solid #eee;\r\n\r\n & > li {\r\n &:first-child {\r\n margin-top: 4px;\r\n }\r\n\r\n &:last-child {\r\n margin-bottom: 4px;\r\n }\r\n }\r\n\r\n .rc-menu-item-selected {\r\n background-color: #eee;\r\n color: var(--bs-primary);\r\n\r\n & > a {\r\n color: var(--bs-primary);\r\n }\r\n }\r\n\r\n .rc-menu-item {\r\n &:hover {\r\n background-color: #e7e7e7;\r\n }\r\n }\r\n }\r\n\r\n .rc-menu-submenu {\r\n & > .rc-menu-submenu-title {\r\n &:hover {\r\n background-color: #e7e7e7;\r\n }\r\n }\r\n }\r\n\r\n .rc-menu-item-active,\r\n .rc-menu-submenu-active > .rc-menu-submenu-title {\r\n background-color: #eee;\r\n }\r\n\r\n .rc-menu-item,\r\n .rc-menu-submenu > .rc-menu-submenu-title {\r\n padding: 0 8px 0 24px;\r\n font-size: 14px;\r\n line-height: 36px;\r\n cursor: pointer;\r\n }\r\n\r\n .rc-menu-sub > .rc-menu-item,\r\n .rc-menu-sub > .rc-menu-submenu > .rc-menu-submenu-title {\r\n padding-top: 0;\r\n padding-bottom: 0;\r\n padding-right: 0;\r\n }\r\n\r\n .rc-menu-submenu-arrow {\r\n line-height: 20px;\r\n }\r\n\r\n .rc-menu-item-selected {\r\n background-color: #f5f5f5;\r\n color: var(--bs-primary);\r\n\r\n & > a {\r\n color: var(--bs-primary);\r\n }\r\n }\r\n\r\n .rc-menu-submenu-selected {\r\n background-color: #eee;\r\n\r\n & > .rc-menu-submenu-title {\r\n color: var(--bs-primary);\r\n font-weight: 500;\r\n }\r\n }\r\n\r\n & > .rc-menu-item {\r\n line-height: 38px;\r\n }\r\n\r\n & > .rc-menu-submenu {\r\n &.rc-menu-submenu-selected {\r\n background-color: #f5f5f5;\r\n }\r\n\r\n & > .rc-menu-submenu-title {\r\n line-height: 38px;\r\n\r\n &:hover {\r\n background-color: #f0f0f0;\r\n }\r\n }\r\n\r\n &.rc-menu-submenu-active > .rc-menu-submenu-title {\r\n background-color: #f5f5f5;\r\n }\r\n\r\n & > .rc-menu-sub {\r\n border-top: 1px solid #e6e6e6;\r\n border-bottom: 1px solid #e6e6e6;\r\n\r\n & > li {\r\n &:first-child {\r\n margin-top: 9px;\r\n }\r\n\r\n &:last-child {\r\n margin-bottom: 9px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n`;\r\n\r\nconst Container = styled.div<{ $top: number }>`\r\n --bs-header-height: ${(p) => p.$top}px;\r\n display: flex;\r\n flex-wrap: nowrap;\r\n width: 100%;\r\n\r\n &:has(&) {\r\n > ${Sidebar} {\r\n display: none;\r\n }\r\n\r\n > ${Content} {\r\n margin-left: 0;\r\n }\r\n }\r\n`;\r\n","import { useMatches } from 'react-router-dom';\r\n\r\nexport default function useRouteHandle() {\r\n const matches = useMatches();\r\n\r\n return matches.reduce<Record<string, any>>((route, match) => {\r\n return { ...route, ...match.handle };\r\n }, {});\r\n}\r\n","import { css, styled } from '@topthink/components';\r\nimport { ElementType, PropsWithChildren, ReactNode, useContext, useMemo } from 'react';\r\nimport { RouteObject, UNSAFE_RouteContext, useLocation, useNavigate, } from 'react-router-dom';\r\nimport { useSider } from '../layout/sider/context';\r\n\r\ninterface ContentProps<As extends ElementType = ElementType> {\r\n title?: ReactNode;\r\n header?: ReactNode;\r\n nav?: ReactNode;\r\n extra?: ReactNode;\r\n showBack?: boolean | string;\r\n fixed?: boolean;\r\n className?: string;\r\n bodyAs?: As;\r\n}\r\n\r\nexport default function Content({\r\n title,\r\n header,\r\n nav,\r\n children,\r\n extra,\r\n showBack,\r\n className,\r\n bodyAs,\r\n fixed = true\r\n}: PropsWithChildren<ContentProps>) {\r\n const { matches } = useContext(UNSAFE_RouteContext);\r\n const route = useMemo(() => {\r\n return matches.reduceRight<RouteObject | undefined>((route, match) => {\r\n if (route || match.route.index) return route;\r\n return match.route;\r\n }, undefined);\r\n }, [matches]);\r\n\r\n const sider = useSider();\r\n\r\n const defaultShowBack = route?.handle?.hideInMenu === true;\r\n const defaultTitle = route?.handle?.title;\r\n\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n\r\n if (showBack === undefined) {\r\n showBack = defaultShowBack;\r\n }\r\n\r\n if (header === undefined) {\r\n header = <Title className={'fs-4 text-truncate'}>{title || defaultTitle}</Title>;\r\n }\r\n\r\n return <Container className={className}>\r\n <Header $fixed={fixed}>\r\n <div className='container'>\r\n {sider?.headless && sider.toggle}\r\n {showBack && (location.key !== 'default' || typeof showBack === 'string') &&\r\n <Back onClick={() => typeof showBack === 'string' ? navigate(showBack) : navigate(-1)}><i className='bi bi-arrow-left-short' /></Back>}\r\n {header}\r\n {nav}\r\n <Extra>{extra}</Extra>\r\n </div>\r\n </Header>\r\n <Body className='container' as={bodyAs}>\r\n {children}\r\n </Body>\r\n </Container>;\r\n};\r\n\r\nconst Back = styled.div`\r\n font-size: 32px;\r\n cursor: pointer;\r\n`;\r\n\r\nconst Container = styled.div`\r\n width: 100%;\r\n container-type: inline-size;\r\n\r\n .container {\r\n @media (min-width: 992px) and (max-width: 1540px) {\r\n max-width: calc(100vw - 236px - 6px);\r\n }\r\n @media (max-width: 991px) {\r\n max-width: calc(100vw - 6px);\r\n }\r\n @container (max-width: 1310px) {\r\n max-width: 100cqw;\r\n }\r\n }\r\n`;\r\n\r\nconst Header = styled.div<{ $fixed?: boolean }>`\r\n background-color: #fff;\r\n display: flex;\r\n border-bottom: 1px solid rgb(227, 227, 227);\r\n align-items: center;\r\n height: 65px;\r\n\r\n ${props => props.$fixed && css`\r\n position: sticky;\r\n top: 0;\r\n z-index: 1000;\r\n `};\r\n\r\n .container {\r\n padding: 0 12px;\r\n display: flex;\r\n align-items: center;\r\n gap: .5rem;\r\n }\r\n`;\r\n\r\nconst Body = styled.div`\r\n margin-top: 24px;\r\n margin-bottom: 24px;\r\n\r\n @media (max-width: 1540px) {\r\n margin-top: 1rem;\r\n margin-bottom: 1rem;\r\n }\r\n`;\r\n\r\nconst Title = styled.div`\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n min-width: 50px;\r\n flex-shrink: 0;\r\n`;\r\n\r\nconst Extra = styled.div`\r\n margin-left: auto;\r\n`;\r\n","import { Dropdown, Nav } from 'react-bootstrap';\r\nimport Content from '../components/content';\r\nimport { Link, Outlet, useLocation } from 'react-router-dom';\r\nimport useMenu from './use-menu';\r\nimport { styled, useWindowSize } from '@topthink/components';\r\nimport classNames from 'classnames';\r\nimport { ReactNode } from 'react';\r\n\r\ninterface Props {\r\n title?: ReactNode;\r\n header?: ReactNode;\r\n showBack?: boolean;\r\n extra?: ReactNode;\r\n}\r\n\r\nexport default function TabLayout({ title, header, showBack, extra }: Props) {\r\n\r\n const [menu, defaultTitle] = useMenu();\r\n const { pathname } = useLocation();\r\n const { isMobile } = useWindowSize();\r\n\r\n const nav = isMobile ? <Dropdown className='ms-2 d-flex align-items-center'>\r\n <Dropdown.Toggle variant='light' size={'sm'} />\r\n <Dropdown.Menu>\r\n {menu.map((item) => {\r\n return <Dropdown.Item active={pathname.startsWith(item.path)} as={Link} to={item.path} replace key={item.path}>\r\n {item.icon}\r\n {item.title}\r\n </Dropdown.Item>;\r\n })}\r\n </Dropdown.Menu>\r\n </Dropdown> : <StyledNav>\r\n {menu.map((item) => {\r\n return <Nav.Item key={item.path}>\r\n <NavLink className={classNames('nav-link', { active: pathname.startsWith(item.path) })} to={item.path} replace>\r\n {item.icon}\r\n {item.title}\r\n </NavLink>\r\n </Nav.Item>;\r\n })}\r\n </StyledNav>;\r\n\r\n return <Content title={title || defaultTitle} header={header} nav={nav} showBack={showBack} extra={extra}>\r\n <Outlet />\r\n </Content>;\r\n}\r\n\r\n\r\nconst StyledNav = styled(Nav)`\r\n flex-wrap: nowrap;\r\n margin-left: 1.25rem;\r\n`;\r\n\r\nconst NavLink = styled(Link)`\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n white-space: nowrap;\r\n position: relative;\r\n\r\n .bi, svg {\r\n text-align: center;\r\n }\r\n\r\n &.active {\r\n &:after {\r\n content: '';\r\n height: 2px;\r\n background: var(--bs-primary);\r\n display: block;\r\n position: absolute;\r\n left: 1rem;\r\n right: 1rem;\r\n bottom: -2px;\r\n }\r\n }\r\n`;\r\n","import logoSrc from '../images/logo.svg';\r\nimport { Dropdown } from 'react-bootstrap';\r\nimport { PropsWithChildren, ReactNode } from 'react';\r\nimport { useUser } from './user-provider';\r\nimport classNames from 'classnames';\r\nimport { styled } from '@topthink/components';\r\n\r\nconst Avatar = styled.a`\r\n cursor: pointer;\r\n`;\r\n\r\ninterface Props {\r\n menus: ReactNode;\r\n className?: string;\r\n logo?: boolean;\r\n}\r\n\r\nexport default function Header({ children, menus, className, logo = true }: PropsWithChildren<Props>) {\r\n const [user] = useUser();\r\n\r\n return <Container\r\n className={classNames('navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top', className)}>\r\n <div className='container-fluid'>\r\n {logo && <a className='navbar-brand' href='https://www.topthink.com'>\r\n <img src={logoSrc} height='30' />\r\n </a>}\r\n {children}\r\n <Dropdown navbar>\r\n <Dropdown.Toggle as={Avatar} className='nav-link'>\r\n <img className='rounded-circle' width='25' height='25' src={user.avatar} />\r\n </Dropdown.Toggle>\r\n <Dropdown.Menu className={'shadow'}>\r\n {menus}\r\n </Dropdown.Menu>\r\n </Dropdown>\r\n </div>\r\n </Container>;\r\n}\r\n\r\nconst Container = styled.header`\r\n height: 54px;\r\n`;\r\n","var img = \"data:image/svg+xml,%3csvg width='485' height='132' xmlns='http://www.w3.org/2000/svg' xml:space='preserve' style='enable-background:new 0 0 531.69 198.43%3b' version='1.1'%3e %3cstyle type='text/css'%3e.st0%7bfill:%233C60FF%3b%7d%3c/style%3e %3cg%3e %3ctitle%3ebackground%3c/title%3e %3crect fill='none' id='canvas_background' height='134' width='487' y='-1' x='-1'/%3e %3c/g%3e %3cg%3e %3ctitle%3eLayer 1%3c/title%3e %3cpath id='svg_1' d='m132.29%2c62.34c-1.19%2c-18.77 -10.34%2c-35.36 -24.11%2c-46.46c-11.15%2c-8.99 -25.34%2c-14.38 -40.79%2c-14.38c-0.55%2c0 -1.09%2c0.01 -1.63%2c0.02c-3.32%2c0.08 -6.57%2c0.41 -9.75%2c0.98c-30.49%2c5.38 -53.65%2c32 -53.65%2c64.04c0%2c1.87 0.08%2c3.73 0.24%2c5.57c2.5%2c29.51 24.7%2c53.4 53.41%2c58.47c2.38%2c0.42 4.8%2c0.72 7.26%2c0.86c0.83%2c0.05 1.66%2c0.09 2.5%2c0.11c0.54%2c0.01 1.08%2c0.02 1.63%2c0.02c34.04%2c0 61.97%2c-26.16 64.79%2c-59.46c0.16%2c-1.83 0.24%2c-3.69 0.24%2c-5.57c0%2c-1.42 -0.05%2c-2.82 -0.14%2c-4.2zm-76.27%2c32.5c-0.26%2c0.01 -0.53%2c0.01 -0.79%2c0.01c-14.56%2c0 -26.88%2c-9.57 -31.03%2c-22.76c-0.97%2c-3.08 -1.49%2c-6.35 -1.49%2c-9.75c0%2c-17.95 14.56%2c-32.52 32.51%2c-32.52c0.26%2c0 0.53%2c0 0.79%2c0.01c3.41%2c0.08 6.69%2c0.68 9.75%2c1.74c6.5%2c2.22 12.06%2c6.45 15.97%2c11.94c1.98%2c2.78 3.54%2c5.9 4.57%2c9.25c0.94%2c3.03 1.44%2c6.24 1.44%2c9.58l-9.75%2c0c0%2c-2.18 -0.31%2c-4.29 -0.88%2c-6.28c-0.92%2c-3.23 -2.55%2c-6.17 -4.69%2c-8.64c-1.86%2c-2.14 -4.12%2c-3.93 -6.65%2c-5.25c-2.93%2c-1.54 -6.24%2c-2.46 -9.75%2c-2.58c-0.26%2c-0.01 -0.52%2c-0.01 -0.79%2c-0.01c-12.57%2c0 -22.76%2c10.19 -22.76%2c22.76c0%2c3.49 0.79%2c6.8 2.19%2c9.75c3.65%2c7.69 11.49%2c13.01 20.57%2c13.01c0.27%2c0 0.53%2c-0.01 0.79%2c-0.01l0%2c9.75zm55.7%2c-17.92c-3.35%2c10.5 -13.18%2c18.09 -24.78%2c18.09c-3.13%2c0 -6.13%2c-0.55 -8.91%2c-1.57c-2.18%2c-0.8 -4.24%2c-1.88 -6.11%2c-3.21c-2.38%2c-1.68 -4.47%2c-3.76 -6.16%2c-6.13c-0.28%2c-0.39 -0.55%2c-0.79 -0.81%2c-1.2c-2.03%2c-3.2 -3.38%2c-6.87 -3.85%2c-10.82l9.87%2c0c0.33%2c1.71 0.92%2c3.32 1.74%2c4.8c1.61%2c2.91 4.09%2c5.26 7.09%2c6.72c0.57%2c0.28 1.15%2c0.53 1.76%2c0.73c1.68%2c0.6 3.49%2c0.92 5.37%2c0.92c7.92%2c0 14.52%2c-5.67 15.96%2c-13.17c0.2%2c-1 0.3%2c-2.04 0.3%2c-3.09c0%2c-2.37 -0.51%2c-4.63 -1.43%2c-6.67c-1.66%2c-3.71 -4.68%2c-6.68 -8.43%2c-8.28l3.54%2c-9.1c7.43%2c3.08 13.13%2c9.49 15.21%2c17.38c0.44%2c1.64 0.72%2c3.34 0.81%2c5.09c0.04%2c0.52 0.05%2c1.05 0.05%2c1.58c0%2c1.05 -0.07%2c2.07 -0.18%2c3.09c-0.18%2c1.68 -0.54%2c3.3 -1.04%2c4.84z' class='st0'/%3e %3cg id='svg_2'%3e %3cg id='svg_3'%3e %3crect id='svg_4' height='6.34' width='94.12' class='st0' y='20.46' x='163.29'/%3e %3c/g%3e %3cg id='svg_5'%3e %3cpath id='svg_6' d='m169.31%2c113.72l0%2c-6.34c6.49%2c0 11.77%2c-5.28 11.77%2c-11.77l0%2c-71.98l6.34%2c0l0%2c71.98c0%2c9.98 -8.12%2c18.11 -18.11%2c18.11z' class='st0'/%3e %3c/g%3e %3cg id='svg_7'%3e %3cpath id='svg_8' d='m255.49%2c91.27l-6.34%2c0l0%2c-38.2c0%2c-5.06 -4.12%2c-9.18 -9.18%2c-9.18l-19.37%2c0c-5.06%2c0 -9.18%2c4.12 -9.18%2c9.18l0%2c38.2l-6.34%2c0l0%2c-38.2c0%2c-8.55 6.96%2c-15.51 15.51%2c-15.51l19.38%2c0c8.55%2c0 15.51%2c6.96 15.51%2c15.51l0%2c38.2l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_9'%3e %3crect id='svg_10' height='17.09' width='6.34' class='st0' y='23.63' x='227.12'/%3e %3c/g%3e %3cg id='svg_11'%3e %3cpath id='svg_12' d='m206.43%2c113.84l-3.34%2c0l0%2c-6.34l3.34%2c0c6.3%2c0 12.9%2c-3.56 15.35%2c-8.29c3.49%2c-6.71 5.33%2c-14.25 5.33%2c-21.81l0%2c-26.13l6.34%2c0l0%2c26.13c0%2c8.58 -2.09%2c17.13 -6.05%2c24.74c-3.98%2c7.68 -13.57%2c11.7 -20.97%2c11.7z' class='st0'/%3e %3c/g%3e %3cg id='svg_13'%3e %3cpath id='svg_14' d='m257.48%2c113.84l-3.34%2c0c-7.4%2c0 -16.98%2c-4.02 -20.98%2c-11.7c-3.96%2c-7.61 -6.05%2c-16.16 -6.05%2c-24.74l6.34%2c0c0%2c7.56 1.84%2c15.1 5.33%2c21.81c2.46%2c4.73 9.06%2c8.29 15.35%2c8.29l3.34%2c0l0%2c6.34l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_15'%3e %3crect id='svg_16' height='6.34' width='42.87' class='st0' y='27.89' x='274.07'/%3e %3c/g%3e %3cg id='svg_17'%3e %3crect id='svg_18' height='61.38' width='6.34' class='st0' y='14.89' x='293.05'/%3e %3c/g%3e %3cg id='svg_19'%3e %3crect id='svg_20' height='6.34' width='33.26' class='st0' transform='matrix(0.11%2c-0.9939%2c0.9939%2c0.11%2c194.7608%2c392.0006) ' y='46.985071' x='325.728637'/%3e %3c/g%3e %3cg id='svg_21'%3e %3crect id='svg_22' height='33.26' width='6.34' class='st0' transform='matrix(0.9939%2c-0.11%2c0.11%2c0.9939%2c-7.5075%2c38.3801) ' y='37.060893' x='310.495485'/%3e %3c/g%3e %3cg id='svg_23'%3e %3cpath id='svg_24' d='m352.9%2c77.14l-15.15%2c0c-7.52%2c0 -13.64%2c-6.12 -13.64%2c-13.63l0%2c-29.61c0%2c-7.52 6.12%2c-13.64 13.64%2c-13.64l15.15%2c0c7.52%2c0 13.64%2c6.12 13.64%2c13.64l0%2c29.61c0%2c7.52 -6.12%2c13.63 -13.64%2c13.63zm-15.15%2c-50.54c-4.02%2c0 -7.3%2c3.27 -7.3%2c7.3l0%2c29.61c0%2c4.02 3.27%2c7.3 7.3%2c7.3l15.15%2c0c4.02%2c0 7.3%2c-3.27 7.3%2c-7.3l0%2c-29.61c0%2c-4.02 -3.27%2c-7.3 -7.3%2c-7.3l-15.15%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_25'%3e %3cg id='svg_26'%3e %3crect id='svg_27' height='6.34' width='17.8' class='st0' y='37.2' x='336.43'/%3e %3c/g%3e %3cg id='svg_28'%3e %3crect id='svg_29' height='6.34' width='17.8' class='st0' y='53.87' x='336.43'/%3e %3c/g%3e %3c/g%3e %3cg id='svg_30'%3e %3cpath id='svg_31' d='m352.7%2c113.84l-37.98%2c0c-8%2c0 -14.5%2c-6.51 -14.5%2c-14.5l0%2c-16.14l6.34%2c0l0%2c16.13c0%2c4.5 3.66%2c8.17 8.17%2c8.17l37.98%2c0l0%2c6.34l-0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_32'%3e %3crect id='svg_33' height='6.34' width='23.57' class='st0' transform='matrix(0.2529%2c-0.9675%2c0.9675%2c0.2529%2c114.4986%2c402.9877) ' y='83.698593' x='326.836101'/%3e %3c/g%3e %3cg id='svg_34'%3e %3crect id='svg_35' height='6.34' width='20.52' class='st0' y='86.2' x='321.58'/%3e %3c/g%3e %3cg id='svg_36'%3e %3crect id='svg_37' height='24.75' width='6.34' class='st0' transform='matrix(0.9556%2c-0.2946%2c0.2946%2c0.9556%2c-19.7967%2c122.424) ' y='75.874073' x='369.686666'/%3e %3c/g%3e %3cg id='svg_38'%3e %3crect id='svg_39' height='6.34' width='71.83' class='st0' y='20.46' x='395.51'/%3e %3c/g%3e %3cg id='svg_40'%3e %3crect id='svg_41' height='6.34' width='90.81' class='st0' y='57.44' x='386.02'/%3e %3c/g%3e %3cg id='svg_42'%3e %3cpath id='svg_43' d='m463.12%2c113.64l-56%2c0c-4.5%2c0 -8.59%2c-2.29 -10.94%2c-6.14c-2.35%2c-3.84 -2.52%2c-8.53 -0.46%2c-12.53l17.68%2c-35.81l5.64%2c2.89l-17.68%2c35.81c-1.04%2c2.02 -0.95%2c4.39 0.23%2c6.33c1.19%2c1.94 3.25%2c3.1 5.53%2c3.1l56%2c0c1.51%2c0 2.88%2c-0.71 3.74%2c-1.95c0.81%2c-1.16 1.03%2c-2.57 0.63%2c-3.91l-7.8%2c-12.34l5.36%2c-3.39l8.18%2c12.94l0.12%2c0.31c1.24%2c3.34 0.76%2c7.08 -1.28%2c10.01c-2.04%2c2.94 -5.39%2c4.68 -8.95%2c4.68z' class='st0'/%3e %3c/g%3e %3c/g%3e %3c/g%3e%3c/svg%3e\";\n export default img;","import { ReactNode } from 'react';\r\nimport { intersection } from 'lodash';\r\nimport { useUser } from './user-provider';\r\nimport { User } from '../utils/types';\r\n\r\nexport interface AccessProps {\r\n require?: string | string[] | ((user: User) => boolean);\r\n fallback?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport default function Access({\r\n require,\r\n children,\r\n fallback\r\n}: AccessProps) {\r\n const [user,] = useUser();\r\n let passed = false;\r\n if (typeof require === 'function') {\r\n passed = require(user);\r\n } else {\r\n if (typeof require === 'string') {\r\n require = [require];\r\n }\r\n passed = intersection(user.roles, require).length > 0;\r\n }\r\n if (!passed) {\r\n children = fallback;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","import { LinkProps, useNavigate } from 'react-router-dom';\r\nimport { Button, ButtonProps } from '@topthink/components';\r\n\r\ninterface Props extends ButtonProps, Pick<LinkProps, 'to' | 'replace'> {\r\n\r\n}\r\n\r\nexport default function LinkButton({ to, replace, ...props }: Props) {\r\n let navigate = useNavigate();\r\n\r\n return <Button {...props} onClick={(e) => {\r\n e.preventDefault();\r\n navigate(to, { replace });\r\n }} />;\r\n}\r\n","import { Loader, RequestConfig, useRequest } from '@topthink/components';\r\nimport { createContext, ReactNode, useContext } from 'react';\r\nimport { useParams } from 'react-router-dom';\r\n\r\nconst Context = createContext<any>(undefined);\r\n\r\ninterface Props {\r\n request: RequestConfig;\r\n children: ReactNode;\r\n}\r\n\r\nconst Inner = function({ request, children }: Props) {\r\n const { result } = useRequest(request);\r\n\r\n if (!result) {\r\n return <Loader wrap />;\r\n }\r\n\r\n return <Context.Provider value={result}>\r\n {children}\r\n </Context.Provider>;\r\n};\r\n\r\nexport default function WithRequest({ request, children }: Props) {\r\n const params = useParams();\r\n\r\n if (typeof request === 'string') {\r\n request = {\r\n url: request.replace(/:(\\w+)/g, (all, name) => {\r\n return params[name] || all;\r\n })\r\n };\r\n } else if (request.url) {\r\n request.url = request.url.replace(/:(\\w+)/g, (all, name) => {\r\n return params[name] || all;\r\n });\r\n }\r\n\r\n return <Inner key={request.url} request={request}>{children}</Inner>;\r\n}\r\n\r\nexport function useRequestData<T = any>(): T {\r\n return useContext(Context);\r\n}\r\n","import { Card, isRecord, isRequestError, Loader, Result, useAsync } from '@topthink/components';\r\nimport { Navigate } from 'react-router-dom';\r\nimport { Container } from 'react-bootstrap';\r\nimport queryString from 'query-string';\r\nimport { Promisable } from '../utils/types';\r\n\r\ninterface LoginProps {\r\n onLogined: (token?: string) => string;\r\n onAuthorize?: (token?: any) => Promisable<void | string | undefined>;\r\n implicit?: boolean;\r\n}\r\n\r\nexport default function Social({ onLogined, onAuthorize, implicit = true }: LoginProps) {\r\n const { result, error } = useAsync(async () => {\r\n let token: any | undefined;\r\n\r\n if (implicit) {\r\n const parsed = queryString.parse(window.location.hash);\r\n if (parsed.access_token) {\r\n token = parsed.access_token;\r\n }\r\n } else {\r\n const parsed = queryString.parse(window.location.search);\r\n if (parsed) {\r\n token = parsed;\r\n\r\n token.redirect_uri = sessionStorage.getItem('redirect_uri');\r\n }\r\n }\r\n\r\n if (onAuthorize) {\r\n try {\r\n const newToken = await onAuthorize(token);\r\n if (newToken) {\r\n token = newToken;\r\n }\r\n } catch (e) {\r\n if (isRequestError(e)) {\r\n const data = e.response?.data;\r\n if (isRecord(data)) {\r\n throw new Error(data.message);\r\n }\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n return onLogined(token);\r\n }, []);\r\n\r\n if (error) {\r\n return <Container className={'mt-5'}>\r\n <Card>\r\n <Result status={'error'} title={error.message} />\r\n </Card>\r\n </Container>;\r\n }\r\n\r\n if (result) {\r\n return <Navigate to={result} replace />;\r\n }\r\n\r\n return <Loader />;\r\n}\r\n","import { Loader, useAsync } from '@topthink/components';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ninterface LogoutProps {\r\n onLogout: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Logout({ onLogout }: LogoutProps) {\r\n const navigate = useNavigate();\r\n\r\n useAsync(async () => {\r\n await onLogout();\r\n navigate('/login', { state: { from: 'logout' } });\r\n }, []);\r\n\r\n return <Loader />;\r\n}\r\n","import { Card } from '@topthink/components';\r\nimport { Col, Container, Row } from 'react-bootstrap';\r\nimport { ReactNode } from 'react';\r\n\r\nexport interface LoginProps {\r\n onAuthorize: (url: string, query?: Record<string, string>) => void;\r\n onLogined: (token?: string) => string;\r\n}\r\n\r\ninterface Props extends LoginProps {\r\n onLogin: (props: LoginProps) => ReactNode;\r\n}\r\n\r\nexport default function Login({ onLogin, onLogined, onAuthorize }: Props) {\r\n return <Container className='vh-100 d-flex align-items-center'>\r\n <Row className='flex-fill'>\r\n <Col lg={{ span: 6, offset: 3 }} xxl={{ span: 4, offset: 4 }}>\r\n <Card className='p-5'>\r\n {onLogin({ onAuthorize, onLogined })}\r\n </Card>\r\n </Col>\r\n </Row>\r\n </Container>;\r\n}\r\n","import { createBrowserRouter, RouteObject, RouterProvider } from 'react-router-dom';\nimport Social from '../pages/social';\nimport Logout from '../pages/logout';\nimport queryString from 'query-string';\nimport * as path from 'path';\nimport { getAbsoluteUrl, Modal, request, ToastProvider } from '@topthink/components';\nimport UserProvider from '../components/user-provider';\nimport transformRoutes from './transform-routes';\nimport Login, { LoginProps } from '../pages/login';\nimport { Promisable, User, UserResolver } from './types';\nimport { Fragment, ReactElement, ReactNode } from 'react';\n\ninterface Component<P = {}> {\n (props: P): (ReactElement | null);\n}\n\nfunction stripBasename(pathname: string, basename: string) {\n if (basename === '/') return pathname;\n\n return pathname.slice(basename.length);\n}\n\ninterface Options {\n baseURL?: string;\n basename?: string;\n authentication?: 'cookie' | 'token';\n implicit?: boolean;\n onLogout?: () => Promisable<void>;\n onAuthorize?: (token?: any) => Promisable<void | string | undefined>;\n onLogin: (props: LoginProps) => ReactNode;\n userResolver: UserResolver;\n routes: RouteObject[];\n extraRoutes?: RouteObject[];\n RootComponent?: Component;\n}\n\nexport default function createApplication(options: Options) {\n const {\n basename = '/',\n onAuthorize,\n onLogout,\n onLogin,\n authentication = 'token',\n implicit,\n baseURL,\n userResolver,\n routes,\n RootComponent = Fragment,\n extraRoutes = []\n } = options;\n\n if (baseURL) {\n request.defaults.baseURL = baseURL;\n }\n\n const updateToken = (token?: string) => {\n if (authentication === 'token' && request.defaults.authTokenName) {\n if (token) {\n localStorage.setItem(request.defaults.authTokenName, token);\n } else {\n localStorage.removeItem(request.defaults.authTokenName);\n }\n }\n };\n\n const handleResolved = (user: User) => {\n if (user.token) {\n updateToken(user.token);\n }\n };\n\n const handleAuthorize = (url: string, query?: Record<string, string>) => {\n const { from } = window.history.state.usr || {};\n\n if (from && from !== 'logout') {\n sessionStorage.setItem('restore_uri', stripBasename(from, basename));\n }\n\n const redirectUri = queryString.stringifyUrl({\n url: getAbsoluteUrl(path.join(basename, '/social')),\n query\n });\n\n if (!implicit) {\n sessionStorage.setItem('redirect_uri', redirectUri);\n }\n\n window.location.href = queryString.stringifyUrl({\n url,\n query: { redirect_uri: redirectUri }\n });\n };\n\n const handleLogined = (token?: string) => {\n updateToken(token);\n\n const redirectUri = sessionStorage.getItem('restore_uri');\n\n if (redirectUri) {\n sessionStorage.removeItem('restore_uri');\n }\n return redirectUri || '/';\n };\n\n const handleLogout = async () => {\n if (onLogout) {\n try {\n await onLogout();\n } catch (e) {\n\n }\n }\n\n updateToken();\n };\n\n const router = createBrowserRouter(\n [\n {\n path: '*',\n element: <UserProvider userResolver={userResolver} onResolved={handleResolved} />,\n children: transformRoutes(routes),\n },\n {\n path: 'social',\n element: <Social implicit={implicit} onAuthorize={onAuthorize} onLogined={handleLogined} />\n },\n {\n path: 'logout',\n element: <Logout onLogout={handleLogout} />\n },\n {\n path: 'login',\n element: <Login onLogin={onLogin} onAuthorize={handleAuthorize} onLogined={handleLogined} />\n },\n ...extraRoutes\n ],\n {\n basename\n }\n );\n\n return function() {\n return <ToastProvider>\n <RootComponent>\n <RouterProvider router={router} />\n </RootComponent>\n <Modal.Message />\n </ToastProvider>;\n };\n}\n"],"names":["_g","_extends","Object","assign","bind","target","i","arguments","length","source","key","prototype","hasOwnProperty","call","apply","this","SvgExternal","props","React","createElement","xmlns","width","height","fill","d","formatRelativePath","user","routes","parent","menus","route","meta","path","children","hideInMenu","access","passed","access_level","Array","isArray","intersection","roles","title","isExternal","href","replace","menu","icon","_jsx","className","hideChildrenInMenu","push","UserContext","createContext","UserProvider","_ref","userResolver","onResolved","state","setState","useState","navigate","useNavigate","execute","useAsync","async","e","isRequestError","response","status","redirectUri","window","location","pathname","search","from","onSuccess","Loader","value","setUser","refresh","Provider","Outlet","useUser","context","useContext","Error","useMenu","matches","UNSAFE_RouteContext","routeMatch","pathnameBase","routesMatch","useMemo","base","getMenuData","reduceRight","match","handle","undefined","transformRoutes","map","index","hideMenu","SiderContext","useSider","Toggle","sider","Trigger","onClick","setShow","styled","div","renderMenuItems","items","item","_jsxs","MenuTitle","ExternalIcon","SubMenu","MenuItem","Link","to","collapseNode","expandNode","node","scrollHeight","motion","motionName","motionAppear","onAppearStart","onAppearActive","onEnterStart","onEnterActive","onLeaveStart","onLeaveActive","SiderLayout","header","headerAs","footer","footerAs","top","isMobile","useWindowSize","defaultTitle","showToggle","setShowToggle","useLocation","useMatches","reduce","selectedKeys","keys","split","pre","curr","join","openKeys","setOpenKeys","useEffect","slice","onOpenChange","useCallback","currentKey","filter","startsWith","Routes","Title","FooterComp","Footer","sidebar","Sidebar","Header","Menu","mode","siderToggle","show","toggle","headless","Container","$top","Offcanvas","onHide","placement","style","Content","Main","memo","_ref2","useRoutes","nav","main","RcMenu","p","extra","showBack","bodyAs","fixed","defaultShowBack","$fixed","Back","Extra","Body","as","css","TabLayout","Dropdown","variant","size","Item","active","StyledNav","Nav","NavLink","classNames","Avatar","a","logo","src","navbar","avatar","Access","require","fallback","_Fragment","LinkButton","Button","preventDefault","Context","Inner","request","result","useRequest","wrap","WithRequest","params","useParams","url","all","name","useRequestData","Social","onLogined","onAuthorize","implicit","error","token","parsed","queryString","parse","hash","access_token","redirect_uri","sessionStorage","getItem","newToken","data","isRecord","message","Card","Result","Navigate","Logout","onLogout","Login","onLogin","Row","Col","lg","span","offset","xxl","createApplication","options","basename","authentication","baseURL","RootComponent","Fragment","extraRoutes","defaults","updateToken","authTokenName","localStorage","setItem","removeItem","handleLogined","router","createBrowserRouter","element","query","history","usr","stripBasename","stringifyUrl","getAbsoluteUrl","ToastProvider","RouterProvider","Modal","Message"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/images/external.svg","../src/utils/get-menu-data.tsx","../src/components/app-provider.tsx","../src/layout/use-menu.tsx","../src/utils/transform-routes.ts","../src/layout/sider/context.tsx","../src/layout/sider/toggle.tsx","../src/layout/sider/index.tsx","../src/hooks/use-route-handle.ts","../src/components/content.tsx","../src/layout/tab.tsx","../src/components/user-provider.tsx","../src/components/header.tsx","../src/images/logo.svg","../src/components/access.tsx","../src/components/link-button.tsx","../src/components/with-request.tsx","../src/pages/social.tsx","../src/pages/logout.tsx","../src/pages/login.tsx","../src/utils/create-application.tsx"],"sourcesContent":["var img = \"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3e %3cg fill='%23888'%3e %3cpath d='M8 3l1.793 1.793L6 8.586 7.414 10l3.793-3.793L13 8V3z'/%3e %3cpath d='M11 11H5V5h2V3H3v10h10V9h-2z'/%3e %3c/g%3e%3c/svg%3e\";\n export default img;","import type { RouteObject } from 'react-router-dom';\r\nimport { ReactNode } from 'react';\r\nimport { App } from './types';\r\nimport { intersection } from 'lodash';\r\n\r\nexport interface MenuData {\r\n path: string;\r\n title: string;\r\n icon?: ReactNode;\r\n isExternal?: boolean;\r\n children: MenuData[];\r\n}\r\n\r\nconst formatRelativePath = (app: App, routes: RouteObject[], parent: string = '/'): MenuData[] => {\r\n\r\n const menus: MenuData[] = [];\r\n\r\n for (const route of routes) {\r\n\r\n let { meta = {}, path = '', children = [] } = route;\r\n\r\n if (meta.hideInMenu) {\r\n continue;\r\n }\r\n\r\n if (meta.access) {\r\n let access = meta.access;\r\n let passed = false;\r\n if (typeof access === 'function') {\r\n passed = access(app);\r\n } else if (typeof access === 'number') {\r\n passed = (app.user?.access_level || 0) >= access;\r\n } else {\r\n if (!Array.isArray(access)) {\r\n access = [access];\r\n }\r\n\r\n passed = intersection((app.user?.roles || []), access).length > 0;\r\n }\r\n if (!passed) {\r\n continue;\r\n }\r\n }\r\n\r\n const title = meta.title;\r\n\r\n if (!title) {\r\n continue;\r\n }\r\n\r\n let isExternal = false;\r\n\r\n if (meta.href) {\r\n isExternal = true;\r\n path = meta.href;\r\n } else {\r\n path = `${parent}/${path}`.replace(/\\/{2,}/g, '/').replace(/\\/$/, '');\r\n }\r\n\r\n const icon = typeof meta.icon === 'string' ?\r\n <i className={`bi bi-${meta.icon}`} /> : meta.icon;\r\n\r\n const menu: MenuData = {\r\n title,\r\n icon,\r\n path,\r\n isExternal,\r\n children: []\r\n };\r\n\r\n if (!meta.hideChildrenInMenu && !isExternal && children.length > 0) {\r\n menu.children = formatRelativePath(app, children, path);\r\n }\r\n\r\n menus.push(menu);\r\n }\r\n\r\n return menus;\r\n};\r\n\r\nexport default function getMenuData(app: App, routes: RouteObject[], base: string = '/'): MenuData[] {\r\n return formatRelativePath(app, routes, base);\r\n}\r\n","import { Dispatch, ReactNode, SetStateAction, createContext, useContext, useState } from 'react';\r\nimport { App, AppResolver } from '../utils/types';\r\nimport { Loader, useAsync } from '@topthink/components';\r\n\r\ntype AppContextType = [App, Dispatch<SetStateAction<App>>];\r\n\r\nexport const AppContext = createContext<AppContextType | null>(null);\r\n\r\ninterface Props {\r\n appResolver?: AppResolver;\r\n children: ReactNode;\r\n}\r\n\r\nexport default function AppProvider({ appResolver, children }: Props) {\r\n const [app, setApp] = useState<App | null>(null);\r\n\r\n useAsync(async () => {\r\n if (appResolver) {\r\n return appResolver();\r\n }\r\n }, [], {\r\n onSuccess(app) {\r\n setApp(app || {});\r\n }\r\n });\r\n\r\n if (!app) {\r\n return <Loader />;\r\n }\r\n\r\n return <AppContext.Provider value={[app, setApp]}>\r\n {children}\r\n </AppContext.Provider>;\r\n}\r\n\r\nexport function useAppState() {\r\n const context = useContext(AppContext);\r\n if (!context) {\r\n throw new Error('useApp must be used within a AppProvider');\r\n }\r\n return context;\r\n}\r\n\r\nexport function useApp() {\r\n const [app] = useAppState();\r\n return app;\r\n}\r\n","import { useContext, useMemo } from 'react';\r\nimport { RouteObject, UNSAFE_RouteContext } from 'react-router-dom';\r\nimport getMenuData, { MenuData } from '../utils/get-menu-data';\r\nimport { useApp } from '../components/app-provider';\r\n\r\nexport default function useMenu(routes?: RouteObject[]): [MenuData[], string | undefined] {\r\n\r\n const { matches } = useContext(UNSAFE_RouteContext);\r\n const app = useApp();\r\n const routeMatch = matches[matches.length - 1];\r\n const pathnameBase = routeMatch.pathnameBase || '/';\r\n\r\n const routesMatch = routes || routeMatch.route.children || [];\r\n\r\n const menu = useMemo(() => getMenuData(app, routesMatch, pathnameBase), [app, routesMatch, pathnameBase]);\r\n\r\n const title = useMemo(() => {\r\n return matches.reduceRight((title, match) => {\r\n if (title) return title;\r\n return match.route.handle?.title;\r\n }, undefined);\r\n }, [matches]);\r\n\r\n return [menu, title];\r\n}\r\n","import { RouteObject } from 'react-router-dom';\r\n\r\nexport default function transformRoutes(routes: RouteObject[], hideInMenu?: boolean) {\r\n return routes.map((route) => {\r\n if (route.children) {\r\n route.children = transformRoutes(route.children, route.meta?.hideChildrenInMenu);\r\n }\r\n\r\n route.handle = route.handle || {};\r\n\r\n const title = route.meta?.title;\r\n if (title !== undefined) {\r\n route.handle.title = title;\r\n }\r\n\r\n hideInMenu = route.meta?.hideInMenu || (hideInMenu && !route.index);\r\n if (hideInMenu !== undefined) {\r\n route.handle.hideInMenu = hideInMenu;\r\n }\r\n\r\n const hideMenu = route.meta?.hideMenu;\r\n if (hideMenu !== undefined) {\r\n route.handle.hideMenu = hideMenu;\r\n }\r\n\r\n const access = route.meta?.access;\r\n if (access !== undefined) {\r\n route.handle.access = access;\r\n }\r\n\r\n return route;\r\n });\r\n}\r\n","import { createContext, ReactNode, useContext } from 'react';\r\n\r\nexport const SiderContext = createContext<{\r\n toggle: ReactNode,\r\n show: boolean,\r\n setShow: (show: boolean) => void,\r\n headless: boolean\r\n} | undefined>(undefined);\r\n\r\nexport const useSider = () => {\r\n return useContext(SiderContext);\r\n};\r\n","import { styled } from '@topthink/components';\r\nimport { useSider } from './context';\r\n\r\nexport default function Toggle() {\r\n const sider = useSider();\r\n return <Trigger onClick={() => sider?.setShow(true)}><i className='bi bi-list' /></Trigger>;\r\n}\r\n\r\nconst Trigger = styled.div`\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n font-size: 2rem;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n`;\r\n","import RcMenu, { MenuItem, SubMenu } from 'rc-menu';\r\nimport { Link, Outlet, RouteObject, useLocation, useRoutes } from 'react-router-dom';\r\nimport { ElementType, memo, ReactNode, useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { MenuData } from '../../utils/get-menu-data';\r\nimport type { CSSMotionProps } from 'rc-motion';\r\nimport { Offcanvas, styled, useWindowSize } from '@topthink/components';\r\nimport { ReactComponent as ExternalIcon } from '../../images/external.svg';\r\nimport useMenu from '../use-menu';\r\nimport transformRoutes from '../../utils/transform-routes';\r\nimport Toggle from './toggle';\r\nimport { SiderContext } from './context';\r\nimport useRouteHandle from '../../hooks/use-route-handle';\r\n\r\nconst renderMenuItems = (items: MenuData[]) => {\r\n return items.map((item) => {\r\n\r\n const title = <MenuTitle>\r\n {item.icon}\r\n {item.title}\r\n {item.isExternal && <ExternalIcon />}\r\n </MenuTitle>;\r\n\r\n if (item.children.length > 0) {\r\n return <SubMenu title={title} key={item.path}>\r\n {renderMenuItems(item.children)}\r\n </SubMenu>;\r\n } else {\r\n return <MenuItem key={item.path}>\r\n {item.isExternal ?\r\n <a href={item.path} target='_blank'>{title}</a> :\r\n <Link to={item.path}>{title}</Link>\r\n }\r\n </MenuItem>;\r\n }\r\n });\r\n};\r\n\r\nconst collapseNode = () => {\r\n return { height: 0 };\r\n};\r\nconst expandNode = (node: HTMLElement) => {\r\n return { height: node.scrollHeight };\r\n};\r\n\r\nconst motion: CSSMotionProps = {\r\n motionName: 'rc-menu-collapse',\r\n motionAppear: true,\r\n onAppearStart: collapseNode,\r\n onAppearActive: expandNode,\r\n onEnterStart: collapseNode,\r\n onEnterActive: expandNode,\r\n onLeaveStart: expandNode,\r\n onLeaveActive: collapseNode,\r\n};\r\n\r\ninterface Props<As extends ElementType = ElementType> {\r\n className?: string;\r\n title?: string;\r\n header?: ReactNode;\r\n headerAs?: As;\r\n footer?: ReactNode;\r\n footerAs?: As;\r\n routes?: RouteObject[];\r\n top?: number;\r\n}\r\n\r\nexport default function SiderLayout({ className, title, header, headerAs, footer, footerAs, top = 54, routes }: Props) {\r\n const { isMobile } = useWindowSize();\r\n const [menu, defaultTitle] = useMenu(routes);\r\n const [showToggle, setShowToggle] = useState(false);\r\n const { pathname, key } = useLocation();\r\n\r\n const { hideMenu = false } = useRouteHandle();\r\n\r\n const selectedKeys = useMemo(() => {\r\n const keys: string[] = [];\r\n const parts = pathname.split('/');\r\n parts.reduce<string[]>((pre, curr) => {\r\n if (pre.length > 1) {\r\n keys.push(pre.join('/'));\r\n }\r\n return [...pre, curr];\r\n }, []);\r\n keys.push(pathname);\r\n return keys;\r\n }, [pathname]);\r\n\r\n const [openKeys, setOpenKeys] = useState<string[]>([]);\r\n\r\n useEffect(() => {\r\n setShowToggle(false);\r\n }, [key]);\r\n\r\n useEffect(() => {\r\n setOpenKeys(selectedKeys.slice(0, -1));\r\n }, [selectedKeys]);\r\n\r\n const onOpenChange = useCallback((openKeys: string[]) => {\r\n const currentKey = openKeys[openKeys.length - 1];\r\n setOpenKeys(openKeys.filter(key => currentKey.startsWith(key)));\r\n }, [openKeys, setOpenKeys]);\r\n\r\n const children = routes ? <Routes routes={routes} /> : <Outlet />;\r\n\r\n if (hideMenu) {\r\n return children;\r\n }\r\n\r\n if (!header) {\r\n header = <Title>{title || defaultTitle}</Title>;\r\n }\r\n\r\n const HeaderComp = headerAs || Header;\r\n\r\n const FooterComp = footerAs || Footer;\r\n\r\n const sidebar = <Sidebar className={className}>\r\n <HeaderComp>{header}</HeaderComp>\r\n <Menu\r\n mode='inline'\r\n motion={motion}\r\n openKeys={openKeys}\r\n onOpenChange={onOpenChange}\r\n selectedKeys={selectedKeys}\r\n >\r\n {renderMenuItems(menu)}\r\n </Menu>\r\n <FooterComp>{footer}</FooterComp>\r\n </Sidebar>;\r\n\r\n const siderToggle = isMobile ? <Toggle /> : null;\r\n\r\n return <SiderContext.Provider value={{\r\n show: showToggle,\r\n setShow: setShowToggle,\r\n toggle: siderToggle,\r\n headless: top == 0\r\n }}>\r\n <Container $top={top}>\r\n {isMobile ? <Offcanvas\r\n show={showToggle}\r\n onHide={() => {\r\n setShowToggle(false);\r\n }}\r\n placement={'start'}\r\n style={{\r\n width: '230px',\r\n }}\r\n >\r\n {sidebar}\r\n </Offcanvas> : sidebar}\r\n <Content>\r\n <Main>\r\n {children}\r\n </Main>\r\n </Content>\r\n </Container>\r\n </SiderContext.Provider>;\r\n}\r\n\r\nconst Routes = memo(function({ routes }: { routes: RouteObject[] }) {\r\n return useRoutes(useMemo(() => transformRoutes(routes), [routes]));\r\n});\r\n\r\nconst Sidebar = styled.nav`\r\n position: fixed;\r\n top: 0;\r\n bottom: 0;\r\n left: 0;\r\n z-index: 100;\r\n padding: var(--bs-header-height) 0 0;\r\n border-right: 1px solid #e3e3e3;\r\n width: 230px;\r\n background-color: #f5f5f5;\r\n display: flex;\r\n flex-direction: column;\r\n`;\r\n\r\nconst Title = styled.div`\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n font-size: 16px;\r\n`;\r\n\r\nconst Header = styled.div`\r\n height: 64px;\r\n display: flex;\r\n align-items: center;\r\n padding: 10px 8px 10px 24px;\r\n border-bottom: 1px solid #e3e3e3;\r\n flex-grow: 0;\r\n flex-shrink: 0;\r\n`;\r\n\r\nconst Footer = styled.div`\r\n flex-grow: 0;\r\n flex-shrink: 0;\r\n`;\r\nconst Content = styled.div`\r\n flex: 1;\r\n @media (min-width: 992px) {\r\n margin-left: 230px;\r\n }\r\n`;\r\n\r\nconst Main = styled.main`\r\n min-height: calc(var(--100vh, 100vh) - var(--bs-header-height));\r\n position: relative;\r\n`;\r\n\r\nconst MenuTitle = styled.div`\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n\r\n .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n min-width: 19px;\r\n text-align: center;\r\n }\r\n`;\r\n\r\nconst Menu = styled(RcMenu)`\r\n border: none;\r\n box-shadow: none;\r\n padding: 10px 0;\r\n flex: 1;\r\n overflow: auto;\r\n\r\n .rc-menu-item {\r\n display: flex;\r\n\r\n &:hover {\r\n background-color: #f0f0f0;\r\n }\r\n\r\n a {\r\n flex: 1;\r\n text-decoration: none;\r\n color: dimgray;\r\n }\r\n }\r\n\r\n .rc-menu-sub {\r\n background-color: #eee;\r\n border-top: 1px solid #eee;\r\n border-bottom: 1px solid #eee;\r\n\r\n & > li {\r\n &:first-child {\r\n margin-top: 4px;\r\n }\r\n\r\n &:last-child {\r\n margin-bottom: 4px;\r\n }\r\n }\r\n\r\n .rc-menu-item-selected {\r\n background-color: #eee;\r\n color: var(--bs-primary);\r\n\r\n & > a {\r\n color: var(--bs-primary);\r\n }\r\n }\r\n\r\n .rc-menu-item {\r\n &:hover {\r\n background-color: #e7e7e7;\r\n }\r\n }\r\n }\r\n\r\n .rc-menu-submenu {\r\n & > .rc-menu-submenu-title {\r\n &:hover {\r\n background-color: #e7e7e7;\r\n }\r\n }\r\n }\r\n\r\n .rc-menu-item-active,\r\n .rc-menu-submenu-active > .rc-menu-submenu-title {\r\n background-color: #eee;\r\n }\r\n\r\n .rc-menu-item,\r\n .rc-menu-submenu > .rc-menu-submenu-title {\r\n padding: 0 8px 0 24px;\r\n font-size: 14px;\r\n line-height: 36px;\r\n cursor: pointer;\r\n }\r\n\r\n .rc-menu-sub > .rc-menu-item,\r\n .rc-menu-sub > .rc-menu-submenu > .rc-menu-submenu-title {\r\n padding-top: 0;\r\n padding-bottom: 0;\r\n padding-right: 0;\r\n }\r\n\r\n .rc-menu-submenu-arrow {\r\n line-height: 20px;\r\n }\r\n\r\n .rc-menu-item-selected {\r\n background-color: #f5f5f5;\r\n color: var(--bs-primary);\r\n\r\n & > a {\r\n color: var(--bs-primary);\r\n }\r\n }\r\n\r\n .rc-menu-submenu-selected {\r\n background-color: #eee;\r\n\r\n & > .rc-menu-submenu-title {\r\n color: var(--bs-primary);\r\n font-weight: 500;\r\n }\r\n }\r\n\r\n & > .rc-menu-item {\r\n line-height: 38px;\r\n }\r\n\r\n & > .rc-menu-submenu {\r\n &.rc-menu-submenu-selected {\r\n background-color: #f5f5f5;\r\n }\r\n\r\n & > .rc-menu-submenu-title {\r\n line-height: 38px;\r\n\r\n &:hover {\r\n background-color: #f0f0f0;\r\n }\r\n }\r\n\r\n &.rc-menu-submenu-active > .rc-menu-submenu-title {\r\n background-color: #f5f5f5;\r\n }\r\n\r\n & > .rc-menu-sub {\r\n border-top: 1px solid #e6e6e6;\r\n border-bottom: 1px solid #e6e6e6;\r\n\r\n & > li {\r\n &:first-child {\r\n margin-top: 9px;\r\n }\r\n\r\n &:last-child {\r\n margin-bottom: 9px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n`;\r\n\r\nconst Container = styled.div<{ $top: number }>`\r\n --bs-header-height: ${(p) => p.$top}px;\r\n display: flex;\r\n flex-wrap: nowrap;\r\n width: 100%;\r\n\r\n &:has(&) {\r\n > ${Sidebar} {\r\n display: none;\r\n }\r\n\r\n > ${Content} {\r\n margin-left: 0;\r\n }\r\n }\r\n`;\r\n","import { useMatches } from 'react-router-dom';\r\n\r\nexport default function useRouteHandle() {\r\n const matches = useMatches();\r\n\r\n return matches.reduce<Record<string, any>>((route, match) => {\r\n return { ...route, ...match.handle };\r\n }, {});\r\n}\r\n","import { css, styled } from '@topthink/components';\r\nimport { ElementType, PropsWithChildren, ReactNode, useContext, useMemo } from 'react';\r\nimport { RouteObject, UNSAFE_RouteContext, useLocation, useNavigate, } from 'react-router-dom';\r\nimport { useSider } from '../layout/sider/context';\r\n\r\ninterface ContentProps<As extends ElementType = ElementType> {\r\n title?: ReactNode;\r\n header?: ReactNode;\r\n nav?: ReactNode;\r\n extra?: ReactNode;\r\n showBack?: boolean | string;\r\n fixed?: boolean;\r\n className?: string;\r\n bodyAs?: As;\r\n}\r\n\r\nexport default function Content({\r\n title,\r\n header,\r\n nav,\r\n children,\r\n extra,\r\n showBack,\r\n className,\r\n bodyAs,\r\n fixed = true\r\n}: PropsWithChildren<ContentProps>) {\r\n const { matches } = useContext(UNSAFE_RouteContext);\r\n const route = useMemo(() => {\r\n return matches.reduceRight<RouteObject | undefined>((route, match) => {\r\n if (route || match.route.index) return route;\r\n return match.route;\r\n }, undefined);\r\n }, [matches]);\r\n\r\n const sider = useSider();\r\n\r\n const defaultShowBack = route?.handle?.hideInMenu === true;\r\n const defaultTitle = route?.handle?.title;\r\n\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n\r\n if (showBack === undefined) {\r\n showBack = defaultShowBack;\r\n }\r\n\r\n if (header === undefined) {\r\n header = <Title className={'fs-4 text-truncate'}>{title || defaultTitle}</Title>;\r\n }\r\n\r\n return <Container className={className}>\r\n <Header $fixed={fixed}>\r\n <div className='container'>\r\n {sider?.headless && sider.toggle}\r\n {showBack && (location.key !== 'default' || typeof showBack === 'string') &&\r\n <Back onClick={() => typeof showBack === 'string' ? navigate(showBack) : navigate(-1)}><i className='bi bi-arrow-left-short' /></Back>}\r\n {header}\r\n {nav}\r\n <Extra>{extra}</Extra>\r\n </div>\r\n </Header>\r\n <Body className='container' as={bodyAs}>\r\n {children}\r\n </Body>\r\n </Container>;\r\n};\r\n\r\nconst Back = styled.div`\r\n font-size: 32px;\r\n cursor: pointer;\r\n`;\r\n\r\nconst Container = styled.div`\r\n width: 100%;\r\n container-type: inline-size;\r\n\r\n .container {\r\n @media (min-width: 992px) and (max-width: 1540px) {\r\n max-width: calc(100vw - 236px - 6px);\r\n }\r\n @media (max-width: 991px) {\r\n max-width: calc(100vw - 6px);\r\n }\r\n @container (max-width: 1310px) {\r\n max-width: 100cqw;\r\n }\r\n }\r\n`;\r\n\r\nconst Header = styled.div<{ $fixed?: boolean }>`\r\n background-color: #fff;\r\n display: flex;\r\n border-bottom: 1px solid rgb(227, 227, 227);\r\n align-items: center;\r\n height: 65px;\r\n\r\n ${props => props.$fixed && css`\r\n position: sticky;\r\n top: 0;\r\n z-index: 1000;\r\n `};\r\n\r\n .container {\r\n padding: 0 12px;\r\n display: flex;\r\n align-items: center;\r\n gap: .5rem;\r\n }\r\n`;\r\n\r\nconst Body = styled.div`\r\n margin-top: 24px;\r\n margin-bottom: 24px;\r\n\r\n @media (max-width: 1540px) {\r\n margin-top: 1rem;\r\n margin-bottom: 1rem;\r\n }\r\n`;\r\n\r\nconst Title = styled.div`\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n min-width: 50px;\r\n flex-shrink: 0;\r\n`;\r\n\r\nconst Extra = styled.div`\r\n margin-left: auto;\r\n`;\r\n","import { Dropdown, Nav } from 'react-bootstrap';\r\nimport Content from '../components/content';\r\nimport { Link, Outlet, useLocation } from 'react-router-dom';\r\nimport useMenu from './use-menu';\r\nimport { styled, useWindowSize } from '@topthink/components';\r\nimport classNames from 'classnames';\r\nimport { ReactNode } from 'react';\r\n\r\ninterface Props {\r\n title?: ReactNode;\r\n header?: ReactNode;\r\n showBack?: boolean;\r\n extra?: ReactNode;\r\n}\r\n\r\nexport default function TabLayout({ title, header, showBack, extra }: Props) {\r\n\r\n const [menu, defaultTitle] = useMenu();\r\n const { pathname } = useLocation();\r\n const { isMobile } = useWindowSize();\r\n\r\n const nav = isMobile ? <Dropdown className='ms-2 d-flex align-items-center'>\r\n <Dropdown.Toggle variant='light' size={'sm'} />\r\n <Dropdown.Menu>\r\n {menu.map((item) => {\r\n return <Dropdown.Item active={pathname.startsWith(item.path)} as={Link} to={item.path} replace key={item.path}>\r\n {item.icon}\r\n {item.title}\r\n </Dropdown.Item>;\r\n })}\r\n </Dropdown.Menu>\r\n </Dropdown> : <StyledNav>\r\n {menu.map((item) => {\r\n return <Nav.Item key={item.path}>\r\n <NavLink className={classNames('nav-link', { active: pathname.startsWith(item.path) })} to={item.path} replace>\r\n {item.icon}\r\n {item.title}\r\n </NavLink>\r\n </Nav.Item>;\r\n })}\r\n </StyledNav>;\r\n\r\n return <Content title={title || defaultTitle} header={header} nav={nav} showBack={showBack} extra={extra}>\r\n <Outlet />\r\n </Content>;\r\n}\r\n\r\n\r\nconst StyledNav = styled(Nav)`\r\n flex-wrap: nowrap;\r\n margin-left: 1.25rem;\r\n`;\r\n\r\nconst NavLink = styled(Link)`\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n white-space: nowrap;\r\n position: relative;\r\n\r\n .bi, svg {\r\n text-align: center;\r\n }\r\n\r\n &.active {\r\n &:after {\r\n content: '';\r\n height: 2px;\r\n background: var(--bs-primary);\r\n display: block;\r\n position: absolute;\r\n left: 1rem;\r\n right: 1rem;\r\n bottom: -2px;\r\n }\r\n }\r\n`;\r\n","import React, { Dispatch, SetStateAction, useContext, useEffect, useState } from 'react';\r\nimport { User, UserResolver } from '../utils/types';\r\nimport { isRequestError, Loader, useAsync } from '@topthink/components';\r\nimport { Outlet, useNavigate } from 'react-router-dom';\r\nimport { useAppState } from './app-provider';\r\n\r\ntype UserContextType = [User, Dispatch<SetStateAction<User>>, () => void] & {\r\n user: User,\r\n setUser: Dispatch<SetStateAction<User>>,\r\n refresh: () => void\r\n};\r\n\r\nexport const UserContext = React.createContext<UserContextType | null>(null);\r\n\r\ninterface Props {\r\n userResolver: UserResolver;\r\n onResolved: (user: User) => void;\r\n}\r\n\r\nconst UserProvider = function({ userResolver, onResolved }: Props) {\r\n const [, setApp] = useAppState();\r\n const [state, setState] = useState<User | null>(null);\r\n\r\n useEffect(() => {\r\n setApp(current => ({ ...current, user: state }));\r\n }, [state]);\r\n\r\n const navigate = useNavigate();\r\n\r\n const { execute } = useAsync(async () => {\r\n if (userResolver) {\r\n const user = await userResolver();\r\n onResolved(user);\r\n return user;\r\n }\r\n }, [], {\r\n async onError(e) {\r\n if (isRequestError(e) && e.response?.status === 401) {\r\n const redirectUri = window.location.pathname + window.location.search;\r\n navigate(`/login`, { state: { from: redirectUri } });\r\n }\r\n },\r\n onSuccess(user) {\r\n if (user) {\r\n setState(user);\r\n }\r\n }\r\n });\r\n\r\n if (!state) {\r\n return <Loader />;\r\n }\r\n\r\n const value: any = [state, setState, execute];\r\n\r\n value.user = state;\r\n value.setUser = setState;\r\n value.refresh = execute;\r\n\r\n return <UserContext.Provider value={value}>\r\n <Outlet />\r\n </UserContext.Provider>;\r\n};\r\n\r\nexport function useUser() {\r\n const context = useContext(UserContext);\r\n if (!context) {\r\n throw new Error('please use `useUser` in UserContext');\r\n }\r\n\r\n return context;\r\n}\r\n\r\nexport default UserProvider;\r\n","import logoSrc from '../images/logo.svg';\r\nimport { Dropdown } from 'react-bootstrap';\r\nimport { PropsWithChildren, ReactNode } from 'react';\r\nimport { useUser } from './user-provider';\r\nimport classNames from 'classnames';\r\nimport { styled } from '@topthink/components';\r\n\r\nconst Avatar = styled.a`\r\n cursor: pointer;\r\n`;\r\n\r\ninterface Props {\r\n menus: ReactNode;\r\n className?: string;\r\n logo?: boolean;\r\n}\r\n\r\nexport default function Header({ children, menus, className, logo = true }: PropsWithChildren<Props>) {\r\n const [user] = useUser();\r\n\r\n return <Container\r\n className={classNames('navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top', className)}>\r\n <div className='container-fluid'>\r\n {logo && <a className='navbar-brand' href='https://www.topthink.com'>\r\n <img src={logoSrc} height='30' />\r\n </a>}\r\n {children}\r\n <Dropdown navbar>\r\n <Dropdown.Toggle as={Avatar} className='nav-link'>\r\n <img className='rounded-circle' width='25' height='25' src={user.avatar} />\r\n </Dropdown.Toggle>\r\n <Dropdown.Menu className={'shadow'}>\r\n {menus}\r\n </Dropdown.Menu>\r\n </Dropdown>\r\n </div>\r\n </Container>;\r\n}\r\n\r\nconst Container = styled.header`\r\n height: 54px;\r\n`;\r\n","var img = \"data:image/svg+xml,%3csvg width='485' height='132' xmlns='http://www.w3.org/2000/svg' xml:space='preserve' style='enable-background:new 0 0 531.69 198.43%3b' version='1.1'%3e %3cstyle type='text/css'%3e.st0%7bfill:%233C60FF%3b%7d%3c/style%3e %3cg%3e %3ctitle%3ebackground%3c/title%3e %3crect fill='none' id='canvas_background' height='134' width='487' y='-1' x='-1'/%3e %3c/g%3e %3cg%3e %3ctitle%3eLayer 1%3c/title%3e %3cpath id='svg_1' d='m132.29%2c62.34c-1.19%2c-18.77 -10.34%2c-35.36 -24.11%2c-46.46c-11.15%2c-8.99 -25.34%2c-14.38 -40.79%2c-14.38c-0.55%2c0 -1.09%2c0.01 -1.63%2c0.02c-3.32%2c0.08 -6.57%2c0.41 -9.75%2c0.98c-30.49%2c5.38 -53.65%2c32 -53.65%2c64.04c0%2c1.87 0.08%2c3.73 0.24%2c5.57c2.5%2c29.51 24.7%2c53.4 53.41%2c58.47c2.38%2c0.42 4.8%2c0.72 7.26%2c0.86c0.83%2c0.05 1.66%2c0.09 2.5%2c0.11c0.54%2c0.01 1.08%2c0.02 1.63%2c0.02c34.04%2c0 61.97%2c-26.16 64.79%2c-59.46c0.16%2c-1.83 0.24%2c-3.69 0.24%2c-5.57c0%2c-1.42 -0.05%2c-2.82 -0.14%2c-4.2zm-76.27%2c32.5c-0.26%2c0.01 -0.53%2c0.01 -0.79%2c0.01c-14.56%2c0 -26.88%2c-9.57 -31.03%2c-22.76c-0.97%2c-3.08 -1.49%2c-6.35 -1.49%2c-9.75c0%2c-17.95 14.56%2c-32.52 32.51%2c-32.52c0.26%2c0 0.53%2c0 0.79%2c0.01c3.41%2c0.08 6.69%2c0.68 9.75%2c1.74c6.5%2c2.22 12.06%2c6.45 15.97%2c11.94c1.98%2c2.78 3.54%2c5.9 4.57%2c9.25c0.94%2c3.03 1.44%2c6.24 1.44%2c9.58l-9.75%2c0c0%2c-2.18 -0.31%2c-4.29 -0.88%2c-6.28c-0.92%2c-3.23 -2.55%2c-6.17 -4.69%2c-8.64c-1.86%2c-2.14 -4.12%2c-3.93 -6.65%2c-5.25c-2.93%2c-1.54 -6.24%2c-2.46 -9.75%2c-2.58c-0.26%2c-0.01 -0.52%2c-0.01 -0.79%2c-0.01c-12.57%2c0 -22.76%2c10.19 -22.76%2c22.76c0%2c3.49 0.79%2c6.8 2.19%2c9.75c3.65%2c7.69 11.49%2c13.01 20.57%2c13.01c0.27%2c0 0.53%2c-0.01 0.79%2c-0.01l0%2c9.75zm55.7%2c-17.92c-3.35%2c10.5 -13.18%2c18.09 -24.78%2c18.09c-3.13%2c0 -6.13%2c-0.55 -8.91%2c-1.57c-2.18%2c-0.8 -4.24%2c-1.88 -6.11%2c-3.21c-2.38%2c-1.68 -4.47%2c-3.76 -6.16%2c-6.13c-0.28%2c-0.39 -0.55%2c-0.79 -0.81%2c-1.2c-2.03%2c-3.2 -3.38%2c-6.87 -3.85%2c-10.82l9.87%2c0c0.33%2c1.71 0.92%2c3.32 1.74%2c4.8c1.61%2c2.91 4.09%2c5.26 7.09%2c6.72c0.57%2c0.28 1.15%2c0.53 1.76%2c0.73c1.68%2c0.6 3.49%2c0.92 5.37%2c0.92c7.92%2c0 14.52%2c-5.67 15.96%2c-13.17c0.2%2c-1 0.3%2c-2.04 0.3%2c-3.09c0%2c-2.37 -0.51%2c-4.63 -1.43%2c-6.67c-1.66%2c-3.71 -4.68%2c-6.68 -8.43%2c-8.28l3.54%2c-9.1c7.43%2c3.08 13.13%2c9.49 15.21%2c17.38c0.44%2c1.64 0.72%2c3.34 0.81%2c5.09c0.04%2c0.52 0.05%2c1.05 0.05%2c1.58c0%2c1.05 -0.07%2c2.07 -0.18%2c3.09c-0.18%2c1.68 -0.54%2c3.3 -1.04%2c4.84z' class='st0'/%3e %3cg id='svg_2'%3e %3cg id='svg_3'%3e %3crect id='svg_4' height='6.34' width='94.12' class='st0' y='20.46' x='163.29'/%3e %3c/g%3e %3cg id='svg_5'%3e %3cpath id='svg_6' d='m169.31%2c113.72l0%2c-6.34c6.49%2c0 11.77%2c-5.28 11.77%2c-11.77l0%2c-71.98l6.34%2c0l0%2c71.98c0%2c9.98 -8.12%2c18.11 -18.11%2c18.11z' class='st0'/%3e %3c/g%3e %3cg id='svg_7'%3e %3cpath id='svg_8' d='m255.49%2c91.27l-6.34%2c0l0%2c-38.2c0%2c-5.06 -4.12%2c-9.18 -9.18%2c-9.18l-19.37%2c0c-5.06%2c0 -9.18%2c4.12 -9.18%2c9.18l0%2c38.2l-6.34%2c0l0%2c-38.2c0%2c-8.55 6.96%2c-15.51 15.51%2c-15.51l19.38%2c0c8.55%2c0 15.51%2c6.96 15.51%2c15.51l0%2c38.2l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_9'%3e %3crect id='svg_10' height='17.09' width='6.34' class='st0' y='23.63' x='227.12'/%3e %3c/g%3e %3cg id='svg_11'%3e %3cpath id='svg_12' d='m206.43%2c113.84l-3.34%2c0l0%2c-6.34l3.34%2c0c6.3%2c0 12.9%2c-3.56 15.35%2c-8.29c3.49%2c-6.71 5.33%2c-14.25 5.33%2c-21.81l0%2c-26.13l6.34%2c0l0%2c26.13c0%2c8.58 -2.09%2c17.13 -6.05%2c24.74c-3.98%2c7.68 -13.57%2c11.7 -20.97%2c11.7z' class='st0'/%3e %3c/g%3e %3cg id='svg_13'%3e %3cpath id='svg_14' d='m257.48%2c113.84l-3.34%2c0c-7.4%2c0 -16.98%2c-4.02 -20.98%2c-11.7c-3.96%2c-7.61 -6.05%2c-16.16 -6.05%2c-24.74l6.34%2c0c0%2c7.56 1.84%2c15.1 5.33%2c21.81c2.46%2c4.73 9.06%2c8.29 15.35%2c8.29l3.34%2c0l0%2c6.34l0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_15'%3e %3crect id='svg_16' height='6.34' width='42.87' class='st0' y='27.89' x='274.07'/%3e %3c/g%3e %3cg id='svg_17'%3e %3crect id='svg_18' height='61.38' width='6.34' class='st0' y='14.89' x='293.05'/%3e %3c/g%3e %3cg id='svg_19'%3e %3crect id='svg_20' height='6.34' width='33.26' class='st0' transform='matrix(0.11%2c-0.9939%2c0.9939%2c0.11%2c194.7608%2c392.0006) ' y='46.985071' x='325.728637'/%3e %3c/g%3e %3cg id='svg_21'%3e %3crect id='svg_22' height='33.26' width='6.34' class='st0' transform='matrix(0.9939%2c-0.11%2c0.11%2c0.9939%2c-7.5075%2c38.3801) ' y='37.060893' x='310.495485'/%3e %3c/g%3e %3cg id='svg_23'%3e %3cpath id='svg_24' d='m352.9%2c77.14l-15.15%2c0c-7.52%2c0 -13.64%2c-6.12 -13.64%2c-13.63l0%2c-29.61c0%2c-7.52 6.12%2c-13.64 13.64%2c-13.64l15.15%2c0c7.52%2c0 13.64%2c6.12 13.64%2c13.64l0%2c29.61c0%2c7.52 -6.12%2c13.63 -13.64%2c13.63zm-15.15%2c-50.54c-4.02%2c0 -7.3%2c3.27 -7.3%2c7.3l0%2c29.61c0%2c4.02 3.27%2c7.3 7.3%2c7.3l15.15%2c0c4.02%2c0 7.3%2c-3.27 7.3%2c-7.3l0%2c-29.61c0%2c-4.02 -3.27%2c-7.3 -7.3%2c-7.3l-15.15%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_25'%3e %3cg id='svg_26'%3e %3crect id='svg_27' height='6.34' width='17.8' class='st0' y='37.2' x='336.43'/%3e %3c/g%3e %3cg id='svg_28'%3e %3crect id='svg_29' height='6.34' width='17.8' class='st0' y='53.87' x='336.43'/%3e %3c/g%3e %3c/g%3e %3cg id='svg_30'%3e %3cpath id='svg_31' d='m352.7%2c113.84l-37.98%2c0c-8%2c0 -14.5%2c-6.51 -14.5%2c-14.5l0%2c-16.14l6.34%2c0l0%2c16.13c0%2c4.5 3.66%2c8.17 8.17%2c8.17l37.98%2c0l0%2c6.34l-0.01%2c0z' class='st0'/%3e %3c/g%3e %3cg id='svg_32'%3e %3crect id='svg_33' height='6.34' width='23.57' class='st0' transform='matrix(0.2529%2c-0.9675%2c0.9675%2c0.2529%2c114.4986%2c402.9877) ' y='83.698593' x='326.836101'/%3e %3c/g%3e %3cg id='svg_34'%3e %3crect id='svg_35' height='6.34' width='20.52' class='st0' y='86.2' x='321.58'/%3e %3c/g%3e %3cg id='svg_36'%3e %3crect id='svg_37' height='24.75' width='6.34' class='st0' transform='matrix(0.9556%2c-0.2946%2c0.2946%2c0.9556%2c-19.7967%2c122.424) ' y='75.874073' x='369.686666'/%3e %3c/g%3e %3cg id='svg_38'%3e %3crect id='svg_39' height='6.34' width='71.83' class='st0' y='20.46' x='395.51'/%3e %3c/g%3e %3cg id='svg_40'%3e %3crect id='svg_41' height='6.34' width='90.81' class='st0' y='57.44' x='386.02'/%3e %3c/g%3e %3cg id='svg_42'%3e %3cpath id='svg_43' d='m463.12%2c113.64l-56%2c0c-4.5%2c0 -8.59%2c-2.29 -10.94%2c-6.14c-2.35%2c-3.84 -2.52%2c-8.53 -0.46%2c-12.53l17.68%2c-35.81l5.64%2c2.89l-17.68%2c35.81c-1.04%2c2.02 -0.95%2c4.39 0.23%2c6.33c1.19%2c1.94 3.25%2c3.1 5.53%2c3.1l56%2c0c1.51%2c0 2.88%2c-0.71 3.74%2c-1.95c0.81%2c-1.16 1.03%2c-2.57 0.63%2c-3.91l-7.8%2c-12.34l5.36%2c-3.39l8.18%2c12.94l0.12%2c0.31c1.24%2c3.34 0.76%2c7.08 -1.28%2c10.01c-2.04%2c2.94 -5.39%2c4.68 -8.95%2c4.68z' class='st0'/%3e %3c/g%3e %3c/g%3e %3c/g%3e%3c/svg%3e\";\n export default img;","import { ReactNode } from 'react';\r\nimport { intersection } from 'lodash';\r\nimport { useUser } from './user-provider';\r\nimport { User } from '../utils/types';\r\n\r\nexport interface AccessProps {\r\n require?: string | string[] | ((user: User) => boolean);\r\n fallback?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport default function Access({\r\n require,\r\n children,\r\n fallback\r\n}: AccessProps) {\r\n const [user,] = useUser();\r\n let passed = false;\r\n if (typeof require === 'function') {\r\n passed = require(user);\r\n } else {\r\n if (typeof require === 'string') {\r\n require = [require];\r\n }\r\n passed = intersection(user.roles, require).length > 0;\r\n }\r\n if (!passed) {\r\n children = fallback;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","import { LinkProps, useNavigate } from 'react-router-dom';\r\nimport { Button, ButtonProps } from '@topthink/components';\r\n\r\ninterface Props extends ButtonProps, Pick<LinkProps, 'to' | 'replace'> {\r\n\r\n}\r\n\r\nexport default function LinkButton({ to, replace, ...props }: Props) {\r\n let navigate = useNavigate();\r\n\r\n return <Button {...props} onClick={(e) => {\r\n e.preventDefault();\r\n navigate(to, { replace });\r\n }} />;\r\n}\r\n","import { Loader, RequestConfig, useRequest } from '@topthink/components';\r\nimport { createContext, ReactNode, useContext } from 'react';\r\nimport { useParams } from 'react-router-dom';\r\n\r\nconst Context = createContext<any>(undefined);\r\n\r\ninterface Props {\r\n request: RequestConfig;\r\n children: ReactNode;\r\n}\r\n\r\nconst Inner = function({ request, children }: Props) {\r\n const { result } = useRequest(request);\r\n\r\n if (!result) {\r\n return <Loader wrap />;\r\n }\r\n\r\n return <Context.Provider value={result}>\r\n {children}\r\n </Context.Provider>;\r\n};\r\n\r\nexport default function WithRequest({ request, children }: Props) {\r\n const params = useParams();\r\n\r\n if (typeof request === 'string') {\r\n request = {\r\n url: request.replace(/:(\\w+)/g, (all, name) => {\r\n return params[name] || all;\r\n })\r\n };\r\n } else if (request.url) {\r\n request.url = request.url.replace(/:(\\w+)/g, (all, name) => {\r\n return params[name] || all;\r\n });\r\n }\r\n\r\n return <Inner key={request.url} request={request}>{children}</Inner>;\r\n}\r\n\r\nexport function useRequestData<T = any>(): T {\r\n return useContext(Context);\r\n}\r\n","import { Card, isRecord, isRequestError, Loader, Result, useAsync } from '@topthink/components';\r\nimport { Navigate } from 'react-router-dom';\r\nimport { Container } from 'react-bootstrap';\r\nimport queryString from 'query-string';\r\nimport { Promisable } from '../utils/types';\r\n\r\ninterface LoginProps {\r\n onLogined: (token?: string) => string;\r\n onAuthorize?: (token?: any) => Promisable<void | string | undefined>;\r\n implicit?: boolean;\r\n}\r\n\r\nexport default function Social({ onLogined, onAuthorize, implicit = true }: LoginProps) {\r\n const { result, error } = useAsync(async () => {\r\n let token: any | undefined;\r\n\r\n if (implicit) {\r\n const parsed = queryString.parse(window.location.hash);\r\n if (parsed.access_token) {\r\n token = parsed.access_token;\r\n }\r\n } else {\r\n const parsed = queryString.parse(window.location.search);\r\n if (parsed) {\r\n token = parsed;\r\n\r\n token.redirect_uri = sessionStorage.getItem('redirect_uri');\r\n }\r\n }\r\n\r\n if (onAuthorize) {\r\n try {\r\n const newToken = await onAuthorize(token);\r\n if (newToken) {\r\n token = newToken;\r\n }\r\n } catch (e) {\r\n if (isRequestError(e)) {\r\n const data = e.response?.data;\r\n if (isRecord(data)) {\r\n throw new Error(data.message);\r\n }\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n return onLogined(token);\r\n }, []);\r\n\r\n if (error) {\r\n return <Container className={'mt-5'}>\r\n <Card>\r\n <Result status={'error'} title={error.message} />\r\n </Card>\r\n </Container>;\r\n }\r\n\r\n if (result) {\r\n return <Navigate to={result} replace />;\r\n }\r\n\r\n return <Loader />;\r\n}\r\n","import { Loader, useAsync } from '@topthink/components';\r\nimport { useNavigate } from 'react-router-dom';\r\n\r\ninterface LogoutProps {\r\n onLogout: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Logout({ onLogout }: LogoutProps) {\r\n const navigate = useNavigate();\r\n\r\n useAsync(async () => {\r\n await onLogout();\r\n navigate('/login', { state: { from: 'logout' } });\r\n }, []);\r\n\r\n return <Loader />;\r\n}\r\n","import { Card } from '@topthink/components';\r\nimport { Col, Container, Row } from 'react-bootstrap';\r\nimport { ReactNode } from 'react';\r\n\r\nexport interface LoginProps {\r\n onAuthorize: (url: string, query?: Record<string, string>) => void;\r\n onLogined: (token?: string) => string;\r\n}\r\n\r\ninterface Props extends LoginProps {\r\n onLogin: (props: LoginProps) => ReactNode;\r\n}\r\n\r\nexport default function Login({ onLogin, onLogined, onAuthorize }: Props) {\r\n return <Container className='vh-100 d-flex align-items-center'>\r\n <Row className='flex-fill'>\r\n <Col lg={{ span: 6, offset: 3 }} xxl={{ span: 4, offset: 4 }}>\r\n <Card className='p-5'>\r\n {onLogin({ onAuthorize, onLogined })}\r\n </Card>\r\n </Col>\r\n </Row>\r\n </Container>;\r\n}\r\n","import { createBrowserRouter, RouteObject, RouterProvider } from 'react-router-dom';\nimport Social from '../pages/social';\nimport Logout from '../pages/logout';\nimport queryString from 'query-string';\nimport * as path from 'path';\nimport { getAbsoluteUrl, Modal, request, ToastProvider } from '@topthink/components';\nimport AppProvider from '../components/app-provider';\nimport UserProvider from '../components/user-provider';\nimport transformRoutes from './transform-routes';\nimport Login, { LoginProps } from '../pages/login';\nimport { AppResolver, Promisable, User, UserResolver } from './types';\nimport { Fragment, ReactElement, ReactNode } from 'react';\n\n\ninterface Component<P = {}> {\n (props: P): (ReactElement | null);\n}\n\nfunction stripBasename(pathname: string, basename: string) {\n if (basename === '/') return pathname;\n\n return pathname.slice(basename.length);\n}\n\ninterface Options {\n baseURL?: string;\n basename?: string;\n authentication?: 'cookie' | 'token';\n implicit?: boolean;\n onLogout?: () => Promisable<void>;\n onAuthorize?: (token?: any) => Promisable<void | string | undefined>;\n onLogin: (props: LoginProps) => ReactNode;\n appResolver?: AppResolver;\n userResolver: UserResolver;\n routes: RouteObject[];\n extraRoutes?: RouteObject[];\n RootComponent?: Component;\n}\n\nexport default function createApplication(options: Options) {\n const {\n basename = '/',\n onAuthorize,\n onLogout,\n onLogin,\n authentication = 'token',\n implicit,\n baseURL,\n appResolver,\n userResolver,\n routes,\n RootComponent = Fragment,\n extraRoutes = []\n } = options;\n\n if (baseURL) {\n request.defaults.baseURL = baseURL;\n }\n\n const updateToken = (token?: string) => {\n if (authentication === 'token' && request.defaults.authTokenName) {\n if (token) {\n localStorage.setItem(request.defaults.authTokenName, token);\n } else {\n localStorage.removeItem(request.defaults.authTokenName);\n }\n }\n };\n\n const handleResolved = (user: User) => {\n if (user.token) {\n updateToken(user.token);\n }\n };\n\n const handleAuthorize = (url: string, query?: Record<string, string>) => {\n const { from } = window.history.state.usr || {};\n\n if (from && from !== 'logout') {\n sessionStorage.setItem('restore_uri', stripBasename(from, basename));\n }\n\n const redirectUri = queryString.stringifyUrl({\n url: getAbsoluteUrl(path.join(basename, '/social')),\n query\n });\n\n if (!implicit) {\n sessionStorage.setItem('redirect_uri', redirectUri);\n }\n\n window.location.href = queryString.stringifyUrl({\n url,\n query: { redirect_uri: redirectUri }\n });\n };\n\n const handleLogined = (token?: string) => {\n updateToken(token);\n\n const redirectUri = sessionStorage.getItem('restore_uri');\n\n if (redirectUri) {\n sessionStorage.removeItem('restore_uri');\n }\n return redirectUri || '/';\n };\n\n const handleLogout = async () => {\n if (onLogout) {\n try {\n await onLogout();\n } catch (e) {\n\n }\n }\n\n updateToken();\n };\n\n const router = createBrowserRouter(\n [\n {\n path: '*',\n element: <UserProvider userResolver={userResolver} onResolved={handleResolved} />,\n children: transformRoutes(routes),\n },\n {\n path: 'social',\n element: <Social implicit={implicit} onAuthorize={onAuthorize} onLogined={handleLogined} />\n },\n {\n path: 'logout',\n element: <Logout onLogout={handleLogout} />\n },\n {\n path: 'login',\n element: <Login onLogin={onLogin} onAuthorize={handleAuthorize} onLogined={handleLogined} />\n },\n ...extraRoutes\n ],\n {\n basename\n }\n );\n\n return function() {\n return <ToastProvider>\n <RootComponent>\n <AppProvider appResolver={appResolver}>\n <RouterProvider router={router} />\n </AppProvider>\n </RootComponent>\n <Modal.Message />\n </ToastProvider>;\n };\n}\n"],"names":["_g","_extends","Object","assign","bind","target","i","arguments","length","source","key","prototype","hasOwnProperty","call","apply","this","SvgExternal","props","React","createElement","xmlns","width","height","fill","d","formatRelativePath","app","routes","parent","menus","route","meta","path","children","hideInMenu","access","passed","user","access_level","Array","isArray","intersection","roles","title","isExternal","href","replace","menu","icon","_jsx","className","hideChildrenInMenu","push","AppContext","createContext","AppProvider","_ref","appResolver","setApp","useState","useAsync","async","onSuccess","Provider","value","Loader","useAppState","context","useContext","Error","useApp","useMenu","matches","UNSAFE_RouteContext","routeMatch","pathnameBase","routesMatch","useMemo","base","getMenuData","reduceRight","match","handle","undefined","transformRoutes","map","index","hideMenu","SiderContext","useSider","Toggle","sider","Trigger","onClick","setShow","styled","div","renderMenuItems","items","item","_jsxs","MenuTitle","ExternalIcon","SubMenu","MenuItem","Link","to","collapseNode","expandNode","node","scrollHeight","motion","motionName","motionAppear","onAppearStart","onAppearActive","onEnterStart","onEnterActive","onLeaveStart","onLeaveActive","SiderLayout","header","headerAs","footer","footerAs","top","isMobile","useWindowSize","defaultTitle","showToggle","setShowToggle","pathname","useLocation","useMatches","reduce","selectedKeys","keys","split","pre","curr","join","openKeys","setOpenKeys","useEffect","slice","onOpenChange","useCallback","currentKey","filter","startsWith","Routes","Outlet","Title","FooterComp","Footer","sidebar","Sidebar","Header","Menu","mode","siderToggle","show","toggle","headless","Container","$top","Offcanvas","onHide","placement","style","Content","Main","memo","_ref2","useRoutes","nav","main","RcMenu","p","extra","showBack","bodyAs","fixed","defaultShowBack","navigate","useNavigate","location","$fixed","Back","Extra","Body","as","css","TabLayout","Dropdown","variant","size","Item","active","StyledNav","Nav","NavLink","classNames","UserContext","UserProvider","userResolver","onResolved","state","setState","current","execute","e","isRequestError","response","status","redirectUri","window","search","from","setUser","refresh","useUser","Avatar","a","logo","src","navbar","avatar","Access","require","fallback","_Fragment","LinkButton","Button","preventDefault","Context","Inner","request","result","useRequest","wrap","WithRequest","params","useParams","url","all","name","useRequestData","Social","onLogined","onAuthorize","implicit","error","token","parsed","queryString","parse","hash","access_token","redirect_uri","sessionStorage","getItem","newToken","data","isRecord","message","Card","Result","Navigate","Logout","onLogout","Login","onLogin","Row","Col","lg","span","offset","xxl","createApplication","options","basename","authentication","baseURL","RootComponent","Fragment","extraRoutes","defaults","updateToken","authTokenName","localStorage","setItem","removeItem","handleLogined","router","createBrowserRouter","element","query","history","usr","stripBasename","stringifyUrl","getAbsoluteUrl","ToastProvider","RouterProvider","Modal","Message"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topthink/common",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "scripts": {
5
5
  "prebuild": "rimraf lib types",
6
6
  "build": "rollup -c --environment NODE_ENV:production",
@@ -16,7 +16,7 @@
16
16
  "scss"
17
17
  ],
18
18
  "dependencies": {
19
- "@topthink/components": "^1.1.0",
19
+ "@topthink/components": "^1.1.1",
20
20
  "classnames": "^2.3.1",
21
21
  "history": "^5.0.0",
22
22
  "query-string": "^8.1.0",
@@ -51,5 +51,5 @@
51
51
  },
52
52
  "author": "yunwuxin <tzzhangyajun@qq.com> (https://github.com/yunwuxin)",
53
53
  "license": "MIT",
54
- "gitHead": "60aa34ea284af9a97a531a1ab5589d38f4792ee5"
54
+ "gitHead": "d40b843253d6b1487fe5889e547849ea22c7c480"
55
55
  }
@@ -0,0 +1,12 @@
1
+ import { Dispatch, ReactNode, SetStateAction } from 'react';
2
+ import { App, AppResolver } from '../utils/types';
3
+ type AppContextType = [App, Dispatch<SetStateAction<App>>];
4
+ export declare const AppContext: import("react").Context<AppContextType | null>;
5
+ interface Props {
6
+ appResolver?: AppResolver;
7
+ children: ReactNode;
8
+ }
9
+ export default function AppProvider({ appResolver, children }: Props): JSX.Element;
10
+ export declare function useAppState(): AppContextType;
11
+ export declare function useApp(): App;
12
+ export {};
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { User } from './utils/types';
1
+ import { App } from './utils/types';
2
2
  declare module 'react-router-dom' {
3
3
  interface Metadata {
4
4
  title?: string;
@@ -6,7 +6,7 @@ declare module 'react-router-dom' {
6
6
  hideInMenu?: boolean;
7
7
  hideChildrenInMenu?: boolean;
8
8
  hideMenu?: boolean;
9
- access?: number | string | string[] | ((user: User) => boolean);
9
+ access?: number | string | string[] | ((app: App) => boolean);
10
10
  href?: string;
11
11
  }
12
12
  interface IndexRouteObject {
@@ -30,8 +30,9 @@ export { default as Access } from './components/access';
30
30
  export { default as Content } from './components/content';
31
31
  export { default as LinkButton } from './components/link-button';
32
32
  export { useUser } from './components/user-provider';
33
+ export { useApp, useAppState } from './components/app-provider';
33
34
  export { default as WithRequest, useRequestData } from './components/with-request';
34
- export { User } from './utils/types';
35
+ export { User, App } from './utils/types';
35
36
  export { default as createApplication } from './utils/create-application';
36
37
  export { RouteObject, useRoutes, Link, Outlet, useLocation, useNavigate, useOutlet, useParams, useSearchParams, Navigate, useMatches, useLoaderData, useRouteLoaderData, useRevalidator, useRouteError, } from 'react-router-dom';
37
38
  export * from '@topthink/components';
@@ -1,6 +1,6 @@
1
1
  import { RouteObject } from 'react-router-dom';
2
2
  import { LoginProps } from '../pages/login';
3
- import { Promisable, UserResolver } from './types';
3
+ import { AppResolver, Promisable, UserResolver } from './types';
4
4
  import { ReactElement, ReactNode } from 'react';
5
5
  interface Component<P = {}> {
6
6
  (props: P): (ReactElement | null);
@@ -13,6 +13,7 @@ interface Options {
13
13
  onLogout?: () => Promisable<void>;
14
14
  onAuthorize?: (token?: any) => Promisable<void | string | undefined>;
15
15
  onLogin: (props: LoginProps) => ReactNode;
16
+ appResolver?: AppResolver;
16
17
  userResolver: UserResolver;
17
18
  routes: RouteObject[];
18
19
  extraRoutes?: RouteObject[];
@@ -1,6 +1,6 @@
1
1
  import type { RouteObject } from 'react-router-dom';
2
2
  import { ReactNode } from 'react';
3
- import { User } from './types';
3
+ import { App } from './types';
4
4
  export interface MenuData {
5
5
  path: string;
6
6
  title: string;
@@ -8,4 +8,4 @@ export interface MenuData {
8
8
  isExternal?: boolean;
9
9
  children: MenuData[];
10
10
  }
11
- export default function getMenuData(user: User, routes: RouteObject[], base?: string): MenuData[];
11
+ export default function getMenuData(app: App, routes: RouteObject[], base?: string): MenuData[];
@@ -1,3 +1,7 @@
1
+ export interface App {
2
+ user?: User;
3
+ [key: string]: any;
4
+ }
1
5
  export interface User {
2
6
  id: number;
3
7
  name: string;
@@ -10,5 +14,6 @@ export interface User {
10
14
  access_level: number;
11
15
  [key: string]: any;
12
16
  }
17
+ export type AppResolver = () => App | Promise<App>;
13
18
  export type UserResolver = () => User | Promise<User>;
14
19
  export type Promisable<T> = T | Promise<T>;