@topthink/common 1.1.20 → 1.1.23
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 +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
- package/scss/app.scss +2 -1
- package/types/index.d.ts +15 -2
- package/types/layout/sider.d.ts +2 -2
- package/types/utils/get-menu-data.d.ts +1 -9
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as c,jsxs as n,Fragment as e}from"react/jsx-runtime";import t,{SubMenu as i,MenuItem as r}from"rc-menu";import{styled as o,useAsync as l,Loader as s,request as a,Unauthorized as d}from"@topthink/components";export*from"@topthink/components";import{useRoutes as g,useLocation as h,Link as u,Navigate as m,BrowserRouter as p,Routes as v,Route as f}from"react-router-dom";export*from"react-router-dom";import b,{useMemo as x,useState as w,useEffect as _,useContext as y}from"react";import{Dropdown as k}from"react-bootstrap";import z from"query-string";import*as N from"path";import L from"classnames";import{intersection as S}from"lodash";function j(c,n){return n||(n=c.slice(0)),Object.freeze(Object.defineProperties(c,{raw:{value:Object.freeze(n)}}))}var I;const A=o.footer(I||(I=j(["\n\n"])));function U(){return c(A,{children:c("div",{className:"container"})})}const C=function(c){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"/";const e=[];for(const l of c){var t,i,r,o;if(null!==(t=l.meta)&&void 0!==t&&t.hideInMenu)continue;const c=null===(i=l.meta)||void 0===i?void 0:i.title;if(!c)continue;let s=l.path||"";s="".concat(n,"/").concat(s),s=s.replace(/\/+/,"/").replace(/\/$/,"");const a={title:c,icon:null===(r=l.meta)||void 0===r?void 0:r.icon,path:s,children:[]};null!==(o=l.meta)&&void 0!==o&&o.hideChildrenInMenu||l.children&&l.children.length>0&&(a.children=C(l.children,s)),e.push(a)}return e};var R,q,E,O,M,P;const F=t=>t.map((t=>{const o=n(e,{children:[t.icon&&c("i",{className:"bi bi-".concat(t.icon)}),t.title]});return t.children.length>0?c(i,{title:o,children:F(t.children)},t.path):c(r,{children:c(u,{to:t.path,children:o})},t.path)})),H=()=>({height:0}),K=c=>({height:c.scrollHeight}),B={motionName:"rc-menu-collapse",motionAppear:!0,onAppearStart:H,onAppearActive:K,onEnterStart:H,onEnterActive:K,onLeaveStart:K,onLeaveActive:H};function T(e){let{routes:t,basename:i,title:r}=e;const o=g(t),l=x((()=>function(c){return C(c,arguments.length>1&&void 0!==arguments[1]?arguments[1]:"/")}(t,i)),[t,i]),{pathname:s}=h(),a=x((()=>{const c=[];return s.split("/").reduce(((n,e)=>(n.length>1&&c.push(n.join("/")),[...n,e])),[]),c.push(s),c}),[s]),[d,u]=w([]);_((()=>{u(a.slice(0,-1))}),[a]);return n(W,{children:[n($,{children:[c(D,{children:r}),c(Q,{mode:"inline",motion:B,openKeys:d,onOpenChange:c=>{const n=c[c.length-1];u(c.filter((c=>n.startsWith(c))))},selectedKeys:a,children:F(l)})]}),n(G,{children:[c(J,{children:o}),c(U,{})]})]})}const W=o.div(R||(R=j(["\n display: flex;\n flex-wrap: nowrap;\n width: 100%;\n"]))),$=o.nav(q||(q=j(["\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n z-index: 100;\n padding: 54px 0 0;\n border-right: 1px solid #e3e3e3;\n width: 230px;\n background-color: #f5f5f5;\n"]))),D=o.div(E||(E=j(["\n padding: 10px 0;\n height: 64px;\n line-height: 44px;\n text-indent: 24px;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n font-size: 16px;\n"]))),G=o.div(O||(O=j(["\n margin-left: 230px;\n flex: 1;\n"]))),J=o.main(M||(M=j(["\n min-height: calc(100vh - 54px);\n position: relative;\n"]))),Q=o(t)(P||(P=j(["\n border: none;\n box-shadow: none;\n padding: 0;\n\n .rc-menu-item {\n display: flex;\n\n &:hover {\n background-color: #f0f0f0;\n }\n\n a {\n flex: 1;\n text-decoration: none;\n color: dimgray;\n\n .bi {\n font-size: 16px;\n line-height: 18px;\n margin-right: 9px;\n min-width: 19px;\n text-align: center;\n vertical-align: text-bottom;\n }\n }\n }\n\n .rc-menu-sub {\n background-color: #eee;\n border-top: 1px solid #eee;\n border-bottom: 1px solid #eee;\n\n & > li {\n &:first-child {\n margin-top: 4px;\n }\n\n &:last-child {\n margin-bottom: 4px;\n }\n }\n\n .rc-menu-item-selected {\n background-color: #eee;\n color: var(--bs-primary);\n\n & > a {\n color: var(--bs-primary);\n }\n }\n\n .rc-menu-item-active {\n background-color: #eee;\n }\n\n .rc-menu-item {\n &:hover {\n background-color: #e7e7e7;\n }\n }\n }\n\n .rc-menu-submenu {\n & > .rc-menu-submenu-title {\n &:hover {\n background-color: #e7e7e7;\n }\n\n .bi {\n font-size: 16px;\n line-height: 18px;\n margin-right: 9px;\n min-width: 19px;\n text-align: center;\n vertical-align: text-bottom;\n }\n }\n }\n\n .rc-menu-submenu-active > .rc-menu-submenu-title {\n background-color: #eee;\n }\n\n .rc-menu-item,\n .rc-menu-submenu > .rc-menu-submenu-title {\n padding: 0 8px 0 24px;\n font-size: 14px;\n line-height: 36px;\n cursor: pointer;\n }\n\n .rc-menu-sub > .rc-menu-item,\n .rc-menu-sub > .rc-menu-submenu > .rc-menu-submenu-title {\n padding-top: 0;\n padding-bottom: 0;\n padding-right: 0;\n }\n\n .rc-menu-submenu-arrow {\n line-height: 38px;\n }\n\n .rc-menu-item-selected {\n background-color: #f5f5f5;\n color: var(--bs-primary);\n\n & > a {\n color: var(--bs-primary);\n }\n }\n\n .rc-menu-submenu-selected {\n background-color: #eee;\n\n & > .rc-menu-submenu-title {\n color: var(--bs-primary);\n font-weight: 500;\n }\n }\n\n & > .rc-menu-item {\n line-height: 38px;\n }\n\n & > .rc-menu-submenu {\n &.rc-menu-submenu-selected {\n background-color: #f5f5f5;\n }\n\n & > .rc-menu-submenu-title {\n line-height: 38px;\n\n &:hover {\n background-color: #f0f0f0;\n }\n }\n\n &.rc-menu-submenu-active > .rc-menu-submenu-title {\n background-color: #f5f5f5;\n }\n\n & > .rc-menu-sub {\n border-top: 1px solid #e6e6e6;\n border-bottom: 1px solid #e6e6e6;\n\n & > li {\n &:first-child {\n margin-top: 9px;\n }\n\n &:last-child {\n margin-bottom: 9px;\n }\n }\n }\n }\n\n"])));function V(n){let{onLogin:e}=n;const{result:t}=l((async()=>{await e();const c=localStorage.getItem("redirect_uri");return c&&localStorage.removeItem("redirect_uri"),c||"/"}),[]);return t?c(m,{to:t,replace:!0}):c(s,{})}function X(n){let{onLogout:e}=n;return l((async()=>{await e()}),[]),c(s,{})}const Y=b.createContext({});function Z(e){const{basename:t="/",onLogin:i,onLogout:r,authentication:o,baseURL:l,userResolver:s}=e;l&&(a.defaults.baseURL=l),"token"===o&&a.interceptors.request.use((c=>{const n=localStorage.getItem("authorization");return n&&(c.headers={...c.headers,Authorization:"Bearer ".concat(n)}),c}));const g=c=>{window.location.pathname!==N.join(t,"/logout")&&localStorage.setItem("redirect_uri",function(c,n){return"/"===n?c:c.slice(n.length)}(window.location.pathname+window.location.search,t));const n=window.location.origin+N.join(t,"/login");window.location.href=z.stringifyUrl({url:c.url,query:{redirect_uri:n}})},h=async()=>{let c;if(i)c=await i();else{const n=z.parse(window.location.hash.substr(1));n.access_token&&(c=n.access_token)}"token"===o&&c&&localStorage.setItem("authorization",c)},u=async()=>{if(r)try{await r()}catch(c){c instanceof d&&g(c)}"token"===o&&localStorage.removeItem("authorization")};return function(e){let{children:i}=e;return c(Y.Provider,{value:{userResolver:s,onUnauthorized:g},children:c(p,{basename:t,children:n(v,{children:[c(f,{path:"*",element:i}),c(f,{path:"login",element:c(V,{onLogin:h})}),c(f,{path:"logout",element:c(X,{onLogout:u})})]})})})}}const cc=b.createContext(null),nc=function(n){let{children:e}=n;const[t,i]=w(null),{userResolver:r,onUnauthorized:o}=y(Y);return l((async()=>{if(r)return r()}),[],{onError(c){c instanceof d&&o&&o(c)},onSuccess(c){c&&i(c)}}),t?c(cc.Provider,{value:[t,i],children:e}):c(s,{})};function ec(){const c=y(cc);if(!c)throw new Error("please use `useUser` in UserContext");return c}var tc,ic;const rc=o.a(tc||(tc=j(["\n cursor: pointer;\n"])));function oc(e){let{children:t,menus:i,className:r,logo:o=!0}=e;const[l]=ec();return c(lc,{className:L("navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top",r),children:n("div",{className:"container-fluid",children:[o&&c("a",{className:"navbar-brand",href:"https://www.topthink.com",children:c("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"})}),t,n(k,{navbar:!0,children:[c(k.Toggle,{as:rc,className:"nav-link",children:c("img",{className:"rounded-circle",width:"25",height:"25",src:l.avatar})}),c(k.Menu,{className:"shadow",children:i})]})]})})}const lc=o.header(ic||(ic=j(["\n height: 54px;\n"])));function sc(n){let{require:t,children:i,fallback:r}=n;const[o]=ec();let l=!1;return"function"==typeof t?l=t(o):("string"==typeof t&&(t=[t]),l=S(o.roles,t).length>0),l||(i=r),c(e,{children:i})}var ac,dc,gc,hc,uc;function mc(e){let{title:t,children:i,nav:r,extra:o}=e;return n(pc,{children:[c(vc,{children:n("div",{className:"container",children:[c(bc,{children:t}),r,c(xc,{children:o})]})}),c(fc,{className:"container",children:i})]})}const pc=o.div(ac||(ac=j(["\n width: 100%;\n"]))),vc=o.div(dc||(dc=j(["\n background-color: #fff;\n display: flex;\n\n .container {\n padding: 0 24px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n\n .nav {\n .nav-link {\n position: relative;\n\n &.active {\n &:after {\n content: '';\n height: 2px;\n background: var(--bs-primary);\n display: block;\n position: absolute;\n left: 1rem;\n right: 1rem;\n bottom: -2px;\n }\n }\n }\n }\n }\n"]))),fc=o.div(gc||(gc=j(["\n margin-top: 24px;\n"]))),bc=o.div(hc||(hc=j(["\n font-size: 22px;\n line-height: 64px;\n height: 64px;\n"]))),xc=o.div(uc||(uc=j(["\n\n"])));export{sc as Access,mc as Content,U as Footer,oc as Header,T as SiderLayout,nc as UserProvider,Z as createApplication,ec as useUser};
|
|
1
|
+
import{jsx as c,jsxs as e,Fragment as n}from"react/jsx-runtime";import t,{SubMenu as i,MenuItem as r}from"rc-menu";import{styled as o,useAsync as l,Loader as s,request as a,Unauthorized as d}from"@topthink/components";export*from"@topthink/components";import{useRoutes as g,useLocation as h,Link as u,Navigate as m,BrowserRouter as p,Routes as v,Route as f}from"react-router-dom";export{Link,Navigate,Outlet,useLocation,useNavigate,useOutlet,useParams,useRoutes}from"react-router-dom";import b,{useMemo as x,useState as w,useEffect as _,useContext as y}from"react";import{Dropdown as k}from"react-bootstrap";import z from"query-string";import*as N from"path";import L from"classnames";import{intersection as S}from"lodash";function j(c,e){return e||(e=c.slice(0)),Object.freeze(Object.defineProperties(c,{raw:{value:Object.freeze(e)}}))}var I;const A=o.footer(I||(I=j(["\n\n"])));function U(){return c(A,{children:c("div",{className:"container"})})}const C=function(c){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"/";const n=[];for(const l of c){var t,i,r,o;if(null!==(t=l.meta)&&void 0!==t&&t.hideInMenu)continue;const c=null===(i=l.meta)||void 0===i?void 0:i.title;if(!c)continue;let s=l.path||"";s="".concat(e,"/").concat(s),s=s.replace(/\/+/,"/").replace(/\/$/,"");const a={title:c,icon:null===(r=l.meta)||void 0===r?void 0:r.icon,path:s,children:[]};null!==(o=l.meta)&&void 0!==o&&o.hideChildrenInMenu||l.children&&l.children.length>0&&(a.children=C(l.children,s)),n.push(a)}return n};var O,R,q,E,P,M;const F=t=>t.map((t=>{const o=e(n,{children:[t.icon&&c("i",{className:"bi bi-".concat(t.icon)}),t.title]});return t.children.length>0?c(i,{title:o,children:F(t.children)},t.path):c(r,{children:c(u,{to:t.path,children:o})},t.path)})),H=()=>({height:0}),K=c=>({height:c.scrollHeight}),B={motionName:"rc-menu-collapse",motionAppear:!0,onAppearStart:H,onAppearActive:K,onEnterStart:H,onEnterActive:K,onLeaveStart:K,onLeaveActive:H};function T(n){let{routes:t,basename:i,title:r}=n;const o=g(t),l=x((()=>function(c){return C(c,arguments.length>1&&void 0!==arguments[1]?arguments[1]:"/")}(t,i)),[t,i]),{pathname:s}=h(),a=x((()=>{const c=[];return s.split("/").reduce(((e,n)=>(e.length>1&&c.push(e.join("/")),[...e,n])),[]),c.push(s),c}),[s]),[d,u]=w([]);_((()=>{u(a.slice(0,-1))}),[a]);return e(W,{children:[e($,{children:[c(D,{children:r}),c(Q,{mode:"inline",motion:B,openKeys:d,onOpenChange:c=>{const e=c[c.length-1];u(c.filter((c=>e.startsWith(c))))},selectedKeys:a,children:F(l)})]}),e(G,{children:[c(J,{children:o}),c(U,{})]})]})}const W=o.div(O||(O=j(["\n display: flex;\n flex-wrap: nowrap;\n width: 100%;\n"]))),$=o.nav(R||(R=j(["\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n z-index: 100;\n padding: 54px 0 0;\n border-right: 1px solid #e3e3e3;\n width: 230px;\n background-color: #f5f5f5;\n"]))),D=o.div(q||(q=j(["\n padding: 10px 0;\n height: 64px;\n line-height: 44px;\n text-indent: 24px;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n font-size: 16px;\n"]))),G=o.div(E||(E=j(["\n margin-left: 230px;\n flex: 1;\n"]))),J=o.main(P||(P=j(["\n min-height: calc(100vh - 54px);\n position: relative;\n"]))),Q=o(t)(M||(M=j(["\n border: none;\n box-shadow: none;\n padding: 0;\n\n .rc-menu-item {\n display: flex;\n\n &:hover {\n background-color: #f0f0f0;\n }\n\n a {\n flex: 1;\n text-decoration: none;\n color: dimgray;\n\n .bi {\n font-size: 16px;\n line-height: 18px;\n margin-right: 9px;\n min-width: 19px;\n text-align: center;\n vertical-align: text-bottom;\n }\n }\n }\n\n .rc-menu-sub {\n background-color: #eee;\n border-top: 1px solid #eee;\n border-bottom: 1px solid #eee;\n\n & > li {\n &:first-child {\n margin-top: 4px;\n }\n\n &:last-child {\n margin-bottom: 4px;\n }\n }\n\n .rc-menu-item-selected {\n background-color: #eee;\n color: var(--bs-primary);\n\n & > a {\n color: var(--bs-primary);\n }\n }\n\n .rc-menu-item-active {\n background-color: #eee;\n }\n\n .rc-menu-item {\n &:hover {\n background-color: #e7e7e7;\n }\n }\n }\n\n .rc-menu-submenu {\n & > .rc-menu-submenu-title {\n &:hover {\n background-color: #e7e7e7;\n }\n\n .bi {\n font-size: 16px;\n line-height: 18px;\n margin-right: 9px;\n min-width: 19px;\n text-align: center;\n vertical-align: text-bottom;\n }\n }\n }\n\n .rc-menu-submenu-active > .rc-menu-submenu-title {\n background-color: #eee;\n }\n\n .rc-menu-item,\n .rc-menu-submenu > .rc-menu-submenu-title {\n padding: 0 8px 0 24px;\n font-size: 14px;\n line-height: 36px;\n cursor: pointer;\n }\n\n .rc-menu-sub > .rc-menu-item,\n .rc-menu-sub > .rc-menu-submenu > .rc-menu-submenu-title {\n padding-top: 0;\n padding-bottom: 0;\n padding-right: 0;\n }\n\n .rc-menu-submenu-arrow {\n line-height: 38px;\n }\n\n .rc-menu-item-selected {\n background-color: #f5f5f5;\n color: var(--bs-primary);\n\n & > a {\n color: var(--bs-primary);\n }\n }\n\n .rc-menu-submenu-selected {\n background-color: #eee;\n\n & > .rc-menu-submenu-title {\n color: var(--bs-primary);\n font-weight: 500;\n }\n }\n\n & > .rc-menu-item {\n line-height: 38px;\n }\n\n & > .rc-menu-submenu {\n &.rc-menu-submenu-selected {\n background-color: #f5f5f5;\n }\n\n & > .rc-menu-submenu-title {\n line-height: 38px;\n\n &:hover {\n background-color: #f0f0f0;\n }\n }\n\n &.rc-menu-submenu-active > .rc-menu-submenu-title {\n background-color: #f5f5f5;\n }\n\n & > .rc-menu-sub {\n border-top: 1px solid #e6e6e6;\n border-bottom: 1px solid #e6e6e6;\n\n & > li {\n &:first-child {\n margin-top: 9px;\n }\n\n &:last-child {\n margin-bottom: 9px;\n }\n }\n }\n }\n\n"])));function V(e){let{onLogin:n}=e;const{result:t}=l((async()=>{await n();const c=localStorage.getItem("redirect_uri");return c&&localStorage.removeItem("redirect_uri"),c||"/"}),[]);return t?c(m,{to:t,replace:!0}):c(s,{})}function X(e){let{onLogout:n}=e;return l((async()=>{await n()}),[]),c(s,{})}const Y=b.createContext({});function Z(n){const{basename:t="/",onLogin:i,onLogout:r,authentication:o,baseURL:l,userResolver:s}=n;l&&(a.defaults.baseURL=l),"token"===o&&a.interceptors.request.use((c=>{const e=localStorage.getItem("authorization");return e&&(c.headers={...c.headers,Authorization:"Bearer ".concat(e)}),c}));const g=c=>{window.location.pathname!==N.join(t,"/logout")&&localStorage.setItem("redirect_uri",function(c,e){return"/"===e?c:c.slice(e.length)}(window.location.pathname+window.location.search,t));const e=window.location.origin+N.join(t,"/login");window.location.href=z.stringifyUrl({url:c.url,query:{redirect_uri:e}})},h=async()=>{let c;if(i)c=await i();else{const e=z.parse(window.location.hash.substr(1));e.access_token&&(c=e.access_token)}"token"===o&&c&&localStorage.setItem("authorization",c)},u=async()=>{if(r)try{await r()}catch(c){c instanceof d&&g(c)}"token"===o&&localStorage.removeItem("authorization")};return function(n){let{children:i}=n;return c(Y.Provider,{value:{userResolver:s,onUnauthorized:g},children:c(p,{basename:t,children:e(v,{children:[c(f,{path:"*",element:i}),c(f,{path:"login",element:c(V,{onLogin:h})}),c(f,{path:"logout",element:c(X,{onLogout:u})})]})})})}}const cc=b.createContext(null),ec=function(e){let{children:n}=e;const[t,i]=w(null),{userResolver:r,onUnauthorized:o}=y(Y);return l((async()=>{if(r)return r()}),[],{onError(c){c instanceof d&&o&&o(c)},onSuccess(c){c&&i(c)}}),t?c(cc.Provider,{value:[t,i],children:n}):c(s,{})};function nc(){const c=y(cc);if(!c)throw new Error("please use `useUser` in UserContext");return c}var tc,ic;const rc=o.a(tc||(tc=j(["\n cursor: pointer;\n"])));function oc(n){let{children:t,menus:i,className:r,logo:o=!0}=n;const[l]=nc();return c(lc,{className:L("navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top",r),children:e("div",{className:"container-fluid",children:[o&&c("a",{className:"navbar-brand",href:"https://www.topthink.com",children:c("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"})}),t,e(k,{navbar:!0,children:[c(k.Toggle,{as:rc,className:"nav-link",children:c("img",{className:"rounded-circle",width:"25",height:"25",src:l.avatar})}),c(k.Menu,{className:"shadow",children:i})]})]})})}const lc=o.header(ic||(ic=j(["\n height: 54px;\n"])));function sc(e){let{require:t,children:i,fallback:r}=e;const[o]=nc();let l=!1;return"function"==typeof t?l=t(o):("string"==typeof t&&(t=[t]),l=S(o.roles,t).length>0),l||(i=r),c(n,{children:i})}var ac,dc,gc,hc,uc;function mc(n){let{title:t,children:i,nav:r,extra:o}=n;return e(pc,{children:[c(vc,{children:e("div",{className:"container",children:[c(bc,{children:t}),r,c(xc,{children:o})]})}),c(fc,{className:"container",children:i})]})}const pc=o.div(ac||(ac=j(["\n width: 100%;\n"]))),vc=o.div(dc||(dc=j(["\n background-color: #fff;\n display: flex;\n\n .container {\n padding: 0 24px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n\n .nav {\n .nav-link {\n position: relative;\n\n &.active {\n &:after {\n content: '';\n height: 2px;\n background: var(--bs-primary);\n display: block;\n position: absolute;\n left: 1rem;\n right: 1rem;\n bottom: -2px;\n }\n }\n }\n }\n }\n"]))),fc=o.div(gc||(gc=j(["\n margin-top: 24px;\n"]))),bc=o.div(hc||(hc=j(["\n font-size: 22px;\n line-height: 64px;\n height: 64px;\n"]))),xc=o.div(uc||(uc=j(["\n\n"])));export{sc as Access,mc as Content,U as Footer,oc as Header,T as SiderLayout,ec as UserProvider,Z as createApplication,nc as useUser};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js","../src/components/footer.tsx","../src/utils/get-menu-data.ts","../src/layout/sider.tsx","../src/pages/login.tsx","../src/pages/logout.tsx","../src/utils/create-application.tsx","../src/components/user-provider.tsx","../src/components/header.tsx","../src/images/logo.svg","../src/components/access.tsx","../src/components/content.tsx"],"sourcesContent":["export default function _taggedTemplateLiteral(strings, raw) {\n if (!raw) {\n raw = strings.slice(0);\n }\n\n return Object.freeze(Object.defineProperties(strings, {\n raw: {\n value: Object.freeze(raw)\n }\n }));\n}","import { styled } from '@topthink/components';\r\n\r\nconst FooterWrapper = styled.footer`\r\n\r\n`;\r\n\r\nexport default function Footer() {\r\n return <FooterWrapper>\r\n <div className='container'>\r\n\r\n </div>\r\n </FooterWrapper>;\r\n}\r\n","import type { RouteObject } from 'react-router-dom';\r\n\r\nexport interface MenuObject extends RouteObject {\r\n meta?: {\r\n title?: string\r\n icon?: string\r\n hideInMenu?: boolean\r\n hideChildrenInMenu?: boolean\r\n };\r\n}\r\n\r\nexport interface MenuData {\r\n path: string;\r\n title: string;\r\n icon?: string;\r\n children: MenuData[];\r\n}\r\n\r\nconst formatRelativePath = (\r\n routes: MenuObject[],\r\n parent: string = '/',\r\n): MenuData[] => {\r\n\r\n const menus: MenuData[] = [];\r\n\r\n for (const route of routes) {\r\n\r\n if (route.meta?.hideInMenu) {\r\n continue;\r\n }\r\n\r\n const title = route.meta?.title;\r\n if (!title) {\r\n continue;\r\n }\r\n\r\n let path = route.path || '';\r\n\r\n path = `${parent}/${path}`;\r\n\r\n path = path.replace(/\\/+/, '/').replace(/\\/$/, '');\r\n\r\n const icon = route.meta?.icon;\r\n\r\n const menu: MenuData = {\r\n title,\r\n icon,\r\n path,\r\n children: []\r\n };\r\n\r\n if (!route.meta?.hideChildrenInMenu) {\r\n if (route.children && route.children.length > 0) {\r\n menu.children = formatRelativePath(route.children, path);\r\n }\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(routes: MenuObject[], base: string = '/'): MenuData[] {\r\n return formatRelativePath(routes, base);\r\n}\r\n","import RcMenu, { MenuItem, SubMenu } from 'rc-menu';\r\nimport Footer from '../components/footer';\r\nimport { Link, useLocation, useRoutes } from 'react-router-dom';\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport getMenuData, { MenuData, MenuObject } from '../utils/get-menu-data';\r\nimport type { CSSMotionProps } from 'rc-motion';\r\nimport { styled } from '@topthink/components';\r\n\r\ninterface Props {\r\n title: string;\r\n routes: MenuObject[];\r\n basename: string;\r\n}\r\n\r\nconst renderMenuItems = (items: MenuData[]) => {\r\n return items.map((item) => {\r\n\r\n const title = <>\r\n {item.icon && <i className={`bi bi-${item.icon}`} />}\r\n {item.title}\r\n </>;\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 <Link to={item.path}>\r\n {title}\r\n </Link>\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\n\r\nexport default function SiderLayout({ routes, basename, title }: Props) {\r\n\r\n const children = useRoutes(routes);\r\n\r\n const menu = useMemo(() => getMenuData(routes, basename), [routes, basename]);\r\n\r\n const { pathname } = useLocation();\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 setOpenKeys(selectedKeys.slice(0, -1));\r\n }, [selectedKeys]);\r\n\r\n const onOpenChange = (openKeys: string[]) => {\r\n const currentKey = openKeys[openKeys.length - 1];\r\n setOpenKeys(openKeys.filter(key => currentKey.startsWith(key)));\r\n };\r\n\r\n return <Container>\r\n <Sidebar>\r\n <Header>{title}</Header>\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 </Sidebar>\r\n <Content>\r\n <Main>{children}</Main>\r\n <Footer />\r\n </Content>\r\n </Container>;\r\n}\r\n\r\nconst Container = styled.div`\r\n display: flex;\r\n flex-wrap: nowrap;\r\n width: 100%;\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: 54px 0 0;\r\n border-right: 1px solid #e3e3e3;\r\n width: 230px;\r\n background-color: #f5f5f5;\r\n`;\r\n\r\nconst Header = styled.div`\r\n padding: 10px 0;\r\n height: 64px;\r\n line-height: 44px;\r\n text-indent: 24px;\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 Content = styled.div`\r\n margin-left: 230px;\r\n flex: 1;\r\n`;\r\n\r\nconst Main = styled.main`\r\n min-height: calc(100vh - 54px);\r\n position: relative;\r\n`;\r\n\r\nconst Menu = styled(RcMenu)`\r\n border: none;\r\n box-shadow: none;\r\n padding: 0;\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 .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n margin-right: 9px;\r\n min-width: 19px;\r\n text-align: center;\r\n vertical-align: text-bottom;\r\n }\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-active {\r\n background-color: #eee;\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 .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n margin-right: 9px;\r\n min-width: 19px;\r\n text-align: center;\r\n vertical-align: text-bottom;\r\n }\r\n }\r\n }\r\n\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: 38px;\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","import { Loader, useAsync } from '@topthink/components';\r\nimport { Navigate } from 'react-router-dom';\r\n\r\ninterface LoginProps {\r\n onLogin: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Login({ onLogin }: LoginProps) {\r\n const { result } = useAsync(async () => {\r\n await onLogin();\r\n\r\n const redirectUri = localStorage.getItem('redirect_uri');\r\n if (redirectUri) {\r\n localStorage.removeItem('redirect_uri');\r\n }\r\n return redirectUri || '/';\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\n\r\ninterface LogoutProps {\r\n onLogout: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Logout({ onLogout }: LogoutProps) {\r\n useAsync(async () => {\r\n await onLogout();\r\n }, []);\r\n\r\n return <Loader />;\r\n}\r\n","import { BrowserRouter, Route, Routes } from 'react-router-dom';\r\nimport React, { PropsWithChildren } from 'react';\r\nimport Login from '../pages/login';\r\nimport Logout from '../pages/logout';\r\nimport queryString from 'query-string';\r\nimport { User } from './types';\r\nimport * as path from 'path';\r\nimport { request, Unauthorized } from '@topthink/components';\r\n\r\ntype UserResolver = () => User | Promise<User>\r\n\r\nexport const AppContext = React.createContext<{ userResolver?: UserResolver, onUnauthorized?: (error: Unauthorized) => void }>({});\r\n\r\nfunction stripBasename(pathname: string, basename: string) {\r\n if (basename === '/') return pathname;\r\n\r\n return pathname.slice(basename.length);\r\n}\r\n\r\ninterface Options {\r\n baseURL?: string;\r\n basename?: string;\r\n authentication?: 'cookie' | 'token';\r\n onLogout?: () => void | Promise<void>;\r\n onLogin?: () => (void | string) | Promise<void | string>;\r\n userResolver?: UserResolver;\r\n}\r\n\r\nexport default function createApplication(options: Options) {\r\n const { basename = '/', onLogin, onLogout, authentication, baseURL, userResolver } = options;\r\n\r\n if (baseURL) {\r\n request.defaults.baseURL = baseURL;\r\n }\r\n\r\n if (authentication === 'token') {\r\n request.interceptors.request.use(\r\n config => {\r\n const token = localStorage.getItem('authorization');\r\n\r\n if (token) {\r\n config.headers = {\r\n ...config.headers,\r\n Authorization: `Bearer ${token}`\r\n };\r\n }\r\n return config;\r\n }\r\n );\r\n }\r\n\r\n const onUnauthorized = (error: Unauthorized) => {\r\n if (window.location.pathname !== path.join(basename, '/logout')) {\r\n localStorage.setItem('redirect_uri', stripBasename(window.location.pathname + window.location.search, basename));\r\n }\r\n const redirectUri = window.location.origin + path.join(basename, '/login');\r\n\r\n window.location.href = queryString.stringifyUrl({\r\n url: error.url,\r\n query: { redirect_uri: redirectUri }\r\n });\r\n };\r\n\r\n const handleLogin = async () => {\r\n let token: string | void;\r\n if (onLogin) {\r\n token = await onLogin();\r\n } else {\r\n const parsed = queryString.parse(window.location.hash.substr(1));\r\n if (parsed.access_token) {\r\n token = parsed.access_token as string;\r\n }\r\n }\r\n\r\n if (authentication === 'token' && token) {\r\n localStorage.setItem('authorization', token);\r\n }\r\n };\r\n\r\n const handleLogout = async () => {\r\n if (onLogout) {\r\n try {\r\n await onLogout();\r\n } catch (e) {\r\n if (e instanceof Unauthorized) {\r\n onUnauthorized(e);\r\n }\r\n }\r\n }\r\n\r\n if (authentication === 'token') {\r\n localStorage.removeItem('authorization');\r\n }\r\n };\r\n\r\n return function({ children }: PropsWithChildren<any>) {\r\n return <AppContext.Provider value={{ userResolver, onUnauthorized }}>\r\n <BrowserRouter basename={basename}>\r\n <Routes>\r\n <Route path='*' element={children} />\r\n <Route path='login' element={<Login onLogin={handleLogin} />} />\r\n <Route path='logout' element={<Logout onLogout={handleLogout} />} />\r\n </Routes>\r\n </BrowserRouter>\r\n </AppContext.Provider>;\r\n };\r\n}\r\n","import React, { PropsWithChildren, useContext, useState } from 'react';\r\nimport { User } from '../utils/types';\r\nimport { AppContext } from '../utils/create-application';\r\nimport { Loader, Unauthorized, useAsync } from '@topthink/components';\r\n\r\nexport const UserContext = React.createContext<[User, ((user: User) => void)] | null>(null);\r\n\r\nconst UserProvider = function({ children }: PropsWithChildren<any>) {\r\n const [state, setState] = useState<User | null>(null);\r\n\r\n const { userResolver, onUnauthorized } = useContext(AppContext);\r\n\r\n useAsync(async () => {\r\n if (userResolver) {\r\n return userResolver();\r\n }\r\n }, [], {\r\n onError(e) {\r\n if (e instanceof Unauthorized && onUnauthorized) {\r\n onUnauthorized(e);\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 return <UserContext.Provider value={[state, setState]}>\r\n {children}\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 { styled } from '@topthink/components';\r\nimport { PropsWithChildren, ReactNode } from 'react';\r\n\r\ninterface ContentProps {\r\n title: string;\r\n nav?: ReactNode;\r\n extra?: ReactNode;\r\n}\r\n\r\nexport default function Content({ title, children, nav, extra }: PropsWithChildren<ContentProps>) {\r\n\r\n return <Container>\r\n <Header>\r\n <div className='container'>\r\n <Title>\r\n {title}\r\n </Title>\r\n {nav}\r\n <Extra>{extra}</Extra>\r\n </div>\r\n </Header>\r\n <Body className='container'>\r\n {children}\r\n </Body>\r\n </Container>;\r\n};\r\n\r\nconst Container = styled.div`\r\n width: 100%;\r\n`;\r\n\r\nconst Header = styled.div`\r\n background-color: #fff;\r\n display: flex;\r\n\r\n .container {\r\n padding: 0 24px;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n\r\n .nav {\r\n .nav-link {\r\n position: relative;\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 }\r\n }\r\n`;\r\n\r\nconst Body = styled.div`\r\n margin-top: 24px;\r\n`;\r\n\r\nconst Title = styled.div`\r\n font-size: 22px;\r\n line-height: 64px;\r\n height: 64px;\r\n`;\r\n\r\nconst Extra = styled.div`\r\n\r\n`;\r\n"],"names":["_taggedTemplateLiteral","strings","raw","slice","Object","freeze","defineProperties","value","FooterWrapper","styled","footer","Footer","_jsx","className","formatRelativePath","routes","parent","menus","route","meta","_route$meta","hideInMenu","title","_route$meta2","path","replace","menu","icon","_route$meta3","children","_route$meta4","hideChildrenInMenu","length","push","renderMenuItems","items","map","item","_jsxs","SubMenu","MenuItem","Link","to","collapseNode","height","expandNode","node","scrollHeight","motion","motionName","motionAppear","onAppearStart","onAppearActive","onEnterStart","onEnterActive","onLeaveStart","onLeaveActive","SiderLayout","basename","useRoutes","useMemo","getMenuData","pathname","useLocation","selectedKeys","keys","split","reduce","pre","curr","join","openKeys","setOpenKeys","useState","useEffect","Container","Sidebar","Header","Menu","mode","onOpenChange","currentKey","filter","key","startsWith","Content","Main","div","nav","main","RcMenu","Login","onLogin","result","useAsync","async","redirectUri","localStorage","getItem","removeItem","Navigate","Loader","Logout","onLogout","AppContext","React","createContext","createApplication","options","authentication","baseURL","userResolver","request","defaults","interceptors","use","config","token","headers","Authorization","onUnauthorized","error","window","location","setItem","stripBasename","search","origin","href","queryString","stringifyUrl","url","query","redirect_uri","handleLogin","parsed","parse","hash","substr","access_token","handleLogout","e","Unauthorized","Provider","BrowserRouter","Routes","Route","element","UserContext","UserProvider","state","setState","useContext","onError","onSuccess","user","useUser","context","Error","Avatar","a","logo","classNames","src","Dropdown","navbar","Toggle","as","width","avatar","header","Access","require","fallback","passed","intersection","roles","extra","Title","Extra","Body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js","../src/components/footer.tsx","../src/utils/get-menu-data.ts","../src/layout/sider.tsx","../src/pages/login.tsx","../src/pages/logout.tsx","../src/utils/create-application.tsx","../src/components/user-provider.tsx","../src/components/header.tsx","../src/images/logo.svg","../src/components/access.tsx","../src/components/content.tsx"],"sourcesContent":["export default function _taggedTemplateLiteral(strings, raw) {\n if (!raw) {\n raw = strings.slice(0);\n }\n\n return Object.freeze(Object.defineProperties(strings, {\n raw: {\n value: Object.freeze(raw)\n }\n }));\n}","import { styled } from '@topthink/components';\r\n\r\nconst FooterWrapper = styled.footer`\r\n\r\n`;\r\n\r\nexport default function Footer() {\r\n return <FooterWrapper>\r\n <div className='container'>\r\n\r\n </div>\r\n </FooterWrapper>;\r\n}\r\n","import type { RouteObject } from 'react-router-dom';\r\n\r\nexport interface MenuData {\r\n path: string;\r\n title: string;\r\n icon?: string;\r\n children: MenuData[];\r\n}\r\n\r\nconst formatRelativePath = (\r\n routes: RouteObject[],\r\n parent: string = '/',\r\n): MenuData[] => {\r\n\r\n const menus: MenuData[] = [];\r\n\r\n for (const route of routes) {\r\n\r\n if (route.meta?.hideInMenu) {\r\n continue;\r\n }\r\n\r\n const title = route.meta?.title;\r\n if (!title) {\r\n continue;\r\n }\r\n\r\n let path = route.path || '';\r\n\r\n path = `${parent}/${path}`;\r\n\r\n path = path.replace(/\\/+/, '/').replace(/\\/$/, '');\r\n\r\n const icon = route.meta?.icon;\r\n\r\n const menu: MenuData = {\r\n title,\r\n icon,\r\n path,\r\n children: []\r\n };\r\n\r\n if (!route.meta?.hideChildrenInMenu) {\r\n if (route.children && route.children.length > 0) {\r\n menu.children = formatRelativePath(route.children, path);\r\n }\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(routes: RouteObject[], base: string = '/'): MenuData[] {\r\n return formatRelativePath(routes, base);\r\n}\r\n","import RcMenu, { MenuItem, SubMenu } from 'rc-menu';\r\nimport Footer from '../components/footer';\r\nimport { Link, RouteObject, useLocation, useRoutes } from 'react-router-dom';\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport getMenuData, { MenuData } from '../utils/get-menu-data';\r\nimport type { CSSMotionProps } from 'rc-motion';\r\nimport { styled } from '@topthink/components';\r\n\r\ninterface Props {\r\n title: string;\r\n routes: RouteObject[];\r\n basename: string;\r\n}\r\n\r\nconst renderMenuItems = (items: MenuData[]) => {\r\n return items.map((item) => {\r\n\r\n const title = <>\r\n {item.icon && <i className={`bi bi-${item.icon}`} />}\r\n {item.title}\r\n </>;\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 <Link to={item.path}>\r\n {title}\r\n </Link>\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\n\r\nexport default function SiderLayout({ routes, basename, title }: Props) {\r\n\r\n const children = useRoutes(routes);\r\n\r\n const menu = useMemo(() => getMenuData(routes, basename), [routes, basename]);\r\n\r\n const { pathname } = useLocation();\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 setOpenKeys(selectedKeys.slice(0, -1));\r\n }, [selectedKeys]);\r\n\r\n const onOpenChange = (openKeys: string[]) => {\r\n const currentKey = openKeys[openKeys.length - 1];\r\n setOpenKeys(openKeys.filter(key => currentKey.startsWith(key)));\r\n };\r\n\r\n return <Container>\r\n <Sidebar>\r\n <Header>{title}</Header>\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 </Sidebar>\r\n <Content>\r\n <Main>{children}</Main>\r\n <Footer />\r\n </Content>\r\n </Container>;\r\n}\r\n\r\nconst Container = styled.div`\r\n display: flex;\r\n flex-wrap: nowrap;\r\n width: 100%;\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: 54px 0 0;\r\n border-right: 1px solid #e3e3e3;\r\n width: 230px;\r\n background-color: #f5f5f5;\r\n`;\r\n\r\nconst Header = styled.div`\r\n padding: 10px 0;\r\n height: 64px;\r\n line-height: 44px;\r\n text-indent: 24px;\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 Content = styled.div`\r\n margin-left: 230px;\r\n flex: 1;\r\n`;\r\n\r\nconst Main = styled.main`\r\n min-height: calc(100vh - 54px);\r\n position: relative;\r\n`;\r\n\r\nconst Menu = styled(RcMenu)`\r\n border: none;\r\n box-shadow: none;\r\n padding: 0;\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 .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n margin-right: 9px;\r\n min-width: 19px;\r\n text-align: center;\r\n vertical-align: text-bottom;\r\n }\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-active {\r\n background-color: #eee;\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 .bi {\r\n font-size: 16px;\r\n line-height: 18px;\r\n margin-right: 9px;\r\n min-width: 19px;\r\n text-align: center;\r\n vertical-align: text-bottom;\r\n }\r\n }\r\n }\r\n\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: 38px;\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","import { Loader, useAsync } from '@topthink/components';\r\nimport { Navigate } from 'react-router-dom';\r\n\r\ninterface LoginProps {\r\n onLogin: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Login({ onLogin }: LoginProps) {\r\n const { result } = useAsync(async () => {\r\n await onLogin();\r\n\r\n const redirectUri = localStorage.getItem('redirect_uri');\r\n if (redirectUri) {\r\n localStorage.removeItem('redirect_uri');\r\n }\r\n return redirectUri || '/';\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\n\r\ninterface LogoutProps {\r\n onLogout: () => void | Promise<void>;\r\n}\r\n\r\nexport default function Logout({ onLogout }: LogoutProps) {\r\n useAsync(async () => {\r\n await onLogout();\r\n }, []);\r\n\r\n return <Loader />;\r\n}\r\n","import { BrowserRouter, Route, Routes } from 'react-router-dom';\r\nimport React, { PropsWithChildren } from 'react';\r\nimport Login from '../pages/login';\r\nimport Logout from '../pages/logout';\r\nimport queryString from 'query-string';\r\nimport { User } from './types';\r\nimport * as path from 'path';\r\nimport { request, Unauthorized } from '@topthink/components';\r\n\r\ntype UserResolver = () => User | Promise<User>\r\n\r\nexport const AppContext = React.createContext<{ userResolver?: UserResolver, onUnauthorized?: (error: Unauthorized) => void }>({});\r\n\r\nfunction stripBasename(pathname: string, basename: string) {\r\n if (basename === '/') return pathname;\r\n\r\n return pathname.slice(basename.length);\r\n}\r\n\r\ninterface Options {\r\n baseURL?: string;\r\n basename?: string;\r\n authentication?: 'cookie' | 'token';\r\n onLogout?: () => void | Promise<void>;\r\n onLogin?: () => (void | string) | Promise<void | string>;\r\n userResolver?: UserResolver;\r\n}\r\n\r\nexport default function createApplication(options: Options) {\r\n const { basename = '/', onLogin, onLogout, authentication, baseURL, userResolver } = options;\r\n\r\n if (baseURL) {\r\n request.defaults.baseURL = baseURL;\r\n }\r\n\r\n if (authentication === 'token') {\r\n request.interceptors.request.use(\r\n config => {\r\n const token = localStorage.getItem('authorization');\r\n\r\n if (token) {\r\n config.headers = {\r\n ...config.headers,\r\n Authorization: `Bearer ${token}`\r\n };\r\n }\r\n return config;\r\n }\r\n );\r\n }\r\n\r\n const onUnauthorized = (error: Unauthorized) => {\r\n if (window.location.pathname !== path.join(basename, '/logout')) {\r\n localStorage.setItem('redirect_uri', stripBasename(window.location.pathname + window.location.search, basename));\r\n }\r\n const redirectUri = window.location.origin + path.join(basename, '/login');\r\n\r\n window.location.href = queryString.stringifyUrl({\r\n url: error.url,\r\n query: { redirect_uri: redirectUri }\r\n });\r\n };\r\n\r\n const handleLogin = async () => {\r\n let token: string | void;\r\n if (onLogin) {\r\n token = await onLogin();\r\n } else {\r\n const parsed = queryString.parse(window.location.hash.substr(1));\r\n if (parsed.access_token) {\r\n token = parsed.access_token as string;\r\n }\r\n }\r\n\r\n if (authentication === 'token' && token) {\r\n localStorage.setItem('authorization', token);\r\n }\r\n };\r\n\r\n const handleLogout = async () => {\r\n if (onLogout) {\r\n try {\r\n await onLogout();\r\n } catch (e) {\r\n if (e instanceof Unauthorized) {\r\n onUnauthorized(e);\r\n }\r\n }\r\n }\r\n\r\n if (authentication === 'token') {\r\n localStorage.removeItem('authorization');\r\n }\r\n };\r\n\r\n return function({ children }: PropsWithChildren<any>) {\r\n return <AppContext.Provider value={{ userResolver, onUnauthorized }}>\r\n <BrowserRouter basename={basename}>\r\n <Routes>\r\n <Route path='*' element={children} />\r\n <Route path='login' element={<Login onLogin={handleLogin} />} />\r\n <Route path='logout' element={<Logout onLogout={handleLogout} />} />\r\n </Routes>\r\n </BrowserRouter>\r\n </AppContext.Provider>;\r\n };\r\n}\r\n","import React, { PropsWithChildren, useContext, useState } from 'react';\r\nimport { User } from '../utils/types';\r\nimport { AppContext } from '../utils/create-application';\r\nimport { Loader, Unauthorized, useAsync } from '@topthink/components';\r\n\r\nexport const UserContext = React.createContext<[User, ((user: User) => void)] | null>(null);\r\n\r\nconst UserProvider = function({ children }: PropsWithChildren<any>) {\r\n const [state, setState] = useState<User | null>(null);\r\n\r\n const { userResolver, onUnauthorized } = useContext(AppContext);\r\n\r\n useAsync(async () => {\r\n if (userResolver) {\r\n return userResolver();\r\n }\r\n }, [], {\r\n onError(e) {\r\n if (e instanceof Unauthorized && onUnauthorized) {\r\n onUnauthorized(e);\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 return <UserContext.Provider value={[state, setState]}>\r\n {children}\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 { styled } from '@topthink/components';\r\nimport { PropsWithChildren, ReactNode } from 'react';\r\n\r\ninterface ContentProps {\r\n title: string;\r\n nav?: ReactNode;\r\n extra?: ReactNode;\r\n}\r\n\r\nexport default function Content({ title, children, nav, extra }: PropsWithChildren<ContentProps>) {\r\n\r\n return <Container>\r\n <Header>\r\n <div className='container'>\r\n <Title>\r\n {title}\r\n </Title>\r\n {nav}\r\n <Extra>{extra}</Extra>\r\n </div>\r\n </Header>\r\n <Body className='container'>\r\n {children}\r\n </Body>\r\n </Container>;\r\n};\r\n\r\nconst Container = styled.div`\r\n width: 100%;\r\n`;\r\n\r\nconst Header = styled.div`\r\n background-color: #fff;\r\n display: flex;\r\n\r\n .container {\r\n padding: 0 24px;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n\r\n .nav {\r\n .nav-link {\r\n position: relative;\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 }\r\n }\r\n`;\r\n\r\nconst Body = styled.div`\r\n margin-top: 24px;\r\n`;\r\n\r\nconst Title = styled.div`\r\n font-size: 22px;\r\n line-height: 64px;\r\n height: 64px;\r\n`;\r\n\r\nconst Extra = styled.div`\r\n\r\n`;\r\n"],"names":["_taggedTemplateLiteral","strings","raw","slice","Object","freeze","defineProperties","value","FooterWrapper","styled","footer","Footer","_jsx","className","formatRelativePath","routes","parent","menus","route","meta","_route$meta","hideInMenu","title","_route$meta2","path","replace","menu","icon","_route$meta3","children","_route$meta4","hideChildrenInMenu","length","push","renderMenuItems","items","map","item","_jsxs","SubMenu","MenuItem","Link","to","collapseNode","height","expandNode","node","scrollHeight","motion","motionName","motionAppear","onAppearStart","onAppearActive","onEnterStart","onEnterActive","onLeaveStart","onLeaveActive","SiderLayout","basename","useRoutes","useMemo","getMenuData","pathname","useLocation","selectedKeys","keys","split","reduce","pre","curr","join","openKeys","setOpenKeys","useState","useEffect","Container","Sidebar","Header","Menu","mode","onOpenChange","currentKey","filter","key","startsWith","Content","Main","div","nav","main","RcMenu","Login","onLogin","result","useAsync","async","redirectUri","localStorage","getItem","removeItem","Navigate","Loader","Logout","onLogout","AppContext","React","createContext","createApplication","options","authentication","baseURL","userResolver","request","defaults","interceptors","use","config","token","headers","Authorization","onUnauthorized","error","window","location","setItem","stripBasename","search","origin","href","queryString","stringifyUrl","url","query","redirect_uri","handleLogin","parsed","parse","hash","substr","access_token","handleLogout","e","Unauthorized","Provider","BrowserRouter","Routes","Route","element","UserContext","UserProvider","state","setState","useContext","onError","onSuccess","user","useUser","context","Error","Avatar","a","logo","classNames","src","Dropdown","navbar","Toggle","as","width","avatar","header","Access","require","fallback","passed","intersection","roles","extra","Title","Extra","Body"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topthink/common",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.23",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "rollup -c --environment NODE_ENV:production",
|
|
6
6
|
"build:dev": "rollup -c",
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"scss"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@topthink/components": "^1.0.
|
|
18
|
+
"@topthink/components": "^1.0.5",
|
|
19
19
|
"classnames": "^2.3.1",
|
|
20
20
|
"history": "^5.0.0",
|
|
21
21
|
"query-string": "^7.0.1",
|
|
22
22
|
"rc-menu": "^9.0.12",
|
|
23
|
-
"react-router-dom": "^6.
|
|
23
|
+
"react-router-dom": "^6.4.3"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"bootstrap": "^5.2.2",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
},
|
|
51
51
|
"author": "yunwuxin <tzzhangyajun@qq.com> (https://github.com/yunwuxin)",
|
|
52
52
|
"license": "MIT",
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "494f24c9caa9aaadbb9d7becb66d11b9bf5e9da7"
|
|
54
54
|
}
|
package/scss/app.scss
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
declare module 'react-router' {
|
|
2
|
+
interface Metadata {
|
|
3
|
+
title?: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
hideInMenu?: boolean;
|
|
6
|
+
hideChildrenInMenu?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface IndexRouteObject {
|
|
9
|
+
meta?: Metadata;
|
|
10
|
+
}
|
|
11
|
+
interface NonIndexRouteObject {
|
|
12
|
+
meta?: Metadata;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
1
15
|
export { default as SiderLayout } from './layout/sider';
|
|
2
16
|
export { default as Header } from './components/header';
|
|
3
17
|
export { default as Footer } from './components/footer';
|
|
@@ -6,6 +20,5 @@ export { default as Content } from './components/content';
|
|
|
6
20
|
export { default as UserProvider, useUser } from './components/user-provider';
|
|
7
21
|
export { User } from './utils/types';
|
|
8
22
|
export { default as createApplication } from './utils/create-application';
|
|
9
|
-
export {
|
|
10
|
-
export * from 'react-router-dom';
|
|
23
|
+
export { RouteObject, useRoutes, Link, Outlet, useLocation, useNavigate, useOutlet, useParams, Navigate } from 'react-router-dom';
|
|
11
24
|
export * from '@topthink/components';
|
package/types/layout/sider.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
2
|
+
import { RouteObject } from 'react-router-dom';
|
|
3
3
|
interface Props {
|
|
4
4
|
title: string;
|
|
5
|
-
routes:
|
|
5
|
+
routes: RouteObject[];
|
|
6
6
|
basename: string;
|
|
7
7
|
}
|
|
8
8
|
export default function SiderLayout({ routes, basename, title }: Props): JSX.Element;
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import type { RouteObject } from 'react-router-dom';
|
|
2
|
-
export interface MenuObject extends RouteObject {
|
|
3
|
-
meta?: {
|
|
4
|
-
title?: string;
|
|
5
|
-
icon?: string;
|
|
6
|
-
hideInMenu?: boolean;
|
|
7
|
-
hideChildrenInMenu?: boolean;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
2
|
export interface MenuData {
|
|
11
3
|
path: string;
|
|
12
4
|
title: string;
|
|
13
5
|
icon?: string;
|
|
14
6
|
children: MenuData[];
|
|
15
7
|
}
|
|
16
|
-
export default function getMenuData(routes:
|
|
8
|
+
export default function getMenuData(routes: RouteObject[], base?: string): MenuData[];
|