@vef-framework/starter 1.0.121 → 1.0.123
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/cjs/api.cjs +17 -0
- package/cjs/app.cjs +27 -0
- package/cjs/components/index.cjs +20 -0
- package/cjs/components/vef-access-denied-page/index.cjs +27 -0
- package/cjs/components/vef-access-denied-page/props.cjs +4 -0
- package/cjs/components/vef-app/index.cjs +19 -0
- package/cjs/components/vef-app/props.cjs +4 -0
- package/cjs/components/vef-dev-assistant/index.cjs +159 -0
- package/cjs/components/vef-dev-assistant/props.cjs +4 -0
- package/cjs/components/vef-error-page/index.cjs +24 -0
- package/cjs/components/vef-error-page/props.cjs +4 -0
- package/cjs/components/vef-login-page/index.cjs +41 -0
- package/cjs/components/vef-login-page/props.cjs +4 -0
- package/cjs/components/vef-not-found-page/index.cjs +26 -0
- package/cjs/components/vef-not-found-page/props.cjs +4 -0
- package/cjs/components/vef-router-provider/index.cjs +22 -0
- package/cjs/components/vef-router-provider/props.cjs +4 -0
- package/cjs/constants.cjs +17 -0
- package/cjs/helper.cjs +22 -0
- package/cjs/index.cjs +47 -0
- package/cjs/router.cjs +72 -0
- package/cjs/routes/access-denied.cjs +14 -0
- package/cjs/routes/index.cjs +14 -0
- package/cjs/routes/layout.cjs +136 -0
- package/cjs/routes/login.cjs +31 -0
- package/cjs/routes/root.cjs +24 -0
- package/cjs/store.cjs +21 -0
- package/esm/api.js +15 -0
- package/esm/app.js +25 -0
- package/esm/components/index.js +10 -0
- package/esm/components/vef-access-denied-page/index.js +23 -0
- package/esm/components/vef-access-denied-page/props.js +2 -0
- package/esm/components/vef-app/index.js +15 -0
- package/esm/components/vef-app/props.js +2 -0
- package/esm/components/vef-dev-assistant/index.js +155 -0
- package/esm/components/vef-dev-assistant/props.js +2 -0
- package/esm/components/vef-error-page/index.js +20 -0
- package/esm/components/vef-error-page/props.js +2 -0
- package/esm/components/vef-login-page/index.js +37 -0
- package/esm/components/vef-login-page/props.js +2 -0
- package/esm/components/vef-not-found-page/index.js +22 -0
- package/esm/components/vef-not-found-page/props.js +2 -0
- package/esm/components/vef-router-provider/index.js +18 -0
- package/esm/components/vef-router-provider/props.js +2 -0
- package/esm/constants.js +10 -0
- package/esm/helper.js +20 -0
- package/esm/index.js +22 -0
- package/esm/router.js +70 -0
- package/esm/routes/access-denied.js +12 -0
- package/esm/routes/index.js +7 -0
- package/esm/routes/layout.js +134 -0
- package/esm/routes/login.js +29 -0
- package/esm/routes/root.js +22 -0
- package/esm/store.js +19 -0
- package/package.json +17 -16
- package/es/api.js +0 -1
- package/es/app.js +0 -1
- package/es/components/index.js +0 -1
- package/es/components/vef-access-denied-page/index.js +0 -1
- package/es/components/vef-app/index.js +0 -1
- package/es/components/vef-dev-assistant/index.js +0 -30
- package/es/components/vef-error-page/index.js +0 -1
- package/es/components/vef-login-page/index.js +0 -1
- package/es/components/vef-not-found-page/index.js +0 -1
- package/es/components/vef-router-provider/index.js +0 -1
- package/es/constants.js +0 -1
- package/es/helper.js +0 -1
- package/es/index.js +0 -1
- package/es/router.js +0 -1
- package/es/routes/access-denied.js +0 -1
- package/es/routes/index.js +0 -1
- package/es/routes/layout.js +0 -1
- package/es/routes/login.js +0 -1
- package/es/routes/root.js +0 -1
- package/es/store.js +0 -1
- package/lib/api.cjs +0 -1
- package/lib/app.cjs +0 -1
- package/lib/components/index.cjs +0 -1
- package/lib/components/vef-access-denied-page/index.cjs +0 -1
- package/lib/components/vef-access-denied-page/props.cjs +0 -1
- package/lib/components/vef-app/index.cjs +0 -1
- package/lib/components/vef-app/props.cjs +0 -1
- package/lib/components/vef-dev-assistant/index.cjs +0 -30
- package/lib/components/vef-dev-assistant/props.cjs +0 -1
- package/lib/components/vef-error-page/index.cjs +0 -1
- package/lib/components/vef-error-page/props.cjs +0 -1
- package/lib/components/vef-login-page/index.cjs +0 -1
- package/lib/components/vef-login-page/props.cjs +0 -1
- package/lib/components/vef-not-found-page/index.cjs +0 -1
- package/lib/components/vef-not-found-page/props.cjs +0 -1
- package/lib/components/vef-router-provider/index.cjs +0 -1
- package/lib/components/vef-router-provider/props.cjs +0 -1
- package/lib/constants.cjs +0 -1
- package/lib/helper.cjs +0 -1
- package/lib/index.cjs +0 -1
- package/lib/router.cjs +0 -1
- package/lib/routes/access-denied.cjs +0 -1
- package/lib/routes/index.cjs +0 -1
- package/lib/routes/layout.cjs +0 -1
- package/lib/routes/login.cjs +0 -1
- package/lib/routes/root.cjs +0 -1
- package/lib/store.cjs +0 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
5
|
+
var reactRouter = require('@tanstack/react-router');
|
|
6
|
+
var components = require('@vef-framework/components');
|
|
7
|
+
var core = require('@vef-framework/core');
|
|
8
|
+
var shared = require('@vef-framework/shared');
|
|
9
|
+
var lucideReact = require('lucide-react');
|
|
10
|
+
var react = require('react');
|
|
11
|
+
var constants = require('../constants.cjs');
|
|
12
|
+
var helper = require('../helper.cjs');
|
|
13
|
+
var store = require('../store.cjs');
|
|
14
|
+
|
|
15
|
+
"use strict";
|
|
16
|
+
const indexBreadcrumbItem = {
|
|
17
|
+
key: constants.INDEX_PAGE_PATH,
|
|
18
|
+
label: /* @__PURE__ */ jsxRuntime.jsx(components.VefIcon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HomeIcon, {}) })
|
|
19
|
+
};
|
|
20
|
+
function createLayoutRouteOptions({
|
|
21
|
+
title,
|
|
22
|
+
logo,
|
|
23
|
+
getUserDescription
|
|
24
|
+
}) {
|
|
25
|
+
function LayoutComponent() {
|
|
26
|
+
const router = reactRouter.useRouter();
|
|
27
|
+
const navigate = reactRouter.useNavigate();
|
|
28
|
+
const { pathname } = reactRouter.useLocation();
|
|
29
|
+
const [menus, user, routeParentMenusMappings] = store.useAppStore((state) => [state.menus, state.user, state.routeParentMenusMappings]);
|
|
30
|
+
const defaultOpenedMenuKeys = routeParentMenusMappings?.get(pathname)?.[1].map((it) => it.key);
|
|
31
|
+
const breadcrumbItems = react.useMemo(() => {
|
|
32
|
+
const mapping = routeParentMenusMappings?.get(pathname);
|
|
33
|
+
if (!mapping) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const [currentMenu, parentMenus] = mapping;
|
|
37
|
+
return [
|
|
38
|
+
indexBreadcrumbItem,
|
|
39
|
+
...parentMenus.map((menu) => ({
|
|
40
|
+
key: menu.key,
|
|
41
|
+
label: menu.label,
|
|
42
|
+
dropdownItems: menu.children.filter((child) => child.type !== "divider").map((child) => ({
|
|
43
|
+
key: child.key,
|
|
44
|
+
label: child.label
|
|
45
|
+
}))
|
|
46
|
+
})),
|
|
47
|
+
{
|
|
48
|
+
label: currentMenu.label
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
}, [pathname, routeParentMenusMappings]);
|
|
52
|
+
const { logoutApi, fetchAuthenticatedUserApi } = core.useApiContext();
|
|
53
|
+
const { mutate: logout } = logoutApi.useMutation();
|
|
54
|
+
const handleLogout = react.useCallback(async () => {
|
|
55
|
+
await logout();
|
|
56
|
+
await helper.handleClientLogout(router, fetchAuthenticatedUserApi);
|
|
57
|
+
}, [logout, router, fetchAuthenticatedUserApi]);
|
|
58
|
+
const handleMenuSwitch = react.useCallback((menuKey) => {
|
|
59
|
+
navigate({
|
|
60
|
+
to: menuKey
|
|
61
|
+
});
|
|
62
|
+
}, [navigate]);
|
|
63
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
64
|
+
components.VefLayout,
|
|
65
|
+
{
|
|
66
|
+
activeMenuKey: pathname,
|
|
67
|
+
breadcrumbItems,
|
|
68
|
+
defaultOpenedMenuKeys,
|
|
69
|
+
logo,
|
|
70
|
+
menuItems: menus,
|
|
71
|
+
title,
|
|
72
|
+
userAvatar: user?.avatar,
|
|
73
|
+
userDescription: getUserDescription?.(user),
|
|
74
|
+
userGender: user?.gender,
|
|
75
|
+
userName: user?.name,
|
|
76
|
+
onActiveMenuKeyChange: handleMenuSwitch,
|
|
77
|
+
onBreadcrumbClick: handleMenuSwitch,
|
|
78
|
+
onLogout: handleLogout,
|
|
79
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactRouter.Outlet, {})
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
beforeLoad: ({ location }) => {
|
|
85
|
+
const { isAuthenticated, routeParentMenusMappings } = store.useAppStore.getState();
|
|
86
|
+
if (!isAuthenticated) {
|
|
87
|
+
throw reactRouter.redirect({
|
|
88
|
+
to: constants.LOGIN_PAGE_PATH,
|
|
89
|
+
search: {
|
|
90
|
+
redirect: location.href
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (routeParentMenusMappings && !routeParentMenusMappings.has(location.pathname)) {
|
|
95
|
+
throw reactRouter.redirect({
|
|
96
|
+
to: constants.ACCESS_DENIED_PAGE_PATH,
|
|
97
|
+
replace: true
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
loader: async ({ context, location }) => {
|
|
102
|
+
const { fetchAuthenticatedUserApi } = context;
|
|
103
|
+
const {
|
|
104
|
+
menus,
|
|
105
|
+
permissions,
|
|
106
|
+
...user
|
|
107
|
+
} = await fetchAuthenticatedUserApi.fetchQuery();
|
|
108
|
+
const routeParentMenusMappings = Object.freeze(shared.buildRouteParentMenusMappings(menus));
|
|
109
|
+
store.useAppStore.setState({
|
|
110
|
+
user: Object.freeze(user),
|
|
111
|
+
menus: Object.freeze(menus),
|
|
112
|
+
permissions: Object.freeze(new Set(permissions)),
|
|
113
|
+
routeParentMenusMappings
|
|
114
|
+
});
|
|
115
|
+
if (!routeParentMenusMappings.has(location.pathname)) {
|
|
116
|
+
throw reactRouter.redirect({
|
|
117
|
+
to: constants.ACCESS_DENIED_PAGE_PATH,
|
|
118
|
+
replace: true
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
pendingComponent: () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
123
|
+
components.VefLoadingPlaceholder,
|
|
124
|
+
{
|
|
125
|
+
size: "large",
|
|
126
|
+
tip: "系统加载中,请稍后..."
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
component: LayoutComponent,
|
|
130
|
+
staleTime: Infinity,
|
|
131
|
+
gcTime: 0,
|
|
132
|
+
shouldReload: false
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
exports.createLayoutRouteOptions = createLayoutRouteOptions;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
5
|
+
var reactRouter = require('@tanstack/react-router');
|
|
6
|
+
var shared = require('@vef-framework/shared');
|
|
7
|
+
require('../components/index.cjs');
|
|
8
|
+
var constants = require('../constants.cjs');
|
|
9
|
+
var store = require('../store.cjs');
|
|
10
|
+
var index = require('../components/vef-login-page/index.cjs');
|
|
11
|
+
|
|
12
|
+
"use strict";
|
|
13
|
+
function createLoginRouteOptions(props) {
|
|
14
|
+
return {
|
|
15
|
+
validateSearch: shared.z.object({
|
|
16
|
+
redirect: shared.z.string().optional().default(constants.INDEX_PAGE_PATH).catch(constants.INDEX_PAGE_PATH)
|
|
17
|
+
}),
|
|
18
|
+
beforeLoad: ({ search }) => {
|
|
19
|
+
if (store.useAppStore.getState().isAuthenticated) {
|
|
20
|
+
const { redirect: redirectPath } = search;
|
|
21
|
+
throw reactRouter.redirect({
|
|
22
|
+
to: redirectPath,
|
|
23
|
+
replace: true
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
component: () => /* @__PURE__ */ jsxRuntime.jsx(index.default, { ...props })
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exports.createLoginRouteOptions = createLoginRouteOptions;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
5
|
+
var reactRouter = require('@tanstack/react-router');
|
|
6
|
+
require('../components/index.cjs');
|
|
7
|
+
var index = require('../components/vef-not-found-page/index.cjs');
|
|
8
|
+
var index$1 = require('../components/vef-error-page/index.cjs');
|
|
9
|
+
var index$2 = require('../components/vef-dev-assistant/index.cjs');
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
function createRootRoute() {
|
|
13
|
+
return reactRouter.createRootRouteWithContext()({
|
|
14
|
+
component: () => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactRouter.Outlet, {}),
|
|
16
|
+
process.env.NODE_ENV === "development" && /* @__PURE__ */ jsxRuntime.jsx(index$2.default, {})
|
|
17
|
+
] }),
|
|
18
|
+
errorComponent: index$1.default,
|
|
19
|
+
notFoundComponent: index.default,
|
|
20
|
+
ssr: false
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
exports.createRootRoute = createRootRoute;
|
package/cjs/store.cjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var shared = require('@vef-framework/shared');
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
const useAppStore = shared.createStore(
|
|
8
|
+
() => ({
|
|
9
|
+
isAuthenticated: false
|
|
10
|
+
}),
|
|
11
|
+
{
|
|
12
|
+
name: "APP",
|
|
13
|
+
storage: "session",
|
|
14
|
+
selector: (state) => ({
|
|
15
|
+
isAuthenticated: state.isAuthenticated,
|
|
16
|
+
token: state.token
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
exports.useAppStore = useAppStore;
|
package/esm/api.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { createApiClient as createApiClient$1 } from '@vef-framework/core';
|
|
3
|
+
import { useAppStore } from './store.js';
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
function createApiClient(options) {
|
|
7
|
+
return createApiClient$1({
|
|
8
|
+
...options,
|
|
9
|
+
getAccessToken() {
|
|
10
|
+
return useAppStore.getState().token?.accessToken;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { createApiClient };
|
package/esm/app.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import './components/index.js';
|
|
5
|
+
import VefApp from './components/vef-app/index.js';
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
function createApp() {
|
|
9
|
+
const root = createRoot(
|
|
10
|
+
document.getElementById("root"),
|
|
11
|
+
{
|
|
12
|
+
identifierPrefix: "vef-"
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
return {
|
|
16
|
+
render: (props) => {
|
|
17
|
+
root.render(
|
|
18
|
+
createElement(VefApp, props)
|
|
19
|
+
);
|
|
20
|
+
},
|
|
21
|
+
unmount: () => root.unmount()
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { createApp };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export { default as VefAccessDeniedPage } from './vef-access-denied-page/index.js';
|
|
3
|
+
export { default as VefApp } from './vef-app/index.js';
|
|
4
|
+
export { default as VefDevAssistant } from './vef-dev-assistant/index.js';
|
|
5
|
+
export { default as VefErrorPage } from './vef-error-page/index.js';
|
|
6
|
+
export { default as VefLoginPage } from './vef-login-page/index.js';
|
|
7
|
+
export { default as VefNotFoundPage } from './vef-not-found-page/index.js';
|
|
8
|
+
export { default as VefRouterProvider } from './vef-router-provider/index.js';
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { useLocation, useRouterState, useNavigate } from '@tanstack/react-router';
|
|
4
|
+
import { VefAccessDenied } from '@vef-framework/components';
|
|
5
|
+
import { useCallback } from 'react';
|
|
6
|
+
import { INDEX_PAGE_PATH } from '../../constants.js';
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
function VefAccessDeniedPage(props) {
|
|
10
|
+
const { pathname } = useLocation();
|
|
11
|
+
const { redirect } = useRouterState();
|
|
12
|
+
const navigate = useNavigate();
|
|
13
|
+
const handleNavigateHome = useCallback(
|
|
14
|
+
() => navigate({
|
|
15
|
+
to: INDEX_PAGE_PATH,
|
|
16
|
+
replace: true
|
|
17
|
+
}),
|
|
18
|
+
[navigate]
|
|
19
|
+
);
|
|
20
|
+
return /* @__PURE__ */ jsx(VefAccessDenied, { uri: redirect?._fromLocation?.pathname ?? pathname, onNavigateHome: handleNavigateHome, ...props });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { VefAccessDeniedPage as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { VefConfigProvider } from '@vef-framework/components';
|
|
4
|
+
import { StrictMode } from 'react';
|
|
5
|
+
import VefRouterProvider from '../vef-router-provider/index.js';
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
function VefApp({
|
|
9
|
+
router,
|
|
10
|
+
...configProviderProps
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(VefConfigProvider, { ...configProviderProps, children: /* @__PURE__ */ jsx(VefRouterProvider, { router }) }) });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { VefApp as default };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsxs, jsx, Fragment } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { css } from '@emotion/react';
|
|
4
|
+
import { VefFloatButtonGroup, VefFloatButton, VefIcon, VefLoadingPlaceholder } from '@vef-framework/components';
|
|
5
|
+
import { useKeyPress } from '@vef-framework/hooks';
|
|
6
|
+
import { themeVariables, noop } from '@vef-framework/shared';
|
|
7
|
+
import { CompassIcon, SendIcon } from 'lucide-react';
|
|
8
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
9
|
+
import { lazy, useState, useCallback, Suspense } from 'react';
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
const devtoolsContainerStyle = css`
|
|
13
|
+
position: fixed;
|
|
14
|
+
bottom: 0;
|
|
15
|
+
width: 100%;
|
|
16
|
+
height: 600px;
|
|
17
|
+
z-index: 2;
|
|
18
|
+
|
|
19
|
+
.tsqd-text-logo-container {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.TanStackRouterDevtoolsPanel {
|
|
24
|
+
> button {
|
|
25
|
+
display: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
> div:first-of-type {
|
|
29
|
+
> div:first-of-type {
|
|
30
|
+
display: none;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
> div {
|
|
35
|
+
padding: ${themeVariables.paddingSm};
|
|
36
|
+
scrollbar-width: thin;
|
|
37
|
+
scrollbar-color: #334155 transparent;
|
|
38
|
+
box-shadow: ${themeVariables.boxShadowDrawerDown};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
function IconCoffee(props) {
|
|
43
|
+
return /* @__PURE__ */ jsxs("svg", { height: 24, viewBox: "0 0 24 24", width: 24, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
|
|
44
|
+
/* @__PURE__ */ jsx("path", { d: "M17 14v4c0 1.66 -1.34 3 -3 3h-6c-1.66 0 -3 -1.34 -3 -3v-4Z", fill: "currentColor", fillOpacity: 0, children: /* @__PURE__ */ jsx("animate", { attributeName: "fill-opacity", begin: "0.8s", dur: "0.5s", fill: "freeze", values: "0;1" }) }),
|
|
45
|
+
/* @__PURE__ */ jsxs("g", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, children: [
|
|
46
|
+
/* @__PURE__ */ jsx("path", { d: "M17 9v9c0 1.66 -1.34 3 -3 3h-6c-1.66 0 -3 -1.34 -3 -3v-9Z", strokeDasharray: 48, strokeDashoffset: 48, children: /* @__PURE__ */ jsx("animate", { attributeName: "stroke-dashoffset", dur: "0.6s", fill: "freeze", values: "48;0" }) }),
|
|
47
|
+
/* @__PURE__ */ jsx("path", { d: "M17 9h3c0.55 0 1 0.45 1 1v3c0 0.55 -0.45 1 -1 1h-3", strokeDasharray: 14, strokeDashoffset: 14, children: /* @__PURE__ */ jsx("animate", { attributeName: "stroke-dashoffset", begin: "0.6s", dur: "0.2s", fill: "freeze", values: "14;0" }) }),
|
|
48
|
+
/* @__PURE__ */ jsx("mask", { id: "lineMdCoffeeHalfEmptyFilledLoop0", children: /* @__PURE__ */ jsx("path", { d: "M8 0c0 2-2 2-2 4s2 2 2 4-2 2-2 4 2 2 2 4M12 0c0 2-2 2-2 4s2 2 2 4-2 2-2 4 2 2 2 4M16 0c0 2-2 2-2 4s2 2 2 4-2 2-2 4 2 2 2 4", stroke: "#fff", children: /* @__PURE__ */ jsx("animateMotion", { calcMode: "linear", dur: "3s", path: "M0 0v-8", repeatCount: "indefinite" }) }) }),
|
|
49
|
+
/* @__PURE__ */ jsxs("rect", { fill: "currentColor", height: 0, mask: "url(#lineMdCoffeeHalfEmptyFilledLoop0)", width: 24, y: 7, children: [
|
|
50
|
+
/* @__PURE__ */ jsx("animate", { attributeName: "y", begin: "0.8s", dur: "0.6s", fill: "freeze", values: "7;2" }),
|
|
51
|
+
/* @__PURE__ */ jsx("animate", { attributeName: "height", begin: "0.8s", dur: "0.6s", fill: "freeze", values: "0;5" })
|
|
52
|
+
] })
|
|
53
|
+
] })
|
|
54
|
+
] });
|
|
55
|
+
}
|
|
56
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
57
|
+
const RouterDevtools = isDev ? lazy(() => import('@tanstack/router-devtools').then((mod) => ({
|
|
58
|
+
default: mod.TanStackRouterDevtoolsPanel
|
|
59
|
+
}))) : () => null;
|
|
60
|
+
const QueryDevtools = isDev ? lazy(() => import('@tanstack/react-query-devtools').then((mod) => ({
|
|
61
|
+
default: mod.ReactQueryDevtoolsPanel
|
|
62
|
+
}))) : () => null;
|
|
63
|
+
const variants = {
|
|
64
|
+
opened: {
|
|
65
|
+
opacity: 1,
|
|
66
|
+
y: 0,
|
|
67
|
+
transition: {
|
|
68
|
+
type: "spring",
|
|
69
|
+
bounce: 0,
|
|
70
|
+
duration: 0.2
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
closed: {
|
|
74
|
+
opacity: 0,
|
|
75
|
+
y: "50%"
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function VefDevAssistant() {
|
|
79
|
+
const [visibleDevtools, setVisibleDevtools] = useState(null);
|
|
80
|
+
const handleShowQueryDevtools = useCallback((event) => {
|
|
81
|
+
event.stopPropagation();
|
|
82
|
+
setVisibleDevtools((visible) => visible === "query" ? null : "query");
|
|
83
|
+
}, []);
|
|
84
|
+
const handleShowRouterDevtools = useCallback((event) => {
|
|
85
|
+
event.stopPropagation();
|
|
86
|
+
setVisibleDevtools((visible) => visible === "router" ? null : "router");
|
|
87
|
+
}, []);
|
|
88
|
+
useKeyPress("esc", () => {
|
|
89
|
+
if (visibleDevtools) {
|
|
90
|
+
setVisibleDevtools(null);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
94
|
+
/* @__PURE__ */ jsxs(
|
|
95
|
+
VefFloatButtonGroup,
|
|
96
|
+
{
|
|
97
|
+
collapsable: true,
|
|
98
|
+
shape: "square",
|
|
99
|
+
icon: /* @__PURE__ */ jsx(VefIcon, { size: "huge", children: /* @__PURE__ */ jsx(IconCoffee, {}) }),
|
|
100
|
+
onClick: (event) => event.stopPropagation(),
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ jsx(
|
|
103
|
+
VefFloatButton,
|
|
104
|
+
{
|
|
105
|
+
tip: "API调试控制台",
|
|
106
|
+
icon: /* @__PURE__ */ jsx(VefIcon, { children: /* @__PURE__ */ jsx(CompassIcon, {}) }),
|
|
107
|
+
onClick: handleShowQueryDevtools
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsx(
|
|
111
|
+
VefFloatButton,
|
|
112
|
+
{
|
|
113
|
+
tip: "路由调试控制台",
|
|
114
|
+
icon: /* @__PURE__ */ jsx(VefIcon, { children: /* @__PURE__ */ jsx(SendIcon, {}) }),
|
|
115
|
+
onClick: handleShowRouterDevtools
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
/* @__PURE__ */ jsxs(AnimatePresence, { mode: "wait", children: [
|
|
122
|
+
visibleDevtools === "query" && /* @__PURE__ */ jsx(
|
|
123
|
+
motion.div,
|
|
124
|
+
{
|
|
125
|
+
animate: "opened",
|
|
126
|
+
css: devtoolsContainerStyle,
|
|
127
|
+
exit: "closed",
|
|
128
|
+
initial: "closed",
|
|
129
|
+
variants,
|
|
130
|
+
children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(VefLoadingPlaceholder, {}), children: /* @__PURE__ */ jsx(QueryDevtools, { style: { height: "100%" } }) })
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
visibleDevtools === "router" && /* @__PURE__ */ jsx(
|
|
134
|
+
motion.div,
|
|
135
|
+
{
|
|
136
|
+
animate: "opened",
|
|
137
|
+
css: devtoolsContainerStyle,
|
|
138
|
+
exit: "closed",
|
|
139
|
+
initial: "closed",
|
|
140
|
+
variants,
|
|
141
|
+
children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(VefLoadingPlaceholder, {}), children: /* @__PURE__ */ jsx(
|
|
142
|
+
RouterDevtools,
|
|
143
|
+
{
|
|
144
|
+
isOpen: visibleDevtools === "router",
|
|
145
|
+
setIsOpen: noop,
|
|
146
|
+
style: { height: "100%" }
|
|
147
|
+
}
|
|
148
|
+
) })
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
] })
|
|
152
|
+
] });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { VefDevAssistant as default };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { VefError } from '@vef-framework/components';
|
|
4
|
+
import { useQueryErrorResetBoundary } from '@vef-framework/core';
|
|
5
|
+
import { useEffect } from 'react';
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
function VefErrorPage({
|
|
9
|
+
error,
|
|
10
|
+
info,
|
|
11
|
+
reset
|
|
12
|
+
}) {
|
|
13
|
+
const { reset: resetQueryError } = useQueryErrorResetBoundary();
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
resetQueryError();
|
|
16
|
+
}, [resetQueryError]);
|
|
17
|
+
return /* @__PURE__ */ jsx(VefError, { componentStack: info?.componentStack, error, reset });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { VefErrorPage as default };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { useRouter, useNavigate, useSearch } from '@tanstack/react-router';
|
|
4
|
+
import { VefLogin } from '@vef-framework/components';
|
|
5
|
+
import { LOGIN_PAGE_ROUTE } from '../../constants.js';
|
|
6
|
+
import { useAppStore } from '../../store.js';
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
function VefLoginPage(props) {
|
|
10
|
+
const router = useRouter();
|
|
11
|
+
const navigate = useNavigate();
|
|
12
|
+
const { redirect } = useSearch({
|
|
13
|
+
from: LOGIN_PAGE_ROUTE
|
|
14
|
+
});
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
VefLogin,
|
|
17
|
+
{
|
|
18
|
+
onLoginSuccess: async ({ accessToken, refreshToken }) => {
|
|
19
|
+
useAppStore.setState({
|
|
20
|
+
isAuthenticated: true,
|
|
21
|
+
token: Object.freeze({
|
|
22
|
+
accessToken,
|
|
23
|
+
refreshToken
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
await router.invalidate();
|
|
27
|
+
await navigate({
|
|
28
|
+
to: redirect,
|
|
29
|
+
replace: true
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
...props
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { VefLoginPage as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { useNavigate, useLocation } from '@tanstack/react-router';
|
|
4
|
+
import { VefNotFound } from '@vef-framework/components';
|
|
5
|
+
import { useCallback } from 'react';
|
|
6
|
+
import { INDEX_PAGE_PATH } from '../../constants.js';
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
function VefNotFoundPage() {
|
|
10
|
+
const navigate = useNavigate();
|
|
11
|
+
const handleNavigateHome = useCallback(
|
|
12
|
+
() => navigate({
|
|
13
|
+
to: INDEX_PAGE_PATH,
|
|
14
|
+
replace: true
|
|
15
|
+
}),
|
|
16
|
+
[navigate]
|
|
17
|
+
);
|
|
18
|
+
const { pathname } = useLocation();
|
|
19
|
+
return /* @__PURE__ */ jsx(VefNotFound, { uri: pathname, onNavigateHome: handleNavigateHome });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { VefNotFoundPage as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
3
|
+
import { RouterProvider } from '@tanstack/react-router';
|
|
4
|
+
import { useApiContext } from '@vef-framework/core';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
function VefRouterProvider({
|
|
9
|
+
router
|
|
10
|
+
}) {
|
|
11
|
+
const { fetchAuthenticatedUserApi } = useApiContext();
|
|
12
|
+
const context = useMemo(() => ({
|
|
13
|
+
fetchAuthenticatedUserApi
|
|
14
|
+
}), [fetchAuthenticatedUserApi]);
|
|
15
|
+
return /* @__PURE__ */ jsx(RouterProvider, { context, router });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { VefRouterProvider as default };
|
package/esm/constants.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use strict";
|
|
3
|
+
const LOGIN_PAGE_PATH = "/login";
|
|
4
|
+
const LOGIN_PAGE_ROUTE = "/_common/login";
|
|
5
|
+
const INDEX_PAGE_PATH = "/";
|
|
6
|
+
const INDEX_PAGE_ROUTE = "/_layout";
|
|
7
|
+
const ACCESS_DENIED_PAGE_PATH = "/access-denied";
|
|
8
|
+
const ACCESS_DENIED_PAGE_ROUTE = "/_common/access-denied";
|
|
9
|
+
|
|
10
|
+
export { ACCESS_DENIED_PAGE_PATH, ACCESS_DENIED_PAGE_ROUTE, INDEX_PAGE_PATH, INDEX_PAGE_ROUTE, LOGIN_PAGE_PATH, LOGIN_PAGE_ROUTE };
|
package/esm/helper.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { LOGIN_PAGE_PATH } from './constants.js';
|
|
3
|
+
import { useAppStore } from './store.js';
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
async function handleClientLogout(router, fetchAuthenticatedUserApi) {
|
|
7
|
+
await fetchAuthenticatedUserApi.invalidateQueries();
|
|
8
|
+
useAppStore.setState(
|
|
9
|
+
{
|
|
10
|
+
isAuthenticated: false
|
|
11
|
+
},
|
|
12
|
+
true
|
|
13
|
+
);
|
|
14
|
+
await router.invalidate();
|
|
15
|
+
await router.navigate({
|
|
16
|
+
to: LOGIN_PAGE_PATH
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { handleClientLogout };
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export { createApiClient } from './api.js';
|
|
3
|
+
export { createApp } from './app.js';
|
|
4
|
+
import './components/index.js';
|
|
5
|
+
export { ACCESS_DENIED_PAGE_PATH, ACCESS_DENIED_PAGE_ROUTE, INDEX_PAGE_PATH, INDEX_PAGE_ROUTE, LOGIN_PAGE_PATH, LOGIN_PAGE_ROUTE } from './constants.js';
|
|
6
|
+
export { handleClientLogout } from './helper.js';
|
|
7
|
+
export { createRouter } from './router.js';
|
|
8
|
+
import './routes/index.js';
|
|
9
|
+
export { useAppStore } from './store.js';
|
|
10
|
+
export { default as VefAccessDeniedPage } from './components/vef-access-denied-page/index.js';
|
|
11
|
+
export { default as VefApp } from './components/vef-app/index.js';
|
|
12
|
+
export { default as VefDevAssistant } from './components/vef-dev-assistant/index.js';
|
|
13
|
+
export { default as VefErrorPage } from './components/vef-error-page/index.js';
|
|
14
|
+
export { default as VefLoginPage } from './components/vef-login-page/index.js';
|
|
15
|
+
export { default as VefNotFoundPage } from './components/vef-not-found-page/index.js';
|
|
16
|
+
export { default as VefRouterProvider } from './components/vef-router-provider/index.js';
|
|
17
|
+
export { createAccessDeniedRouteOptions } from './routes/access-denied.js';
|
|
18
|
+
export { createLayoutRouteOptions } from './routes/layout.js';
|
|
19
|
+
export { createLoginRouteOptions } from './routes/login.js';
|
|
20
|
+
export { createRootRoute } from './routes/root.js';
|
|
21
|
+
|
|
22
|
+
"use strict";
|