test tank

This commit is contained in:
2026-01-28 03:12:53 +08:00
parent b394175079
commit 78fd9fcda0
71 changed files with 2744 additions and 1435 deletions

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/user/_index')({
beforeLoad: () => {
throw redirect({
to: '/user/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -33,7 +33,7 @@
"@stackblitz/sdk": "^1.11.0",
"@tailwindcss/vite": "^4.1.18",
"@uiw/react-textarea-code-editor": "^3.1.1",
"antd": "^6.2.1",
"antd": "^6.2.2",
"clsx": "^2.1.1",
"copy-to-clipboard": "^3.3.3",
"dayjs": "^1.11.19",
@@ -46,28 +46,31 @@
"marked": "^17.0.1",
"nanoid": "^5.1.6",
"qrcode": "^1.5.4",
"react": "19.2.3",
"react-dom": "19.2.3",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-dropzone": "^14.3.8",
"react-hook-form": "^7.71.1",
"react-i18next": "^16.5.3",
"react-resizable-panels": "^4.4.1",
"react-router": "^7.12.0",
"react-router-dom": "^7.12.0",
"react-i18next": "^16.5.4",
"react-resizable-panels": "^4.5.2",
"react-router": "^7.13.0",
"react-router-dom": "^7.13.0",
"react-toastify": "^11.0.5",
"vite-plugin-tsconfig-paths": "^1.4.1",
"zustand": "^5.0.10"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@kevisual/router": "^0.0.60",
"@kevisual/router": "^0.0.63",
"@kevisual/ssl": "^0.0.1",
"@tanstack/react-router": "^1.157.16",
"@tanstack/react-router-devtools": "^1.157.16",
"@tanstack/router-plugin": "^1.157.16",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
"@types/node": "^25.0.10",
"@types/path-browserify": "^1.0.3",
"@types/qrcode": "^1.5.6",
"@types/react": "^19.2.9",
"@types/react": "^19.2.10",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-basic-ssl": "^2.1.4",
"@vitejs/plugin-react": "^5.1.2",
@@ -76,19 +79,19 @@
"eslint": "^9.39.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26",
"globals": "^17.0.0",
"lucide-react": "^0.562.0",
"globals": "^17.2.0",
"lucide-react": "^0.563.0",
"path-browserify": "^1.0.1",
"postcss-import": "^16.1.1",
"pretty-bytes": "^7.1.0",
"react-is": "19.2.3",
"react-is": "19.2.4",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.18",
"tailwindcss-animate": "^1.0.7",
"turbo": "^2.7.5",
"turbo": "^2.7.6",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"typescript-eslint": "^8.54.0",
"vite": "^7.3.1"
},
"packageManager": "pnpm@10.28.1"
"packageManager": "pnpm@10.28.2"
}

1953
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,52 +1,50 @@
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
// import { App as ContainerApp } from './pages/container';
import { App as UserAppApp } from './pages/app';
import { App as HomeApp } from './pages/home';
import { RouterProvider, createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import { useTheme, theme } from '@kevisual/components/theme/index.tsx'
import { ToastContainer } from 'react-toastify'
import { useEffect, useState } from 'react'
import 'dayjs/locale/zh-cn'
import 'dayjs/locale/en'
import zhCN from 'antd/locale/zh_CN'
import enUS from 'antd/locale/en_US'
import ConfigProvider from 'antd/es/config-provider'
import { useTranslation } from 'react-i18next'
import React from 'react'
import { ThemeProvider } from '@mui/material'
// import { App as MapApp } from './pages/map';
// import { App as UserApp } from './pages/user';
// import { App as FileApp } from './pages/file';
// import { App as OrgApp } from './pages/org';
// import { App as ConfigApp } from './pages/config';
// import { App as DomainApp } from './pages/domain';
// Set up a Router instance
const router = createRouter({
routeTree,
defaultPreload: 'intent',
scrollRestoration: true,
})
import { basename } from './modules/basename';
import { Redirect } from './modules/Redirect';
import { useTheme, theme } from '@kevisual/components/theme/index.tsx';
import { ToastContainer } from 'react-toastify';
import { lazy, Suspense } from 'react';
import 'dayjs/locale/zh-cn';
import 'dayjs/locale/en';
import zhCN from 'antd/locale/zh_CN';
import enUS from 'antd/locale/en_US';
import ConfigProvider from 'antd/es/config-provider';
import { useTranslation } from 'react-i18next';
import React, { useEffect, useState } from 'react';
import { ThemeProvider } from '@mui/material';
const ContainerApp = lazy(() => import('./pages/container'));
const MapApp = lazy(() => import('./pages/map'));
const UserApp = lazy(() => import('./pages/user'));
const FileApp = lazy(() => import('./pages/file'));
const OrgApp = lazy(() => import('./pages/org'));
const ConfigApp = lazy(() => import('./pages/config'));
const DomainApp = lazy(() => import('./pages/domain'));
// Register things for typesafety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
const CustomThemeProvider2 = ({ children }: { children: React.ReactNode }) => {
return <ThemeProvider theme={theme}>{children}</ThemeProvider>
}
export const CustomThemeProvider2 = ({ children }: { children: React.ReactNode }) => {
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
};
const AntProvider = ({ children }: { children: React.ReactNode }) => {
const theme = useTheme();
const primaryColor = theme.palette.primary.main;
const secondaryColor = theme.palette.secondary.main;
const { i18n } = useTranslation();
const [locale, setLocale] = useState(zhCN);
const themeContext = useTheme()
const primaryColor = themeContext.palette.primary.main
const secondaryColor = themeContext.palette.secondary.main
const { i18n } = useTranslation()
const [locale, setLocale] = useState(zhCN)
useEffect(() => {
if (i18n.language === 'en') {
setLocale(enUS);
setLocale(enUS)
} else {
setLocale(zhCN);
setLocale(zhCN)
}
}, [i18n.language]);
}, [i18n.language])
return (
<ConfigProvider
locale={locale}
@@ -75,42 +73,20 @@ const AntProvider = ({ children }: { children: React.ReactNode }) => {
}}>
{children}
</ConfigProvider>
);
};
export const App = () => {
)
}
const App = () => {
return (
<CustomThemeProvider2>
<AntProvider>
<div className='w-full h-full'>
<Router basename={basename}>
<Routes>
<Route path='/' element={<Redirect to='/app/' />} />
<Route
path='/container/*'
element={
<Suspense fallback={'loading container'}>
<ContainerApp />
</Suspense>
}
/>
<Route path='/map/*' element={<MapApp />} />
<Route path='/user-center/*' element={<UserApp />} />
<Route path='/user/*' element={<UserApp />} />
<Route path='/org/*' element={<OrgApp />} />
<Route path='/config/*' element={<ConfigApp />} />
<Route path='/app/*' element={<UserAppApp />} />
<Route path='/file/*' element={<FileApp />} />
<Route path='/domain/*' element={<DomainApp />} />
{/* <Route path='/home/*' element={<HomeApp />} /> */}
<Route path='/404' element={<div>404</div>} />
<Route path='*' element={<div>404</div>} />
</Routes>
</Router>
</div>
<RouterProvider router={router} />
</AntProvider>
<div id='for-drawer'></div>
<div id='for-modal'></div>
<ToastContainer />
</CustomThemeProvider2>
);
};
)
}
export default App

View File

@@ -1,13 +1,24 @@
import { createRoot } from 'react-dom/client';
import { App } from './App.tsx';
import { RouterProvider, createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import './globals.css';
import { Suspense } from 'react';
import { I18NextProvider } from '@kevisual/components/translate/I18Next.tsx';
// Set up a Router instance
const router = createRouter({
routeTree,
defaultPreload: 'intent',
scrollRestoration: true,
})
// Register things for typesafety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
createRoot(document.getElementById('root')!).render(
<I18NextProvider basename={!DEV_SERVER ? '/root/locales' : '/'}>
<Suspense fallback={<div>Loading...</div>}>
<App />
</Suspense>
<RouterProvider router={router} />
</I18NextProvider>,
);

View File

@@ -1,6 +1,5 @@
import { basename } from './basename';
import { Navigate } from 'react-router-dom';
import { redirect } from '@tanstack/react-router';
export const Redirect = (({ to }) => {
return <Navigate to={`${to}`} />;
}) as any as typeof Navigate;
export const Redirect = ({ to }: { to: string }) => {
throw redirect({ to });
};

View File

@@ -1,4 +1,3 @@
import { useShallow } from 'zustand/react/shallow';
import { useLayoutStore } from './store';
import clsx from 'clsx';
import { Menu, MenuItem, Tooltip } from '@mui/material';
@@ -14,19 +13,14 @@ import { useTranslation } from 'react-i18next';
import React from 'react';
export const LayoutUser = () => {
const { open, setOpen, isAdmin, ...store } = useLayoutStore(
useShallow((state) => ({
open: state.openUser, //
setOpen: state.setOpenUser,
me: state.me,
switchOrg: state.switchOrg,
isAdmin: state.isAdmin,
})),
);
const menuStore = useLayoutStore();
const navigate = useNewNavigate();
const { t } = useTranslation();
const { openUser, setOpenUser, me, switchOrg, isAdmin } = menuStore;
const items = useMemo(() => {
const orgs = store.me?.orgs || [];
const orgs = me?.orgs || [];
return orgs.map((item) => {
return {
label: item,
@@ -34,9 +28,10 @@ export const LayoutUser = () => {
icon: <SmileOutlined />,
};
});
}, [store.me]);
}, [me]);
const menu = useMemo(() => {
const orgs = store.me?.orgs || [];
const orgs = me?.orgs || [];
const hasOrg = orgs.length > 0;
const items = [
{
@@ -71,7 +66,8 @@ export const LayoutUser = () => {
}
return true;
});
}, [store.me]);
}, [me]);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
@@ -82,16 +78,16 @@ export const LayoutUser = () => {
};
return (
<div className={clsx('w-full h-full absolute z-20 no-drag text-primary', !open && 'hidden')}>
<div className={clsx('w-full h-full absolute z-20 no-drag text-primary', !openUser && 'hidden')}>
<div
className='w-full absolute h-full opacity-60 z-0'
onClick={() => {
setOpen(false);
setOpenUser(false);
}}></div>
<div className='w-[400px] bg-amber-900 transition-all duration-300 h-full absolute top-0 right-0 rounded-l-lg'>
<div className='flex justify-between p-6 mt-4 font-bold items-center border-b'>
<div className='flex items-center gap-2'>
{t('User')}: <span className='text-primary'>{store.me?.username}</span>
{t('User')}: <span className='text-primary'>{me?.username}</span>
</div>
<div className='flex gap-4'>
{items.length > 0 && (
@@ -102,7 +98,7 @@ export const LayoutUser = () => {
</Tooltip>
)}
<Button onClick={() => setOpen(false)}>
<Button onClick={() => setOpenUser(false)}>
<X />
</Button>
</div>
@@ -116,7 +112,7 @@ export const LayoutUser = () => {
onClick={() => {
if (item.link) {
navigate(item.link);
setOpen(false);
setOpenUser(false);
} else {
message.info('Coming soon');
}
@@ -131,7 +127,6 @@ export const LayoutUser = () => {
className='flex items-center p-4 hover:bg-secondary hover:text-white cursor-pointer'
onClick={async () => {
const res = await queryLogin.logout();
// console.log(res);
if (res.success) {
window.open('/user/login', '_self');
} else {
@@ -150,7 +145,7 @@ export const LayoutUser = () => {
<MenuItem
key={index}
onClick={() => {
store.switchOrg(item.key, 'org');
switchOrg(item.key, 'org');
handleClose();
}}>
<div className='mr-4'>{item.icon}</div>

View File

@@ -1,4 +1,3 @@
import { useShallow } from 'zustand/react/shallow';
import { useLayoutStore } from './store';
import clsx from 'clsx';
import { Button } from '@mui/material';
@@ -13,6 +12,7 @@ import { X, Settings } from 'lucide-react';
import { useNewNavigate } from '../navicate';
import { useTranslation } from 'react-i18next';
import { Map } from 'lucide-react';
export const useQuickMenu = () => {
const { t } = useTranslation();
return [
@@ -33,8 +33,12 @@ export const useQuickMenu = () => {
},
];
};
export const LayoutMenu = () => {
const { t } = useTranslation();
const menuStore = useLayoutStore();
const navigate = useNewNavigate();
const meun = [
{
title: t('Home'),
@@ -63,8 +67,9 @@ export const LayoutMenu = () => {
icon: <SmileOutlined />,
},
];
const { open, setOpen } = useLayoutStore(useShallow((state) => ({ open: state.open, setOpen: state.setOpen })));
const navigate = useNewNavigate();
const { open, setOpen } = menuStore;
return (
<div className={clsx('w-full h-full text-primary absolute z-20 no-drag', !open && 'hidden')}>
<div

View File

@@ -1,9 +1,8 @@
import { MenuOutlined, SwapOutlined } from '@ant-design/icons';
import { Tooltip } from '@mui/material';
import { Outlet, useNavigate } from 'react-router-dom';
import { Outlet, useNavigate } from '@tanstack/react-router';
import { LayoutMenu, useQuickMenu } from './Menu';
import { useLayoutStore, usePlatformStore } from './store';
import { useShallow } from 'zustand/react/shallow';
import { useEffect, useLayoutEffect, useState } from 'react';
import { LayoutUser } from './LayoutUser';
import { PandaPNG } from '@/assets/index.tsx';
@@ -25,29 +24,11 @@ type LayoutMainProps = {
children?: React.ReactNode;
};
export const LayoutMain = (props: LayoutMainProps) => {
const menuStore = useLayoutStore(
useShallow((state) => {
return {
open: state.open,
setOpen: state.setOpen, //
getMe: state.getMe,
me: state.me,
setOpenUser: state.setOpenUser,
switchOrg: state.switchOrg,
};
}),
);
const platformStore = usePlatformStore(
useShallow((state) => {
return {
isMac: state.isMac,
mount: state.mount,
isElectron: state.isElectron,
init: state.init,
};
}),
);
const { isMac, mount, isElectron } = platformStore;
const menuStore = useLayoutStore();
const platformStore = usePlatformStore();
const isMac = platformStore.isMac;
const mount = platformStore.mount;
const isElectron = platformStore.isElectron;
const navigate = useNavigate();
const quickMenu = useQuickMenu();

View File

@@ -1,14 +1,12 @@
import { NavigateFunction, To, useNavigate } from 'react-router-dom';
import { basename } from './basename';
import { To, useNavigate } from '@tanstack/react-router';
/**
* 如果有basepath刚好给path加上basepath
* @returns NavigateFunction
*/
export const useNewNavigate = (): NavigateFunction => {
export const useNewNavigate = () => {
const navigate = useNavigate();
const fn = (path: To, data?: any) => {
// navigate(basename + '/' + path, data);
navigate(path, data);
};
return fn as NavigateFunction;
return fn;
};

View File

@@ -3,25 +3,22 @@ import { Folder } from 'lucide-react';
import { Button } from '@mui/material';
import { useLayoutStore } from '@/modules/layout/store';
import { useShallow } from 'zustand/shallow';
import { toast } from 'react-toastify';
type Props = {
pathname?: string;
};
export const AIEditorLink = (props: Props) => {
const layoutUser = useLayoutStore(
useShallow((state) => ({
user: state.me?.username || '',
})),
);
const layoutStore = useLayoutStore();
const { me } = layoutStore;
const username = me?.username || '';
return (
<Tooltip title={'打开对应的文件夹'}>
<Button
onClick={() => {
if (!layoutUser.user) {
if (!username) {
toast.error('请先登录');
}
let folder = `${layoutUser.user}/resources/${props.pathname}`;
let folder = `${username}/resources/${props.pathname}`;
if (folder.endsWith('/')) {
folder = folder.slice(0, -1);
}

View File

@@ -1,6 +1,5 @@
import { useNavigation, useParams } from 'react-router';
import { useAppVersionStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { useCallback, useEffect, useMemo, useState } from 'react';
import CloudUploadOutlined from '@ant-design/icons/CloudUploadOutlined';
import DeleteOutlined from '@ant-design/icons/DeleteOutlined';
@@ -28,45 +27,37 @@ import { AIEditorLink } from './AIEditorLink';
const FormModal = () => {
const { t } = useTranslation();
const { control, handleSubmit, reset } = useForm();
const containerStore = useAppVersionStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
};
}),
);
const versionStore = useAppVersionStore();
const { showEdit, setShowEdit, formData, updateData } = versionStore;
useEffect(() => {
const open = containerStore.showEdit;
const open = showEdit;
if (open) {
const isNull = isObjectNull(containerStore.formData);
const isNull = isObjectNull(formData);
if (isNull) {
reset({});
} else {
reset(containerStore.formData);
reset(formData);
}
}
}, [containerStore.showEdit]);
}, [showEdit]);
const onFinish = async (values: any) => {
const pickValues = pick(values, ['id', 'key', 'version']);
containerStore.updateData(pickValues);
updateData(pickValues);
};
const onClose = () => {
containerStore.setShowEdit(false);
setShowEdit(false);
reset();
};
const isEdit = containerStore.formData.id;
const isEdit = formData.id;
return (
<Dialog
open={containerStore.showEdit}
onClose={() => containerStore.setShowEdit(false)}
open={showEdit}
onClose={() => setShowEdit(false)}
sx={{
'& .MuiDialog-paper': {
width: '800px',
@@ -94,48 +85,29 @@ const FormModal = () => {
export const AppVersionList = () => {
const params = useParams();
const appKey = params.appKey;
const versionStore = useAppVersionStore(
useShallow((state) => {
return {
list: state.list,
getList: state.getList,
key: state.key,
setKey: state.setKey,
setShowEdit: state.setShowEdit,
formData: state.formData,
setFormData: state.setFormData,
deleteData: state.deleteData,
publishVersion: state.publishVersion,
app: state.app,
};
}),
);
const appDeleteModalStore = useAppDeleteModalStore(
useShallow((state) => {
return {
onClickDelete: state.onClickDelete,
};
}),
);
const versionStore = useAppVersionStore();
const { list, getList, key, setKey, setShowEdit, formData, setFormData, deleteData, publishVersion, app } = versionStore;
const appDeleteModalStore = useAppDeleteModalStore();
const { onClickDelete } = appDeleteModalStore;
const navigate = useNewNavigate();
const [isUpload, setIsUpload] = useState(false);
useEffect(() => {
// fetch app version list
if (appKey) {
versionStore.setKey(appKey);
versionStore.getList();
setKey(appKey);
getList();
}
}, [appKey]);
const appVersion = useMemo(() => {
return versionStore.app?.version || '';
}, [versionStore.app?.version]);
return app?.version || '';
}, [app?.version]);
return (
<div className='w-full h-full flex bg-slate-100'>
<div className='p-2 bg-white'>
<IconButton
onClick={() => {
versionStore.setFormData({ key: appKey });
versionStore.setShowEdit(true);
setFormData({ key: appKey });
setShowEdit(true);
}}>
<PlusOutlined />
</IconButton>
@@ -185,7 +157,7 @@ export const AppVersionList = () => {
<Tooltip title='Delete'>
<Button
onClick={(e) => {
appDeleteModalStore.onClickDelete('app-version', item);
onClickDelete('app-version', item);
e.stopPropagation();
}}>
<DeleteOutlined />
@@ -194,7 +166,7 @@ export const AppVersionList = () => {
<Tooltip title='使用当前版本,发布为此版本'>
<Button
onClick={() => {
versionStore.publishVersion({ id: item.id });
publishVersion({ id: item.id });
}}>
<CloudUploadOutlined />
</Button>
@@ -243,7 +215,7 @@ export const AppVersionList = () => {
<LeftOutlined />
</IconButton>
</Tooltip>
<div className='font-bold'>{versionStore.key}</div>
<div className='font-bold'>{key}</div>
</div>
<AppVersionFile />
</div>
@@ -255,28 +227,22 @@ export const AppVersionList = () => {
);
};
export const AppVersionFile = () => {
const versionStore = useAppVersionStore(
useShallow((state) => {
return {
formData: state.formData,
detectVersionList: state.detectVersionList,
};
}),
);
const versionStore = useAppVersionStore();
const { formData, detectVersionList } = versionStore;
const versionFiles = useMemo(() => {
if (!versionStore.formData?.data) return [];
const files = versionStore.formData.data.files || [];
return files;
}, [versionStore.formData]);
const onDetect = useCallback(async () => {
console.log('formData', versionStore.formData);
if (!versionStore.formData.key || !versionStore.formData.version) {
console.log('formData', formData);
if (!formData.key || !formData.version) {
toast.error('请先选择应用和版本');
return;
}
const res = await versionStore.detectVersionList({
appKey: versionStore.formData.key,
version: versionStore.formData.version,
const res = await detectVersionList({
appKey: formData.key,
version: formData.version,
});
console.log('res', res);
if (res.code === 200) {
@@ -284,11 +250,11 @@ export const AppVersionFile = () => {
} else {
toast.error(res.message || 'Detect failed');
}
}, [versionStore.formData]);
}, [formData]);
const { t } = useTranslation();
return (
<>
<div>version: {versionStore.formData.version}</div>
<div>version: {formData.version}</div>
<div className='border border-gray-200 rounded-md my-2 grow overflow-hidden'>
<div className='flex gap-2 items-center border-b border-b-gray-200 py-2 px-2'>
Files
@@ -304,7 +270,7 @@ export const AppVersionFile = () => {
}}>
<div className='h-full overflow-auto mb-4 pb-8 scrollbar'>
{versionFiles.map((file, index) => {
const prefix = versionStore.formData.key + '/' + versionStore.formData.version + '/';
const prefix = formData.key + '/' + formData.version + '/';
const _path = file.path || '';
const path = _path.replace(prefix, '');
return (

View File

@@ -1,4 +1,3 @@
import { useShallow } from 'zustand/react/shallow';
import { useAppVersionStore, useUserAppStore } from '../store';
import { useEffect, useMemo, useState } from 'react';
import { useModal } from '@kevisual/components/modal/Confirm.tsx';
@@ -42,44 +41,37 @@ const FormModal = () => {
const { control, handleSubmit, reset } = useForm({
defaultValues,
});
const containerStore = useUserAppStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
userApp: state.userApp,
updateData: state.updateData,
};
}),
);
const userAppStore = useUserAppStore();
const { showEdit, setShowEdit, userApp, updateData } = userAppStore;
useEffect(() => {
const open = containerStore.showEdit;
const open = showEdit;
if (open) {
const isNull = isObjectNull(containerStore.userApp);
const isNull = isObjectNull(userApp);
if (isNull) {
reset(defaultValues);
} else {
reset(containerStore.userApp);
reset(userApp);
}
}
}, [containerStore.showEdit, containerStore.userApp]);
}, [showEdit, userApp]);
const onFinish = async (values: any) => {
const pickValues = pick(values, ['id', 'title', 'domain', 'key', 'description', 'proxy', 'status']);
containerStore.updateData(pickValues);
updateData(pickValues);
};
const onClose = () => {
containerStore.setShowEdit(false);
setShowEdit(false);
reset();
};
const isEdit = containerStore?.userApp?.id;
const isEdit = userApp?.id;
const theme = useTheme();
const defaultProps = theme.components?.MuiTextField?.defaultProps as any;
const isAdmin = useLayoutStore(useShallow((state) => state.isAdmin));
const layoutStore = useLayoutStore();
const { isAdmin } = layoutStore;
return (
<Dialog
open={containerStore.showEdit}
onClose={() => containerStore.setShowEdit(false)}
open={showEdit}
onClose={() => setShowEdit(false)}
sx={{
'& .MuiDialog-paper': {
width: '1000px',
@@ -134,51 +126,44 @@ const FormModal = () => {
const ShareModal = () => {
const [permission, setPermission] = useState<any>(null);
const [runtime, setRuntime] = useState<string[]>([]);
const containerStore = useUserAppStore(
useShallow((state) => {
return {
showEdit: state.showShareEdit,
setShowEdit: state.setShowShareEdit,
updateData: state.updateData,
userApp: state.userApp,
};
}),
);
const userAppStore = useUserAppStore();
const { showShareEdit, setShowShareEdit, updateData, userApp } = userAppStore;
useEffect(() => {
const open = containerStore.showEdit;
const open = showShareEdit;
if (open) {
const permission = containerStore.userApp?.data?.permission || {};
const runtime = containerStore.userApp?.data?.runtime || [];
if (isObjectNull(permission)) {
const perm = userApp?.data?.permission || {};
const run = userApp?.data?.runtime || [];
if (isObjectNull(perm)) {
setPermission({ share: 'private' });
} else {
setPermission(permission);
setPermission(perm);
}
setRuntime(runtime);
setRuntime(run);
}
}, [containerStore.showEdit, containerStore.userApp]);
}, [showShareEdit, userApp]);
const onFinish = async () => {
const values = {
id: containerStore.userApp.id,
id: userApp.id,
data: {
permission,
runtime,
},
};
containerStore.updateData(values);
updateData(values);
};
const onClose = () => {
containerStore.setShowEdit(false);
setShowShareEdit(false);
};
const { t } = useTranslation();
const theme = useTheme();
const defaultProps = theme.components?.MuiTextField?.defaultProps as any;
const isAdmin = useLayoutStore(useShallow((state) => state.isAdmin));
const layoutStore = useLayoutStore();
const { isAdmin } = layoutStore;
return (
<Dialog
open={containerStore.showEdit}
open={showShareEdit}
onClose={() => {
containerStore.setShowEdit(false);
setShowShareEdit(false);
}}>
<DialogTitle>{t('app.share')}</DialogTitle>
<DialogContent>
@@ -236,37 +221,15 @@ const ShareModal = () => {
export const List = () => {
const [modal, contextHolder] = useModal();
const { t } = useTranslation();
const userAppStore = useUserAppStore(
useShallow((state) => {
return {
list: state.list,
getList: state.getList,
setShowEdit: state.setShowEdit,
formData: state.formData,
setFormData: state.setFormData,
deleteData: state.deleteData,
setShowShareEdit: state.setShowShareEdit,
getUserApp: state.getUserApp,
};
}),
);
const appVersionStore = useAppVersionStore(
useShallow((state) => {
return {
publishVersion: state.publishVersion,
};
}),
);
const appDeleteModalStore = useAppDeleteModalStore(
useShallow((state) => {
return {
onClickDelete: state.onClickDelete,
};
}),
);
const userAppStore = useUserAppStore();
const { list, getList, setShowEdit, formData, setFormData, deleteData, setShowShareEdit, getUserApp } = userAppStore;
const appVersionStore = useAppVersionStore();
const { publishVersion } = appVersionStore;
const appDeleteModalStore = useAppDeleteModalStore();
const { onClickDelete } = appDeleteModalStore;
const navicate = useNewNavigate();
useEffect(() => {
userAppStore.getList();
getList();
}, []);
return (
<div className='w-full h-full flex bg-slate-100'>
@@ -277,8 +240,8 @@ export const List = () => {
padding: '8px',
}}
onClick={() => {
userAppStore.setFormData({});
userAppStore.setShowEdit(true);
setFormData({});
setShowEdit(true);
}}>
<PlusOutlined />
</IconButton>
@@ -369,9 +332,9 @@ export const List = () => {
<Tooltip title={'Edit'}>
<Button
onClick={() => {
userAppStore.getUserApp(item.id);
userAppStore.setFormData(item);
userAppStore.setShowEdit(true);
getUserApp(item.id);
setFormData(item);
setShowEdit(true);
}}>
<Edit size={16} />
</Button>
@@ -387,9 +350,9 @@ export const List = () => {
<Tooltip title={iText.share.tips}>
<Button
onClick={() => {
userAppStore.getUserApp(item.id);
userAppStore.setFormData(item);
userAppStore.setShowShareEdit(true);
getUserApp(item.id);
setFormData(item);
setShowShareEdit(true);
}}>
<Share2 size={16} />
</Button>
@@ -397,7 +360,7 @@ export const List = () => {
<Tooltip title={'reload'}>
<Button
onClick={() => {
appVersionStore.publishVersion({ appKey: item.key, version: item.version }, { showToast: false });
publishVersion({ appKey: item.key, version: item.version }, { showToast: false });
}}>
<RefreshCcw size={16} />
</Button>
@@ -438,7 +401,7 @@ export const List = () => {
<Tooltip title={'Delete'}>
<Button
onClick={(e) => {
appDeleteModalStore.onClickDelete('user-app', item);
onClickDelete('user-app', item);
e.stopPropagation();
}}>
<Trash size={16} />

View File

@@ -1,18 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { Main } from './layouts';
import { List } from './edit/List';
import { AppVersionList } from './edit/AppVersionList';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/app/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
<Route path='/:appKey/version/list' element={<AppVersionList />} />
</Route>
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -3,7 +3,6 @@ import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { create } from 'zustand';
import { useAppVersionStore, useUserAppStore } from '../store';
import { useShallow } from 'zustand/shallow';
type AppDeleteModalStore = {
open: boolean;
@@ -29,28 +28,18 @@ export const useAppDeleteModalStore = create<AppDeleteModalStore>((set) => ({
export const AppDeleteModal = () => {
const { t } = useTranslation();
const { open, setOpen, app, type, setType } = useAppDeleteModalStore();
const userAppStore = useUserAppStore(
useShallow((state) => {
return {
deleteData: state.deleteData,
};
}),
);
const appVersionStore = useAppVersionStore(
useShallow((state) => {
return {
deleteData: state.deleteData,
};
}),
);
const userAppStore = useUserAppStore();
const { deleteData: deleteUserAppData } = userAppStore;
const appVersionStore = useAppVersionStore();
const { deleteData: deleteVersionData } = appVersionStore;
const onClose = () => {
setOpen(false);
};
const onDelete = (deleteFile = false) => {
if (type === 'user-app') {
userAppStore.deleteData(app.id, deleteFile);
deleteUserAppData(app.id, deleteFile);
} else {
appVersionStore.deleteData(app.id, deleteFile);
deleteVersionData(app.id, deleteFile);
}
setOpen(false);
};

View File

@@ -1,7 +1,6 @@
import { Button } from '@mui/material';
import { useCallback, useRef } from 'react';
import { useAppVersionStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { message } from '@/modules/message';
import { useTranslation } from 'react-i18next';
export type FileType = {
@@ -14,15 +13,8 @@ export type FileType = {
export const FileUpload = () => {
const ref = useRef<HTMLInputElement | null>(null);
const { t } = useTranslation();
const appVersionStore = useAppVersionStore(
useShallow((state) => {
return {
formData: state.formData,
setFormData: state.setFormData,
updateByFromData: state.updateByFromData,
};
}),
);
const versionStore = useAppVersionStore();
const { formData, setFormData, updateByFromData } = versionStore;
const onChange = useCallback(
async (e) => {
console.log(e.target.files);
@@ -57,8 +49,8 @@ export const FileUpload = () => {
const webkitRelativePath = file.webkitRelativePath.replace(root + '/', '');
formData.append('file', file, webkitRelativePath); // 保留文件夹路径
});
const key = appVersionStore.formData.key;
const version = appVersionStore.formData.version;
const key = formData.key;
const version = formData.version;
formData.append('appKey', key);
formData.append('version', version);
const res = await fetch('/api/app/upload', {
@@ -69,15 +61,15 @@ export const FileUpload = () => {
},
}).then((res) => res.json());
if (res?.code === 200) {
appVersionStore.setFormData(res.data);
appVersionStore.updateByFromData();
setFormData(res.data);
updateByFromData();
} else {
message.error(res.message || 'Request failed');
}
// 清理之前上传的文件
e.target.value = '';
},
[appVersionStore.formData],
[formData],
);
return (
@@ -93,8 +85,8 @@ export const FileUpload = () => {
/>
<Button
onClick={() => {
const key = appVersionStore.formData.key;
const version = appVersionStore.formData.version;
const key = formData.key;
const version = formData.version;
if (!key || !version) {
message.error('请先选择应用和版本');
return;

View File

@@ -11,7 +11,6 @@ import { useController } from 'react-hook-form';
import { TextField, TextFieldLabel } from '@kevisual/components/input/TextField.tsx';
import { useTranslation } from 'react-i18next';
import { IconButton } from '@kevisual/components/button/index.tsx';
import { useShallow } from 'zustand/shallow';
import { load, dump } from 'js-yaml';
import CodeEditor from '@uiw/react-textarea-code-editor';
import { toast } from 'react-toastify';
@@ -25,13 +24,8 @@ type DataYamlEditProps = {
type?: 'yaml' | 'json';
};
export const DataYamlEdit = ({ onSave, type }: DataYamlEditProps) => {
const { formData } = useConfigStore(
useShallow((state) => {
return {
formData: state.formData,
};
}),
);
const configStore = useConfigStore();
const { formData } = configStore;
const [yaml, setYaml] = useState(formData.data);
useEffect(() => {
const _fromData = formData.data || {};
@@ -79,16 +73,8 @@ export const DataYamlEdit = ({ onSave, type }: DataYamlEditProps) => {
};
export const DrawerEdit = () => {
const { t } = useTranslation();
const { showEdit, setShowEdit, formData, updateData } = useConfigStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
};
}),
);
const configStore = useConfigStore();
const { showEdit, setShowEdit, formData, updateData } = configStore;
const [tab, setTab] = useState<'base' | 'yaml' | 'json'>('base');
const { control, handleSubmit, reset } = useForm({
@@ -189,9 +175,11 @@ export const DrawerEdit = () => {
};
export const List = () => {
const { list, getConfigList, setShowEdit, setFormData, deleteConfig, updateData, formData, detectConfig, onOpenKey } = useConfigStore();
const configStore = useConfigStore();
const { list, getConfigList, setShowEdit, setFormData, deleteConfig, updateData, formData, detectConfig, onOpenKey } = configStore;
const [modal, contextHolder] = useModal();
const isAdmin = useLayoutStore(useShallow((state) => state.isAdmin));
const layoutStore = useLayoutStore();
const { isAdmin } = layoutStore;
useEffect(() => {
getConfigList();
}, []);

View File

@@ -1,16 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { LayoutMain } from '@/modules/layout';
import { List } from './edit/List.tsx';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<LayoutMain title='Config' />}>
<Route path='/' element={<Redirect to='/config/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
</Route>
</Routes>
);
return <LayoutMain title='Config' />;
};
export default App;

View File

@@ -1,6 +1,5 @@
import { Fragment, Suspense, useEffect, useState } from 'react';
import { useContainerStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
// import copy from 'copy-to-clipboard';
import { useNewNavigate } from '@/modules';
import { message } from '@/modules/message';
@@ -26,45 +25,37 @@ const DrawEdit = React.lazy(() => import('../module/DrawEdit'));
const FormModal = () => {
const { control, handleSubmit, reset, setValue } = useForm();
const containerStore = useContainerStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
};
}),
);
const containerStore = useContainerStore();
const { showEdit, setShowEdit, formData, updateData } = containerStore;
useEffect(() => {
const open = containerStore.showEdit;
const open = showEdit;
if (open) {
const isNull = isObjectNull(containerStore.formData);
const isNull = isObjectNull(formData);
if (isNull) {
reset({});
} else {
Object.keys(containerStore.formData).forEach((key) => {
setValue(key, containerStore.formData[key]);
Object.keys(formData).forEach((key) => {
setValue(key, formData[key]);
});
}
}
return () => {
reset({});
};
}, [containerStore.showEdit]);
}, [showEdit]);
const onFinish = async (values: any) => {
const pickValues = pick(values, ['id', 'title', 'description', 'tags', 'code']);
containerStore.updateData(pickValues);
updateData(pickValues);
};
const onClose = () => {
containerStore.setShowEdit(false);
setShowEdit(false);
reset();
};
const isEdit = containerStore.formData.id;
const isEdit = formData.id;
const { t } = useTranslation();
return (
<Dialog open={containerStore.showEdit} onClose={onClose}>
@@ -105,35 +96,27 @@ const FormModal = () => {
const PublishFormModal = () => {
const { control, handleSubmit, reset, setValue, getValues } = useForm();
const { t } = useTranslation();
const containerStore = useContainerStore(
useShallow((state) => {
return {
showEdit: state.showPublish,
setShowEdit: state.setShowPublish,
formData: state.formData,
updateData: state.updateData,
};
}),
);
const containerStore = useContainerStore();
const { showPublish, setShowPublish, formData, updateData } = containerStore;
useEffect(() => {
const open = containerStore.showEdit;
const open = showPublish;
if (open) {
const isNull = isObjectNull(containerStore.formData);
const isNull = isObjectNull(formData);
if (isNull) {
reset({});
} else {
Object.keys(containerStore.formData).forEach((key) => {
setValue(key, containerStore.formData[key]);
Object.keys(formData).forEach((key) => {
setValue(key, formData[key]);
});
}
}
}, [containerStore.showEdit]);
}, [showPublish]);
const onFinish = async () => {
const values = getValues();
const pickValues = pick(values, ['id', 'publish.key', 'publish.version', 'publish.fileName', 'publish.description']);
const containerRes = await containerStore.updateData(pickValues, { closePublish: false });
const containerRes = await updateData(pickValues, { closePublish: false });
if (containerRes.code === 200) {
const code = containerRes.data?.code || '-';
const fileName = values['publish']?.['fileName'];
@@ -167,16 +150,16 @@ const PublishFormModal = () => {
const onUpdate = async () => {
const values = getValues();
containerStore.updateData(values);
updateData(values);
};
const onClose = () => {
containerStore.setShowEdit(false);
setShowPublish(false);
reset();
};
return (
<Dialog open={containerStore.showEdit} onClose={onClose}>
<Dialog open={showPublish} onClose={onClose}>
<DialogTitle>Publish</DialogTitle>
<DialogContent sx={{ padding: '10px', minWidth: '600px' }}>
<form className='flex flex-col gap-6 pt-2' onSubmit={handleSubmit(onFinish)}>
@@ -224,28 +207,11 @@ const PublishFormModal = () => {
};
export const ContainerList = () => {
const [modal, contextHolder] = useModal();
const containerStore = useContainerStore(
useShallow((state) => {
return {
setFormData: state.setFormData,
setShowEdit: state.setShowEdit,
list: state.list,
deleteData: state.deleteData,
getList: state.getList,
loading: state.loading,
// publishData: state.publishData,
setShowPublish: state.setShowPublish,
updateData: state.updateData,
formData: state.formData,
getOne: state.getOne,
setOpenDrawEdit: state.setOpenDrawEdit,
openDrawEdit: state.openDrawEdit,
};
}),
);
const containerStore = useContainerStore();
const { setFormData, setShowEdit, list, deleteData, getList, loading, setShowPublish, updateData, formData, getOne, setOpenDrawEdit, openDrawEdit } = containerStore;
useEffect(() => {
containerStore.getList();
getList();
}, []);
const onAdd = () => {
@@ -302,9 +268,9 @@ export const ContainerList = () => {
<Tooltip title='编辑代码'>
<Button
onClick={(e) => {
containerStore.getOne(item.id);
containerStore.setFormData(item);
containerStore.setOpenDrawEdit(true);
getOne(item.id);
setFormData(item);
setOpenDrawEdit(true);
e.stopPropagation();
}}>
<Settings size={16} />
@@ -313,8 +279,8 @@ export const ContainerList = () => {
<Tooltip title='编辑'>
<Button
onClick={(e) => {
containerStore.setFormData(item);
containerStore.setShowEdit(true);
setFormData(item);
setShowEdit(true);
e.stopPropagation();
}}>
<EditOutlined />
@@ -323,9 +289,8 @@ export const ContainerList = () => {
<Tooltip title='添加到 user app当中'>
<Button
onClick={(e) => {
// containerStore.publishData(item);
containerStore.setFormData(item);
containerStore.setShowPublish(true);
setFormData(item);
setShowPublish(true);
e.stopPropagation();
}}>
<CloudUploadOutlined />
@@ -340,7 +305,7 @@ export const ContainerList = () => {
title: 'Delete',
content: 'Are you sure delete this data?',
onOk: () => {
containerStore.deleteData(item.id);
deleteData(item.id);
},
});
e.stopPropagation();

View File

@@ -1,19 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { ContainerList } from './edit/List';
import { Main } from './layouts';
import { Preview, PreviewWrapper } from './preview';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/container/edit/list' />}></Route>
<Route path='edit/list' element={<ContainerList />} />
<Route path='preview/:id/wrapper' element={<PreviewWrapper />} />
</Route>
<Route path='preview/:id' element={<Preview />} />
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -1,6 +1,5 @@
import { lazy, useEffect, useRef, useState } from 'react';
import { Box, Drawer } from '@mui/material';
import { useShallow } from 'zustand/shallow';
import { useContainerStore } from '../store';
import { Tooltip } from '@mui/material';
import { IconButton } from '@kevisual/components/button/index.tsx';
@@ -12,17 +11,8 @@ import { BaseEditor } from '@kevisual/codemirror/editor/editor.ts';
export const DrawEdit = () => {
const editorElRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<BaseEditor>(null);
const containerStore = useContainerStore(
useShallow((state) => {
return {
openDrawEdit: state.openDrawEdit,
setOpenDrawEdit: state.setOpenDrawEdit,
data: state.data,
updateData: state.updateData,
};
}),
);
const { openDrawEdit, setOpenDrawEdit } = containerStore;
const containerStore = useContainerStore();
const { openDrawEdit, setOpenDrawEdit, data, updateData } = containerStore;
const [mount, setMount] = useState(false);
useEffect(() => {
if (openDrawEdit && editorElRef.current && !mount) {
@@ -95,7 +85,7 @@ export const DrawEdit = () => {
}}
onClick={() => {
const code = editorRef.current?.getContent();
containerStore.updateData({ id: containerStore.data.id, code }, { refresh: false });
updateData({ id: data.id, code }, { refresh: false });
}}>
<SaveOutlined />
</IconButton>
@@ -114,7 +104,7 @@ export const DrawEdit = () => {
</IconButton>
</Tooltip> */}
</div>
<div className='flex-1 ml-2 flex items-center'>{containerStore.data?.title}</div>
<div className='flex-1 ml-2 flex items-center'>{data?.title}</div>
</div>
</div>
<Box

View File

@@ -1,16 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { Main } from './layouts';
import { List } from './edit/List';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/domain/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
</Route>
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -1,4 +1,3 @@
import { useShallow } from 'zustand/react/shallow';
import { useFileStore } from '../store';
import { useEffect, useMemo, useRef, useState } from 'react';
import path from 'path-browserify';
@@ -17,16 +16,8 @@ import { useTranslation } from 'react-i18next';
import { UploadButton } from '@kevisual/resources/pages/upload/index.tsx';
import { DialogDirectory, DialogDeleteDirectory } from '@kevisual/resources/pages/upload/DialogDirectory.tsx';
export const CardPath = ({ children }: any) => {
const userAppStore = useFileStore(
useShallow((state) => {
return {
list: state.list,
getList: state.getList,
setPath: state.setPath,
path: state.path,
};
}),
);
const fileStore = useFileStore();
const { list, getList, setPath, path } = fileStore;
const [dialogDirectory, setDialogDirectory] = useState(false);
const [dialogDeleteDirectory, setDialogDeleteDirectory] = useState(false);
const paths = ['root', ...userAppStore.path.split('/').filter((item) => item)];
@@ -163,29 +154,10 @@ export const CardPath = ({ children }: any) => {
export const List = () => {
const [tab, setTab] = useState<'folder' | 'upload'>('folder');
const uploadRef = useRef<HTMLDivElement>(null);
const { setOpenDrawer, setPrefix, setResource, getStatFile, setOnce } = useResourceFileStore(
useShallow((state) => {
return {
setOpenDrawer: state.setOpenDrawer,
setPrefix: state.setPrefix,
setResource: state.setResource,
getStatFile: state.getStatFile,
setOnce: state.setOnce,
};
}),
);
const userAppStore = useFileStore(
useShallow((state) => {
return {
list: state.list,
getList: state.getList,
setPath: state.setPath,
path: state.path,
getFile: state.getFile,
file: state.file,
};
}),
);
const resourceFileStore = useResourceFileStore();
const { setOpenDrawer, setPrefix, setResource, getStatFile, setOnce } = resourceFileStore;
const fileStore = useFileStore();
const { list, getList, setPath, path, getFile, file } = fileStore;
useEffect(() => {
userAppStore.getList();
return () => {
@@ -201,9 +173,9 @@ export const List = () => {
<>
<CardPath>
<div className='flex flex-col'>
{userAppStore.list.map((item, index) => {
{fileStore.list.map((item, index) => {
if (item.prefix) {
let showPrefix = item.prefix.replace(userAppStore.path, '');
let showPrefix = item.prefix.replace(path, '');
showPrefix = showPrefix.replace('/', '');
return (
<div

View File

@@ -1,16 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { Main } from './layouts';
import { List } from './edit/List';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/file/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
</Route>
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -9,16 +9,14 @@ import { useDropzone } from 'react-dropzone';
import { CacheWorkspace } from '@kevisual/cache';
import { useHomeStore } from './store/index.ts';
import { UploadModal } from './module/UploadModal.tsx';
import { useShallow } from 'zustand/shallow';
import { toast } from 'react-toastify';
import { SuccessModal } from './module/SuccessModal.tsx';
export const Home = () => {
const editorElRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<BaseEditor>(null);
const { initApp, setOpenUploadModal, setText, filename } = useHomeStore(
useShallow((state) => ({ initApp: state.initApp, setOpenUploadModal: state.setOpenUploadModal, setText: state.setText, filename: state.filename })),
);
const homeStore = useHomeStore();
const { initApp, setOpenUploadModal, setText, filename } = homeStore;
const onDrop = (acceptedFiles) => {
console.log(acceptedFiles);
const file = acceptedFiles[0];

View File

@@ -1,14 +1,12 @@
import { Route, Routes } from 'react-router-dom';
import { Main } from './layouts';
import { Home } from './Home';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Home />}></Route>
</Route>
</Routes>
<Main>
<Home />
</Main>
);
};
export default App;
export default App;

View File

@@ -1,5 +1,5 @@
import { LayoutMain } from '@/modules/layout';
export const Main = () => {
return <LayoutMain title='Home' />;
export const Main = ({ children }: { children?: React.ReactNode }) => {
return <LayoutMain title='Home'>{children}</LayoutMain>;
};

View File

@@ -1,5 +1,4 @@
import { Dialog, DialogContent, DialogTitle } from '@mui/material';
import { useShallow } from 'zustand/shallow';
import { useHomeStore } from '../store';
import { useMemo } from 'react';
import { useLayoutStore } from '@/modules/layout/store';
@@ -12,16 +11,10 @@ export const Label = ({ label, children }: { label: string; children: React.Reac
);
};
export const SuccessModal = () => {
const { openSuccessModal, setOpenSuccessModal, appKey, version, filename } = useHomeStore(
useShallow((state) => ({
openSuccessModal: state.openSuccessModal,
setOpenSuccessModal: state.setOpenSuccessModal,
appKey: state.appKey, //
version: state.version, //
filename: state.filename, //
})),
);
const { me } = useLayoutStore(useShallow((state) => ({ me: state.me })));
const homeStore = useHomeStore();
const { openSuccessModal, setOpenSuccessModal, appKey, version, filename } = homeStore;
const layoutStore = useLayoutStore();
const { me } = layoutStore;
const link = useMemo(() => {
const _currentHref = new URL(window.location.href);
const username = me?.username;

View File

@@ -8,14 +8,15 @@ import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { uploadFile } from './upload-file';
import { useAppVersionStore } from '@/pages/app/store';
import { useShallow } from 'zustand/shallow';
import { RefreshCcw } from 'lucide-react';
export const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
export const UploadModal = () => {
const { appKey, version, filename, openUploadModal, text, setOpenUploadModal, setAppKey, setVersion, setFilename, setOpenSuccessModal } = useHomeStore();
const homeStore = useHomeStore();
const { appKey, version, filename, openUploadModal, text, setOpenUploadModal, setAppKey, setVersion, setFilename, setOpenSuccessModal } = homeStore;
const { control, handleSubmit, reset, setValue } = useForm();
const { publishVersion } = useAppVersionStore(useShallow((state) => ({ publishVersion: state.publishVersion })));
const appVersionStore = useAppVersionStore();
const { publishVersion } = appVersionStore;
useEffect(() => {
if (openUploadModal) {
reset({ appKey: appKey || randomAppKey(), version: version || '1.0.0', filename: filename || 'index.html' });

View File

@@ -2,20 +2,13 @@ import clsx from 'clsx';
import { useNewNavigate } from '@/modules';
import { useTranslation } from 'react-i18next';
import { useLayoutStore } from '@/modules/layout/store';
import { useShallow } from 'zustand/shallow';
import { useMemo } from 'react';
const ServerPath = () => {
const navigate = useNewNavigate();
const { t } = useTranslation();
const layoutStore = useLayoutStore(
useShallow((state) => {
return {
isAdmin: state.isAdmin,
checkHasOrg: state.checkHasOrg,
};
}),
);
const layoutStore = useLayoutStore();
const { isAdmin, checkHasOrg } = layoutStore;
const serverPath = [
{
path: 'container',

View File

@@ -1,6 +1,5 @@
import { Fragment, useEffect, useState } from 'react';
import { useOrgStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { useNewNavigate } from '@/modules';
import { useTranslation } from 'react-i18next';
import { Tooltip, Button, ButtonGroup, Dialog, DialogTitle, DialogContent } from '@mui/material';
@@ -24,46 +23,37 @@ import { pick } from 'lodash-es';
const FormModal = () => {
const { t } = useTranslation();
const { control, handleSubmit, reset } = useForm();
const userStore = useOrgStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
setFormData: state.setFormData,
};
}),
);
const orgStore = useOrgStore();
const { showEdit, setShowEdit, formData, updateData, setFormData } = orgStore;
useEffect(() => {
const open = userStore.showEdit;
const open = showEdit;
if (open) {
const isNull = isObjectNull(userStore.formData);
const isNull = isObjectNull(formData);
if (isNull) {
reset({});
} else reset(userStore.formData);
} else reset(formData);
}
return () => {
reset({});
};
}, [userStore.showEdit, userStore.formData, reset]);
}, [showEdit, formData, reset]);
const onFinish = async (values: any) => {
const pickValues = pick(values, ['id', 'username', 'description']);
userStore.updateData(pickValues);
updateData(pickValues);
};
const onClose = () => {
userStore.setShowEdit(false);
setShowEdit(false);
reset({});
userStore.setFormData({});
setFormData({});
};
const isEdit = userStore.formData.id;
const isEdit = formData.id;
return (
<Dialog open={userStore.showEdit} onClose={() => userStore.setShowEdit(false)}>
<Dialog open={showEdit} onClose={() => setShowEdit(false)}>
<DialogTitle>{isEdit ? 'Edit' : 'Add'}</DialogTitle>
<DialogContent sx={{ padding: '20px', minWidth: '600px' }}>
<form onSubmit={handleSubmit(onFinish)}>
@@ -94,30 +84,13 @@ const FormModal = () => {
};
export const List = () => {
const navicate = useNewNavigate();
const userStore = useOrgStore(
useShallow((state) => {
return {
setFormData: state.setFormData,
setShowEdit: state.setShowEdit,
list: state.list,
deleteData: state.deleteData,
getList: state.getList,
loading: state.loading,
updateData: state.updateData,
formData: state.formData,
};
}),
);
const layoutStore = useLayoutStore(
useShallow((state) => {
return {
switchOrg: state.switchOrg,
};
}),
);
const orgStore = useOrgStore();
const { setFormData, setShowEdit, list, deleteData, getList, loading, updateData, formData } = orgStore;
const layoutStore = useLayoutStore();
const { switchOrg } = layoutStore;
const [modal, contextHolder] = useModal();
useEffect(() => {
userStore.getList();
getList();
}, []);
const onAdd = () => {
@@ -166,8 +139,8 @@ export const List = () => {
<Tooltip title={t('Edit')}>
<Button
onClick={(e) => {
userStore.setFormData(item);
userStore.setShowEdit(true);
setFormData(item);
setShowEdit(true);
e.stopPropagation();
}}>
<EditOutlined />

View File

@@ -1,4 +1,3 @@
import { useShallow } from 'zustand/react/shallow';
import { useOrgStore } from '../store';
import { useParams } from 'react-router';
import { useEffect } from 'react';
@@ -19,30 +18,21 @@ import { useForm, Controller } from 'react-hook-form';
const FormModal = () => {
const { control, handleSubmit, reset } = useForm();
const userStore = useOrgStore(
useShallow((state) => {
return {
showEdit: state.showUserEdit,
setShowEdit: state.setShowUserEdit,
formData: state.userFormData,
setFormData: state.setUserFormData,
addUser: state.addUser,
};
}),
);
const orgStore = useOrgStore();
const { showUserEdit, setShowUserEdit, userFormData, setUserFormData, addUser } = orgStore;
useEffect(() => {
const open = userStore.showEdit;
const open = showUserEdit;
if (open) {
const isNull = isObjectNull(userStore.formData);
const isNull = isObjectNull(userFormData);
if (isNull) {
reset({});
} else reset(userStore.formData);
} else reset(userFormData);
}
return () => {
reset({});
};
}, [userStore.showEdit, userStore.formData, reset]);
}, [showUserEdit, userFormData, reset]);
const onFinish = async (values: any) => {
console.log(values);
@@ -52,22 +42,22 @@ const FormModal = () => {
message.error('username is required');
return;
}
const res = await userStore.addUser({ username: username, role });
const res = await addUser({ username: username, role });
if (res?.code === 200) {
userStore.setShowEdit(false);
setShowUserEdit(false);
}
};
const onClose = () => {
userStore.setShowEdit(false);
userStore.setFormData({});
setShowUserEdit(false);
setUserFormData({});
};
const isEdit = userStore.formData.id;
const isEdit = userFormData.id;
const { t } = useTranslation();
return (
<Dialog open={userStore.showEdit} onClose={() => userStore.setShowEdit(false)}>
<Dialog open={showUserEdit} onClose={() => setShowUserEdit(false)}>
<DialogTitle>{isEdit ? 'Edit' : 'Add'}</DialogTitle>
<DialogContent sx={{ padding: '20px', minWidth: '600px' }}>
<form className='flex flex-col gap-6' onSubmit={handleSubmit(onFinish)}>
@@ -111,28 +101,15 @@ export const UserList = () => {
const navicate = useNewNavigate();
const [modal, contextHolder] = useModal();
const { t } = useTranslation();
const orgStore = useOrgStore(
useShallow((state) => {
return {
users: state.users,
org: state.org,
setOrgId: state.setOrgId,
getOrg: state.getOrg,
setShowUserEdit: state.setShowUserEdit,
setUserFormData: state.setUserFormData,
setShowEdit: state.setShowEdit,
removeUser: state.removeUser,
addUser: state.addUser,
};
}),
);
const orgStore = useOrgStore();
const { users, org, setOrgId, getOrg, setShowUserEdit, setUserFormData, setShowEdit, removeUser, addUser } = orgStore;
useEffect(() => {
if (param.id) {
orgStore.setOrgId(param.id);
orgStore.getOrg();
setOrgId(param.id);
getOrg();
}
return () => {
orgStore.setUserFormData({});
setUserFormData({});
};
}, []);
return (
@@ -140,8 +117,8 @@ export const UserList = () => {
<div className='p-2 bg-white mr-2'>
<IconButton
onClick={() => {
orgStore.setUserFormData({});
orgStore.setShowUserEdit(true);
setUserFormData({});
setShowUserEdit(true);
}}>
<PlusOutlined />
</IconButton>
@@ -194,7 +171,7 @@ export const UserList = () => {
title: 'Delete',
content: 'Are you sure?',
onOk: () => {
orgStore.removeUser(item.id);
removeUser(item.id);
},
});
}}>

View File

@@ -1,19 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { List } from './edit/List';
import { Main } from './layouts';
import { UserList } from './edit/UserList';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/org/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
<Route path='edit/user/:id' element={<UserList />} />
</Route>
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -1,6 +1,5 @@
import { Fragment, useEffect, useState } from 'react';
import { useUserStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
import { isObjectNull } from '@/utils/is-null';
import { CardBlank } from '@kevisual/components/card/CardBlank.tsx';
import { Dialog, ButtonGroup, Button, DialogContent, DialogTitle, Tooltip } from '@mui/material';
@@ -15,35 +14,26 @@ import { SquareAsterisk, Edit as EditOutlined, Trash as DeleteOutlined, Plus as
import { toast } from 'react-toastify';
const FormModal = () => {
const { control, handleSubmit, reset } = useForm();
const userStore = useUserStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
setFormData: state.setFormData,
};
}),
);
const adminStore = useAdminStore(useShallow((state) => state));
const userStore = useUserStore();
const { showEdit, setShowEdit, formData, updateData, setFormData } = userStore;
const adminStore = useAdminStore();
useEffect(() => {
const open = userStore.showEdit;
const open = showEdit;
if (open) {
const isNull = isObjectNull(userStore.formData);
const isNull = isObjectNull(formData);
if (isNull) {
reset({});
} else reset(userStore.formData);
} else reset(formData);
}
return () => {
reset({});
};
}, [userStore.showEdit]);
}, [showEdit]);
const onFinish = (values: any) => {
const pickValues = pick(values, ['id', 'username', 'description']);
if (pickValues.id) {
userStore.updateData(pickValues);
updateData(pickValues);
} else {
const newPickValues = pick(values, ['username', 'description', 'password']);
adminStore.createNewUser(newPickValues);
@@ -51,12 +41,12 @@ const FormModal = () => {
};
const onClose = () => {
userStore.setShowEdit(false);
setShowEdit(false);
reset({});
userStore.setFormData({});
setFormData({});
};
const isEdit = userStore.formData.id;
const isEdit = formData.id;
const { t } = useTranslation();
return (
@@ -101,8 +91,8 @@ const FormModal = () => {
};
export const NameModal = () => {
const { control, handleSubmit, reset } = useForm();
const userStore = useUserStore(useShallow((state) => state));
const adminStore = useAdminStore(useShallow((state) => state));
const userStore = useUserStore();
const adminStore = useAdminStore();
const onFinish = async (values: any) => {
const check = await adminStore.checkUserExist(values.username);
if (check === false) {
@@ -147,23 +137,11 @@ export const NameModal = () => {
};
export const List = () => {
const [modal, contextHolder] = useModal();
const userStore = useUserStore(
useShallow((state) => {
return {
setFormData: state.setFormData,
setShowEdit: state.setShowEdit,
setShowNameEdit: state.setShowNameEdit,
list: state.list,
deleteData: state.deleteData,
getList: state.getList,
loading: state.loading,
formData: state.formData,
};
}),
);
const adminStore = useAdminStore(useShallow((state) => state));
const userStore = useUserStore();
const { setFormData, setShowEdit, setShowNameEdit, list, deleteData, getList, loading, formData } = userStore;
const adminStore = useAdminStore();
useEffect(() => {
userStore.getList();
getList();
}, []);
const onAdd = () => {
@@ -209,8 +187,8 @@ export const List = () => {
<Tooltip title='编辑'>
<Button
onClick={(e) => {
userStore.setFormData(item);
userStore.setShowEdit(true);
setFormData(item);
setShowEdit(true);
e.stopPropagation();
}}>
<EditOutlined />
@@ -219,8 +197,8 @@ export const List = () => {
<Tooltip title='修改用户名'>
<Button
onClick={(e) => {
userStore.setFormData(item);
userStore.setShowNameEdit(true);
setFormData(item);
setShowNameEdit(true);
e.stopPropagation();
}}>
<UserPen />
@@ -249,7 +227,7 @@ export const List = () => {
content: 'Are you sure delete this data?',
onOk: async () => {
await adminStore.deleteUser(item.id);
userStore.getList();
getList();
},
});
e.stopPropagation();
@@ -264,7 +242,7 @@ export const List = () => {
);
})}
<CardBlank className='w-[400px]' />
{userStore.list.length == 0 && (
{list.length == 0 && (
<div className='text-center' key={'no-data'}>
No Data
</div>

View File

@@ -3,7 +3,6 @@ import { useForm, Controller } from 'react-hook-form';
import { Button } from '@mui/material';
import { useUserStore } from '../store';
import { useEffect, useRef, useState } from 'react';
import { useShallow } from 'zustand/react/shallow';
import { isObjectNull } from '@/utils/is-null';
import { useLayoutStore } from '@/modules/layout/store';
import UploadOutlined from '@ant-design/icons/UploadOutlined';
@@ -16,23 +15,12 @@ import { useAdminStore } from '../admin/store/admin-store';
import { IconButton } from '@kevisual/components/button/index.tsx';
export const CheckUserExistModal = () => {
const { t } = useTranslation();
const userStore = useUserStore(
useShallow((state) => {
return {
showCheckUserExist: state.showCheckUserExist,
setShowCheckUserExist: state.setShowCheckUserExist,
};
}),
);
const adminStore = useAdminStore(
useShallow((state) => {
return {
checkUserExist: state.checkUserExist,
};
}),
);
const userStore = useUserStore();
const { showCheckUserExist, setShowCheckUserExist } = userStore;
const adminStore = useAdminStore();
const { checkUserExist } = adminStore;
const onClose = () => {
userStore.setShowCheckUserExist(false);
setShowCheckUserExist(false);
};
const [username, setUsername] = useState('@');
@@ -49,7 +37,7 @@ export const CheckUserExistModal = () => {
}
};
return (
<Dialog open={userStore.showCheckUserExist} onClose={onClose}>
<Dialog open={showCheckUserExist} onClose={onClose}>
<DialogTitle>{t('Tips')}</DialogTitle>
<DialogContent>
<div className='flex flex-col pt-4 gap-6 w-[400px]'>
@@ -65,15 +53,8 @@ export const CheckUserExistModal = () => {
};
export const ChangePasswordModal = () => {
const { t } = useTranslation();
const userStore = useUserStore(
useShallow((state) => {
return {
showChangePassword: state.showChangePassword,
setShowChangePassword: state.setShowChangePassword,
updateSelf: state.updateSelf,
};
}),
);
const userStore = useUserStore();
const { showChangePassword, setShowChangePassword, updateSelf } = userStore;
const [newPassword, setNewPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const onSubmit = async () => {
@@ -81,7 +62,7 @@ export const ChangePasswordModal = () => {
toast.error('两次密码不一致');
return;
}
const res = await userStore.updateSelf({
const res = await updateSelf({
password: newPassword,
});
if (res.code === 200) {
@@ -91,10 +72,10 @@ export const ChangePasswordModal = () => {
const onClose = () => {
setNewPassword('');
setConfirmPassword('');
userStore.setShowChangePassword(false);
setShowChangePassword(false);
};
return (
<Dialog open={userStore.showChangePassword} onClose={onClose}>
<Dialog open={showChangePassword} onClose={onClose}>
<DialogTitle>{t('Change Password')}</DialogTitle>
<DialogContent>
<div className='flex flex-col w-[400px] p-4 gap-4 pt-2'>
@@ -124,29 +105,11 @@ export const Profile = () => {
},
});
const ref = useRef<any>(null);
const userStore = useUserStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
setFormData: state.setFormData,
updateSelf: state.updateSelf,
setShowCheckUserExist: state.setShowCheckUserExist,
setShowChangePassword: state.setShowChangePassword,
};
}),
);
const userStore = useUserStore();
const { showEdit, setShowEdit, formData, updateData, setFormData, updateSelf, setShowCheckUserExist, setShowChangePassword } = userStore;
const [avatar, setAvatar] = useState<string>('');
const layoutStore = useLayoutStore(
useShallow((state) => {
return {
me: state.me,
setMe: state.setMe,
};
}),
);
const layoutStore = useLayoutStore();
const { me, setMe } = layoutStore;
useEffect(() => {
const fromData = layoutStore.me;
if (isObjectNull(fromData)) {
@@ -207,7 +170,7 @@ export const Profile = () => {
className='w-4 h-4 cursor-pointer text-primary'
onClick={() => {
console.log('onClick edit');
userStore.setShowCheckUserExist(true);
setShowCheckUserExist(true);
}}
/>
</InputAdornment>
@@ -255,7 +218,7 @@ export const Profile = () => {
</div>
<div className='mt-2'>
<Tooltip title={t('Change Password')}>
<IconButton className='' onClick={() => userStore.setShowChangePassword(true)}>
<IconButton className='' onClick={() => setShowChangePassword(true)}>
<UserCog size={16} />
</IconButton>
</Tooltip>

View File

@@ -1,22 +1,7 @@
import { Route, Routes } from 'react-router-dom';
import { List } from './edit/List';
import { Main } from './layouts';
import { Login } from './login/Login';
import { Login as WxLogin } from './wx/Login';
import { Profile } from './edit/Profile';
import { Redirect } from '@/modules/Redirect';
export const App = () => {
return (
<Routes>
<Route element={<Main />}>
<Route path='/' element={<Redirect to='/user/edit/list' />}></Route>
<Route path='edit/list' element={<List />} />
<Route path='profile' element={<Profile />} />
</Route>
<Route path='login' element={<Login />} />
<Route path='wx/login' element={<WxLogin />} />
</Routes>
);
return <Main />;
};
export default App;

View File

@@ -1,5 +1,4 @@
import { useLoginStore } from '../store/login';
import { useShallow } from 'zustand/react/shallow';
import LockOutlined from '@ant-design/icons/LockOutlined';
import UserOutlined from '@ant-design/icons/UserOutlined';
import { Button } from '@mui/material';
@@ -9,19 +8,12 @@ import { useForm, Controller } from 'react-hook-form';
export const Login = () => {
const { t } = useTranslation();
const { control, handleSubmit } = useForm();
const loginStore = useLoginStore(
useShallow((state) => {
return {
login: state.login,
formData: state.formData,
setFormData: state.setFormData,
};
}),
);
const loginStore = useLoginStore();
const { login, formData, setFormData } = loginStore;
const onFinish = (values: any) => {
loginStore.setFormData(values);
loginStore.login();
setFormData(values);
login();
};
return (

728
src/routeTree.gen.ts Normal file
View File

@@ -0,0 +1,728 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as UserRouteImport } from './routes/user'
import { Route as OrgRouteImport } from './routes/org'
import { Route as MapRouteImport } from './routes/map'
import { Route as HomeRouteImport } from './routes/home'
import { Route as FileRouteImport } from './routes/file'
import { Route as DomainRouteImport } from './routes/domain'
import { Route as ContainerRouteImport } from './routes/container'
import { Route as ConfigRouteImport } from './routes/config'
import { Route as AppRouteImport } from './routes/app'
import { Route as IndexRouteImport } from './routes/index'
import { Route as UserLoginRouteImport } from './routes/user.login'
import { Route as UserIndexRouteImport } from './routes/user._index'
import { Route as OrgIndexRouteImport } from './routes/org._index'
import { Route as FileIndexRouteImport } from './routes/file._index'
import { Route as DomainIndexRouteImport } from './routes/domain._index'
import { Route as ContainerIndexRouteImport } from './routes/container._index'
import { Route as ConfigIndexRouteImport } from './routes/config._index'
import { Route as AppIndexRouteImport } from './routes/app._index'
import { Route as UserWxLoginRouteImport } from './routes/user.wx.login'
import { Route as UserEditProfileRouteImport } from './routes/user.edit.profile'
import { Route as UserEditListRouteImport } from './routes/user.edit.list'
import { Route as OrgEditListRouteImport } from './routes/org.edit.list'
import { Route as FileEditListRouteImport } from './routes/file.edit.list'
import { Route as DomainEditListRouteImport } from './routes/domain.edit.list'
import { Route as ContainerPreviewIdRouteImport } from './routes/container.preview.$id'
import { Route as ContainerEditListRouteImport } from './routes/container.edit.list'
import { Route as ConfigEditListRouteImport } from './routes/config.edit.list'
import { Route as AppEditListRouteImport } from './routes/app.edit.list'
import { Route as OrgEditUserIdRouteImport } from './routes/org.edit.user.$id'
import { Route as ContainerPreviewIdWrapperRouteImport } from './routes/container.preview.$id.wrapper'
import { Route as AppAppKeyVersionListRouteImport } from './routes/app.$appKey.version.list'
const UserRoute = UserRouteImport.update({
id: '/user',
path: '/user',
getParentRoute: () => rootRouteImport,
} as any)
const OrgRoute = OrgRouteImport.update({
id: '/org',
path: '/org',
getParentRoute: () => rootRouteImport,
} as any)
const MapRoute = MapRouteImport.update({
id: '/map',
path: '/map',
getParentRoute: () => rootRouteImport,
} as any)
const HomeRoute = HomeRouteImport.update({
id: '/home',
path: '/home',
getParentRoute: () => rootRouteImport,
} as any)
const FileRoute = FileRouteImport.update({
id: '/file',
path: '/file',
getParentRoute: () => rootRouteImport,
} as any)
const DomainRoute = DomainRouteImport.update({
id: '/domain',
path: '/domain',
getParentRoute: () => rootRouteImport,
} as any)
const ContainerRoute = ContainerRouteImport.update({
id: '/container',
path: '/container',
getParentRoute: () => rootRouteImport,
} as any)
const ConfigRoute = ConfigRouteImport.update({
id: '/config',
path: '/config',
getParentRoute: () => rootRouteImport,
} as any)
const AppRoute = AppRouteImport.update({
id: '/app',
path: '/app',
getParentRoute: () => rootRouteImport,
} as any)
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
const UserLoginRoute = UserLoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => UserRoute,
} as any)
const UserIndexRoute = UserIndexRouteImport.update({
id: '/_index',
getParentRoute: () => UserRoute,
} as any)
const OrgIndexRoute = OrgIndexRouteImport.update({
id: '/_index',
getParentRoute: () => OrgRoute,
} as any)
const FileIndexRoute = FileIndexRouteImport.update({
id: '/_index',
getParentRoute: () => FileRoute,
} as any)
const DomainIndexRoute = DomainIndexRouteImport.update({
id: '/_index',
getParentRoute: () => DomainRoute,
} as any)
const ContainerIndexRoute = ContainerIndexRouteImport.update({
id: '/_index',
getParentRoute: () => ContainerRoute,
} as any)
const ConfigIndexRoute = ConfigIndexRouteImport.update({
id: '/_index',
getParentRoute: () => ConfigRoute,
} as any)
const AppIndexRoute = AppIndexRouteImport.update({
id: '/_index',
getParentRoute: () => AppRoute,
} as any)
const UserWxLoginRoute = UserWxLoginRouteImport.update({
id: '/wx/login',
path: '/wx/login',
getParentRoute: () => UserRoute,
} as any)
const UserEditProfileRoute = UserEditProfileRouteImport.update({
id: '/edit/profile',
path: '/edit/profile',
getParentRoute: () => UserRoute,
} as any)
const UserEditListRoute = UserEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => UserRoute,
} as any)
const OrgEditListRoute = OrgEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => OrgRoute,
} as any)
const FileEditListRoute = FileEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => FileRoute,
} as any)
const DomainEditListRoute = DomainEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => DomainRoute,
} as any)
const ContainerPreviewIdRoute = ContainerPreviewIdRouteImport.update({
id: '/preview/$id',
path: '/preview/$id',
getParentRoute: () => ContainerRoute,
} as any)
const ContainerEditListRoute = ContainerEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => ContainerRoute,
} as any)
const ConfigEditListRoute = ConfigEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => ConfigRoute,
} as any)
const AppEditListRoute = AppEditListRouteImport.update({
id: '/edit/list',
path: '/edit/list',
getParentRoute: () => AppRoute,
} as any)
const OrgEditUserIdRoute = OrgEditUserIdRouteImport.update({
id: '/edit/user/$id',
path: '/edit/user/$id',
getParentRoute: () => OrgRoute,
} as any)
const ContainerPreviewIdWrapperRoute =
ContainerPreviewIdWrapperRouteImport.update({
id: '/wrapper',
path: '/wrapper',
getParentRoute: () => ContainerPreviewIdRoute,
} as any)
const AppAppKeyVersionListRoute = AppAppKeyVersionListRouteImport.update({
id: '/$appKey/version/list',
path: '/$appKey/version/list',
getParentRoute: () => AppRoute,
} as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/app': typeof AppIndexRoute
'/config': typeof ConfigIndexRoute
'/container': typeof ContainerIndexRoute
'/domain': typeof DomainIndexRoute
'/file': typeof FileIndexRoute
'/home': typeof HomeRoute
'/map': typeof MapRoute
'/org': typeof OrgIndexRoute
'/user': typeof UserIndexRoute
'/user/login': typeof UserLoginRoute
'/app/edit/list': typeof AppEditListRoute
'/config/edit/list': typeof ConfigEditListRoute
'/container/edit/list': typeof ContainerEditListRoute
'/container/preview/$id': typeof ContainerPreviewIdRouteWithChildren
'/domain/edit/list': typeof DomainEditListRoute
'/file/edit/list': typeof FileEditListRoute
'/org/edit/list': typeof OrgEditListRoute
'/user/edit/list': typeof UserEditListRoute
'/user/edit/profile': typeof UserEditProfileRoute
'/user/wx/login': typeof UserWxLoginRoute
'/app/$appKey/version/list': typeof AppAppKeyVersionListRoute
'/container/preview/$id/wrapper': typeof ContainerPreviewIdWrapperRoute
'/org/edit/user/$id': typeof OrgEditUserIdRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/app': typeof AppIndexRoute
'/config': typeof ConfigIndexRoute
'/container': typeof ContainerIndexRoute
'/domain': typeof DomainIndexRoute
'/file': typeof FileIndexRoute
'/home': typeof HomeRoute
'/map': typeof MapRoute
'/org': typeof OrgIndexRoute
'/user': typeof UserIndexRoute
'/user/login': typeof UserLoginRoute
'/app/edit/list': typeof AppEditListRoute
'/config/edit/list': typeof ConfigEditListRoute
'/container/edit/list': typeof ContainerEditListRoute
'/container/preview/$id': typeof ContainerPreviewIdRouteWithChildren
'/domain/edit/list': typeof DomainEditListRoute
'/file/edit/list': typeof FileEditListRoute
'/org/edit/list': typeof OrgEditListRoute
'/user/edit/list': typeof UserEditListRoute
'/user/edit/profile': typeof UserEditProfileRoute
'/user/wx/login': typeof UserWxLoginRoute
'/app/$appKey/version/list': typeof AppAppKeyVersionListRoute
'/container/preview/$id/wrapper': typeof ContainerPreviewIdWrapperRoute
'/org/edit/user/$id': typeof OrgEditUserIdRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/app': typeof AppRouteWithChildren
'/config': typeof ConfigRouteWithChildren
'/container': typeof ContainerRouteWithChildren
'/domain': typeof DomainRouteWithChildren
'/file': typeof FileRouteWithChildren
'/home': typeof HomeRoute
'/map': typeof MapRoute
'/org': typeof OrgRouteWithChildren
'/user': typeof UserRouteWithChildren
'/app/_index': typeof AppIndexRoute
'/config/_index': typeof ConfigIndexRoute
'/container/_index': typeof ContainerIndexRoute
'/domain/_index': typeof DomainIndexRoute
'/file/_index': typeof FileIndexRoute
'/org/_index': typeof OrgIndexRoute
'/user/_index': typeof UserIndexRoute
'/user/login': typeof UserLoginRoute
'/app/edit/list': typeof AppEditListRoute
'/config/edit/list': typeof ConfigEditListRoute
'/container/edit/list': typeof ContainerEditListRoute
'/container/preview/$id': typeof ContainerPreviewIdRouteWithChildren
'/domain/edit/list': typeof DomainEditListRoute
'/file/edit/list': typeof FileEditListRoute
'/org/edit/list': typeof OrgEditListRoute
'/user/edit/list': typeof UserEditListRoute
'/user/edit/profile': typeof UserEditProfileRoute
'/user/wx/login': typeof UserWxLoginRoute
'/app/$appKey/version/list': typeof AppAppKeyVersionListRoute
'/container/preview/$id/wrapper': typeof ContainerPreviewIdWrapperRoute
'/org/edit/user/$id': typeof OrgEditUserIdRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/app'
| '/config'
| '/container'
| '/domain'
| '/file'
| '/home'
| '/map'
| '/org'
| '/user'
| '/user/login'
| '/app/edit/list'
| '/config/edit/list'
| '/container/edit/list'
| '/container/preview/$id'
| '/domain/edit/list'
| '/file/edit/list'
| '/org/edit/list'
| '/user/edit/list'
| '/user/edit/profile'
| '/user/wx/login'
| '/app/$appKey/version/list'
| '/container/preview/$id/wrapper'
| '/org/edit/user/$id'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/app'
| '/config'
| '/container'
| '/domain'
| '/file'
| '/home'
| '/map'
| '/org'
| '/user'
| '/user/login'
| '/app/edit/list'
| '/config/edit/list'
| '/container/edit/list'
| '/container/preview/$id'
| '/domain/edit/list'
| '/file/edit/list'
| '/org/edit/list'
| '/user/edit/list'
| '/user/edit/profile'
| '/user/wx/login'
| '/app/$appKey/version/list'
| '/container/preview/$id/wrapper'
| '/org/edit/user/$id'
id:
| '__root__'
| '/'
| '/app'
| '/config'
| '/container'
| '/domain'
| '/file'
| '/home'
| '/map'
| '/org'
| '/user'
| '/app/_index'
| '/config/_index'
| '/container/_index'
| '/domain/_index'
| '/file/_index'
| '/org/_index'
| '/user/_index'
| '/user/login'
| '/app/edit/list'
| '/config/edit/list'
| '/container/edit/list'
| '/container/preview/$id'
| '/domain/edit/list'
| '/file/edit/list'
| '/org/edit/list'
| '/user/edit/list'
| '/user/edit/profile'
| '/user/wx/login'
| '/app/$appKey/version/list'
| '/container/preview/$id/wrapper'
| '/org/edit/user/$id'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
AppRoute: typeof AppRouteWithChildren
ConfigRoute: typeof ConfigRouteWithChildren
ContainerRoute: typeof ContainerRouteWithChildren
DomainRoute: typeof DomainRouteWithChildren
FileRoute: typeof FileRouteWithChildren
HomeRoute: typeof HomeRoute
MapRoute: typeof MapRoute
OrgRoute: typeof OrgRouteWithChildren
UserRoute: typeof UserRouteWithChildren
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/user': {
id: '/user'
path: '/user'
fullPath: '/user'
preLoaderRoute: typeof UserRouteImport
parentRoute: typeof rootRouteImport
}
'/org': {
id: '/org'
path: '/org'
fullPath: '/org'
preLoaderRoute: typeof OrgRouteImport
parentRoute: typeof rootRouteImport
}
'/map': {
id: '/map'
path: '/map'
fullPath: '/map'
preLoaderRoute: typeof MapRouteImport
parentRoute: typeof rootRouteImport
}
'/home': {
id: '/home'
path: '/home'
fullPath: '/home'
preLoaderRoute: typeof HomeRouteImport
parentRoute: typeof rootRouteImport
}
'/file': {
id: '/file'
path: '/file'
fullPath: '/file'
preLoaderRoute: typeof FileRouteImport
parentRoute: typeof rootRouteImport
}
'/domain': {
id: '/domain'
path: '/domain'
fullPath: '/domain'
preLoaderRoute: typeof DomainRouteImport
parentRoute: typeof rootRouteImport
}
'/container': {
id: '/container'
path: '/container'
fullPath: '/container'
preLoaderRoute: typeof ContainerRouteImport
parentRoute: typeof rootRouteImport
}
'/config': {
id: '/config'
path: '/config'
fullPath: '/config'
preLoaderRoute: typeof ConfigRouteImport
parentRoute: typeof rootRouteImport
}
'/app': {
id: '/app'
path: '/app'
fullPath: '/app'
preLoaderRoute: typeof AppRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
'/user/login': {
id: '/user/login'
path: '/login'
fullPath: '/user/login'
preLoaderRoute: typeof UserLoginRouteImport
parentRoute: typeof UserRoute
}
'/user/_index': {
id: '/user/_index'
path: ''
fullPath: '/user'
preLoaderRoute: typeof UserIndexRouteImport
parentRoute: typeof UserRoute
}
'/org/_index': {
id: '/org/_index'
path: ''
fullPath: '/org'
preLoaderRoute: typeof OrgIndexRouteImport
parentRoute: typeof OrgRoute
}
'/file/_index': {
id: '/file/_index'
path: ''
fullPath: '/file'
preLoaderRoute: typeof FileIndexRouteImport
parentRoute: typeof FileRoute
}
'/domain/_index': {
id: '/domain/_index'
path: ''
fullPath: '/domain'
preLoaderRoute: typeof DomainIndexRouteImport
parentRoute: typeof DomainRoute
}
'/container/_index': {
id: '/container/_index'
path: ''
fullPath: '/container'
preLoaderRoute: typeof ContainerIndexRouteImport
parentRoute: typeof ContainerRoute
}
'/config/_index': {
id: '/config/_index'
path: ''
fullPath: '/config'
preLoaderRoute: typeof ConfigIndexRouteImport
parentRoute: typeof ConfigRoute
}
'/app/_index': {
id: '/app/_index'
path: ''
fullPath: '/app'
preLoaderRoute: typeof AppIndexRouteImport
parentRoute: typeof AppRoute
}
'/user/wx/login': {
id: '/user/wx/login'
path: '/wx/login'
fullPath: '/user/wx/login'
preLoaderRoute: typeof UserWxLoginRouteImport
parentRoute: typeof UserRoute
}
'/user/edit/profile': {
id: '/user/edit/profile'
path: '/edit/profile'
fullPath: '/user/edit/profile'
preLoaderRoute: typeof UserEditProfileRouteImport
parentRoute: typeof UserRoute
}
'/user/edit/list': {
id: '/user/edit/list'
path: '/edit/list'
fullPath: '/user/edit/list'
preLoaderRoute: typeof UserEditListRouteImport
parentRoute: typeof UserRoute
}
'/org/edit/list': {
id: '/org/edit/list'
path: '/edit/list'
fullPath: '/org/edit/list'
preLoaderRoute: typeof OrgEditListRouteImport
parentRoute: typeof OrgRoute
}
'/file/edit/list': {
id: '/file/edit/list'
path: '/edit/list'
fullPath: '/file/edit/list'
preLoaderRoute: typeof FileEditListRouteImport
parentRoute: typeof FileRoute
}
'/domain/edit/list': {
id: '/domain/edit/list'
path: '/edit/list'
fullPath: '/domain/edit/list'
preLoaderRoute: typeof DomainEditListRouteImport
parentRoute: typeof DomainRoute
}
'/container/preview/$id': {
id: '/container/preview/$id'
path: '/preview/$id'
fullPath: '/container/preview/$id'
preLoaderRoute: typeof ContainerPreviewIdRouteImport
parentRoute: typeof ContainerRoute
}
'/container/edit/list': {
id: '/container/edit/list'
path: '/edit/list'
fullPath: '/container/edit/list'
preLoaderRoute: typeof ContainerEditListRouteImport
parentRoute: typeof ContainerRoute
}
'/config/edit/list': {
id: '/config/edit/list'
path: '/edit/list'
fullPath: '/config/edit/list'
preLoaderRoute: typeof ConfigEditListRouteImport
parentRoute: typeof ConfigRoute
}
'/app/edit/list': {
id: '/app/edit/list'
path: '/edit/list'
fullPath: '/app/edit/list'
preLoaderRoute: typeof AppEditListRouteImport
parentRoute: typeof AppRoute
}
'/org/edit/user/$id': {
id: '/org/edit/user/$id'
path: '/edit/user/$id'
fullPath: '/org/edit/user/$id'
preLoaderRoute: typeof OrgEditUserIdRouteImport
parentRoute: typeof OrgRoute
}
'/container/preview/$id/wrapper': {
id: '/container/preview/$id/wrapper'
path: '/wrapper'
fullPath: '/container/preview/$id/wrapper'
preLoaderRoute: typeof ContainerPreviewIdWrapperRouteImport
parentRoute: typeof ContainerPreviewIdRoute
}
'/app/$appKey/version/list': {
id: '/app/$appKey/version/list'
path: '/$appKey/version/list'
fullPath: '/app/$appKey/version/list'
preLoaderRoute: typeof AppAppKeyVersionListRouteImport
parentRoute: typeof AppRoute
}
}
}
interface AppRouteChildren {
AppIndexRoute: typeof AppIndexRoute
AppEditListRoute: typeof AppEditListRoute
AppAppKeyVersionListRoute: typeof AppAppKeyVersionListRoute
}
const AppRouteChildren: AppRouteChildren = {
AppIndexRoute: AppIndexRoute,
AppEditListRoute: AppEditListRoute,
AppAppKeyVersionListRoute: AppAppKeyVersionListRoute,
}
const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren)
interface ConfigRouteChildren {
ConfigIndexRoute: typeof ConfigIndexRoute
ConfigEditListRoute: typeof ConfigEditListRoute
}
const ConfigRouteChildren: ConfigRouteChildren = {
ConfigIndexRoute: ConfigIndexRoute,
ConfigEditListRoute: ConfigEditListRoute,
}
const ConfigRouteWithChildren =
ConfigRoute._addFileChildren(ConfigRouteChildren)
interface ContainerPreviewIdRouteChildren {
ContainerPreviewIdWrapperRoute: typeof ContainerPreviewIdWrapperRoute
}
const ContainerPreviewIdRouteChildren: ContainerPreviewIdRouteChildren = {
ContainerPreviewIdWrapperRoute: ContainerPreviewIdWrapperRoute,
}
const ContainerPreviewIdRouteWithChildren =
ContainerPreviewIdRoute._addFileChildren(ContainerPreviewIdRouteChildren)
interface ContainerRouteChildren {
ContainerIndexRoute: typeof ContainerIndexRoute
ContainerEditListRoute: typeof ContainerEditListRoute
ContainerPreviewIdRoute: typeof ContainerPreviewIdRouteWithChildren
}
const ContainerRouteChildren: ContainerRouteChildren = {
ContainerIndexRoute: ContainerIndexRoute,
ContainerEditListRoute: ContainerEditListRoute,
ContainerPreviewIdRoute: ContainerPreviewIdRouteWithChildren,
}
const ContainerRouteWithChildren = ContainerRoute._addFileChildren(
ContainerRouteChildren,
)
interface DomainRouteChildren {
DomainIndexRoute: typeof DomainIndexRoute
DomainEditListRoute: typeof DomainEditListRoute
}
const DomainRouteChildren: DomainRouteChildren = {
DomainIndexRoute: DomainIndexRoute,
DomainEditListRoute: DomainEditListRoute,
}
const DomainRouteWithChildren =
DomainRoute._addFileChildren(DomainRouteChildren)
interface FileRouteChildren {
FileIndexRoute: typeof FileIndexRoute
FileEditListRoute: typeof FileEditListRoute
}
const FileRouteChildren: FileRouteChildren = {
FileIndexRoute: FileIndexRoute,
FileEditListRoute: FileEditListRoute,
}
const FileRouteWithChildren = FileRoute._addFileChildren(FileRouteChildren)
interface OrgRouteChildren {
OrgIndexRoute: typeof OrgIndexRoute
OrgEditListRoute: typeof OrgEditListRoute
OrgEditUserIdRoute: typeof OrgEditUserIdRoute
}
const OrgRouteChildren: OrgRouteChildren = {
OrgIndexRoute: OrgIndexRoute,
OrgEditListRoute: OrgEditListRoute,
OrgEditUserIdRoute: OrgEditUserIdRoute,
}
const OrgRouteWithChildren = OrgRoute._addFileChildren(OrgRouteChildren)
interface UserRouteChildren {
UserIndexRoute: typeof UserIndexRoute
UserLoginRoute: typeof UserLoginRoute
UserEditListRoute: typeof UserEditListRoute
UserEditProfileRoute: typeof UserEditProfileRoute
UserWxLoginRoute: typeof UserWxLoginRoute
}
const UserRouteChildren: UserRouteChildren = {
UserIndexRoute: UserIndexRoute,
UserLoginRoute: UserLoginRoute,
UserEditListRoute: UserEditListRoute,
UserEditProfileRoute: UserEditProfileRoute,
UserWxLoginRoute: UserWxLoginRoute,
}
const UserRouteWithChildren = UserRoute._addFileChildren(UserRouteChildren)
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
AppRoute: AppRouteWithChildren,
ConfigRoute: ConfigRouteWithChildren,
ContainerRoute: ContainerRouteWithChildren,
DomainRoute: DomainRouteWithChildren,
FileRoute: FileRouteWithChildren,
HomeRoute: HomeRoute,
MapRoute: MapRoute,
OrgRoute: OrgRouteWithChildren,
UserRoute: UserRouteWithChildren,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()

16
src/routes/__root.tsx Normal file
View File

@@ -0,0 +1,16 @@
import { Link, Outlet, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
export const Route = createRootRoute({
component: RootComponent,
})
function RootComponent() {
return (
<>
<hr />
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
)
}

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { AppVersionList } from '../pages/app/edit/AppVersionList'
export const Route = createFileRoute('/app/$appKey/version/list')({
component: () => <AppVersionList />,
})

11
src/routes/app._index.tsx Normal file
View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/app/_index')({
beforeLoad: () => {
throw redirect({
to: '/app/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/app/edit/List'
export const Route = createFileRoute('/app/edit/list')({
component: () => <List />,
})

6
src/routes/app.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { Main } from '../pages/app/layouts'
export const Route = createFileRoute('/app')({
component: () => <Main><Outlet /></Main>,
})

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/config/_index')({
beforeLoad: () => {
throw redirect({
to: '/config/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/config/edit/List'
export const Route = createFileRoute('/config/edit/list')({
component: () => <List />,
})

10
src/routes/config.tsx Normal file
View File

@@ -0,0 +1,10 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { LayoutMain } from '@/modules/layout'
export const Route = createFileRoute('/config')({
component: () => (
<LayoutMain title='Config'>
<Outlet />
</LayoutMain>
),
})

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/container/_index')({
beforeLoad: () => {
throw redirect({
to: '/container/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { ContainerList } from '../pages/container/edit/List'
export const Route = createFileRoute('/container/edit/list')({
component: () => <ContainerList />,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { Preview } from '../pages/container/preview'
export const Route = createFileRoute('/container/preview/$id')({
component: () => <Preview />,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { PreviewWrapper } from '../pages/container/preview'
export const Route = createFileRoute('/container/preview/$id/wrapper')({
component: () => <PreviewWrapper />,
})

10
src/routes/container.tsx Normal file
View File

@@ -0,0 +1,10 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { LayoutMain } from '@/modules/layout'
export const Route = createFileRoute('/container')({
component: () => (
<LayoutMain title='Container'>
<Outlet />
</LayoutMain>
),
})

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/domain/_index')({
beforeLoad: () => {
throw redirect({
to: '/domain/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/domain/edit/List'
export const Route = createFileRoute('/domain/edit/list')({
component: () => <List />,
})

6
src/routes/domain.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { Main } from '../pages/domain/layouts'
export const Route = createFileRoute('/domain')({
component: () => <Main><Outlet /></Main>,
})

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/file/_index')({
beforeLoad: () => {
throw redirect({
to: '/file/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/file/edit/List'
export const Route = createFileRoute('/file/edit/list')({
component: () => <List />,
})

6
src/routes/file.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { Main } from '../pages/file/layouts'
export const Route = createFileRoute('/file')({
component: () => <Main><Outlet /></Main>,
})

6
src/routes/home.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { App as HomeApp } from '../pages/home'
export const Route = createFileRoute('/home')({
component: () => <HomeApp />,
})

11
src/routes/index.tsx Normal file
View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
beforeLoad: () => {
throw redirect({
to: '/app',
throw: true,
})
},
component: () => null,
})

6
src/routes/map.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { App as MapApp } from '../pages/map'
export const Route = createFileRoute('/map')({
component: () => <MapApp />,
})

11
src/routes/org._index.tsx Normal file
View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/org/_index')({
beforeLoad: () => {
throw redirect({
to: '/org/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/org/edit/List'
export const Route = createFileRoute('/org/edit/list')({
component: () => <List />,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { UserList } from '../pages/org/edit/UserList'
export const Route = createFileRoute('/org/edit/user/$id')({
component: () => <UserList />,
})

6
src/routes/org.tsx Normal file
View File

@@ -0,0 +1,6 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { Main } from '../pages/org/layouts'
export const Route = createFileRoute('/org')({
component: () => <Main><Outlet /></Main>,
})

View File

@@ -0,0 +1,11 @@
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/user/_index')({
beforeLoad: () => {
throw redirect({
to: '/user/edit/list',
throw: true,
})
},
component: () => null,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { List } from '../pages/user/edit/List'
export const Route = createFileRoute('/user/edit/list')({
component: () => <List />,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { Profile } from '../pages/user/edit/Profile'
export const Route = createFileRoute('/user/edit/profile')({
component: () => <Profile />,
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { Login as UserLogin } from '../pages/user/login/Login'
export const Route = createFileRoute('/user/login')({
component: () => <UserLogin />,
})

10
src/routes/user.tsx Normal file
View File

@@ -0,0 +1,10 @@
import { Outlet, createFileRoute } from '@tanstack/react-router'
import { LayoutMain } from '@/modules/layout'
export const Route = createFileRoute('/user')({
component: () => (
<LayoutMain title='User'>
<Outlet />
</LayoutMain>
),
})

View File

@@ -0,0 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { Login as WxLogin } from '../pages/user/wx/Login'
export const Route = createFileRoute('/user/wx/login')({
component: () => <WxLogin />,
})

View File

@@ -2,6 +2,8 @@ import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import tailwindcss from '@tailwindcss/vite';
import { tanstackRouter } from '@tanstack/router-plugin/vite'
const isDev = process.env.NODE_ENV === 'development';
const centerEnv = process.env.CENTER_ENV;
const plugins: any[] = [];
@@ -17,7 +19,13 @@ let proxy = {
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), ...plugins],
plugins: [
// Please make sure that '@tanstack/router-plugin' is passed before '@vitejs/plugin-react'
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
react(), ...plugins],
css: {
postcss: {},
@@ -34,38 +42,6 @@ export default defineConfig({
base: isDev ? '/' : '/root/center-v1/',
build: {
sourcemap: false,
rollupOptions: {
output: {
// 控制输出
// 在rollup里面, hash代表将你的文件名和文件内容进行组合计算得来的结果
assetFileNames: (chunkInfo) => {
console.log(chunkInfo.names);
if (chunkInfo.names?.includes('panda.jpg')) {
return '[name].[ext]';
}
const qrcode = ['qrcode-8x8.jpg'];
const names = chunkInfo.names || [];
if (qrcode.some((name) => names.includes(name))) {
return '[name].[ext]';
}
return '[name].[hash].[ext]';
},
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('react')) {
return 'vendor-react';
}
// prettier
if (id.includes('prettier')) {
return 'vendor-prettier';
}
// codemirror
// console.log(id);
return 'vendor';
}
},
},
},
},
server: {
port: 6020,