feat: add dynamic routing (#25) #42

Merged
primakov merged 2 commits from feature/router-arm-dynamic into main 2024-11-24 19:54:28 +03:00
5 changed files with 90 additions and 52 deletions

View File

@ -1,9 +1,9 @@
/* eslint-disable no-undef */ /* eslint-disable no-undef */
/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-require-imports */
const pkg = require("./package"); const pkg = require('./package');
module.exports = { module.exports = {
apiPath: "stubs/api", apiPath: 'stubs/api',
webpackConfig: { webpackConfig: {
output: { output: {
publicPath: `/static/${pkg.name}/${process.env.VERSION || pkg.version}/`, publicPath: `/static/${pkg.name}/${process.env.VERSION || pkg.version}/`,
@ -11,17 +11,19 @@ module.exports = {
}, },
/* use https://admin.bro-js.ru/ to create config, navigations and features */ /* use https://admin.bro-js.ru/ to create config, navigations and features */
navigations: { navigations: {
"dry-wash.main": "/dry-wash", 'dry-wash.main': '/dry-wash',
"dry-wash.create": "/order", 'dry-wash.create': '/order',
"dry-wash.view.order": "/order/:orderId", 'dry-wash.view.order': '/order/:orderId',
"dry-wash.arm": "/arm", 'dry-wash.arm.master': '/master',
'dry-wash.arm.order': '/order',
'dry-wash.arm': '/arm/*',
}, },
features: { features: {
"dry-wash-pl": { 'dry-wash-pl': {
// add your features here in the format [featureName]: { value: string } // add your features here in the format [featureName]: { value: string }
}, },
}, },
config: { config: {
"dry-wash-pl.api": "/api", 'dry-wash-pl.api': '/api',
}, },
}; };

View File

@ -1,25 +1,40 @@
import { generatePath } from "react-router-dom"; import { generatePath } from 'react-router-dom';
import { getNavigationValue } from "@brojs/cli"; import { getNavigationValue } from '@brojs/cli';
import { Order } from "../models"; import { Order } from '../models';
const getFullUrls = (url: string) =>
`${getNavigationValue('dry-wash.main')}${url}`;
export const URLs = { export const URLs = {
landing: { landing: {
url: getNavigationValue("dry-wash.main"), url: getNavigationValue('dry-wash.main'),
getUrl() { getUrl() {
return this.url; return this.url;
} },
}, },
orderForm: { orderForm: {
url: getNavigationValue("dry-wash.create"), url: getNavigationValue('dry-wash.create'),
getUrl() { getUrl() {
return this.url; return this.url;
} },
}, },
orderView: { orderView: {
url: getNavigationValue("dry-wash.view.order"), url: getNavigationValue('dry-wash.view.order'),
getUrl(orderId: Order.Id) { getUrl(orderId: Order.Id) {
return generatePath(this.url, { orderId }); return generatePath(this.url, { orderId });
} },
} },
}; armMaster: {
url: getNavigationValue('dry-wash.arm.master'),
isOn: Boolean(getNavigationValue('dry-wash.arm.master')),
},
armOrder: {
url: getNavigationValue('dry-wash.arm.order'),
isOn: Boolean(getNavigationValue('dry-wash.arm.order')),
},
armBase: {
url: getFullUrls(getNavigationValue('dry-wash.arm')),
isOn: Boolean(getNavigationValue('dry-wash.arm')),
},
};

View File

@ -5,20 +5,33 @@ import { Navigate, Route, Routes } from 'react-router-dom';
import Sidebar from '../Sidebar'; import Sidebar from '../Sidebar';
import Orders from '../Orders'; import Orders from '../Orders';
import Masters from '../Masters'; import Masters from '../Masters';
import { URLs } from '../../__data__/urls';
const LayoutArm = () => ( const LayoutArm = () => {
<Flex h='100vh'> let defaultRedirect = null;
<Sidebar />
<Box flex='1' bg='gray.50'> if (URLs.armOrder.isOn) {
<Routes> defaultRedirect = URLs.armOrder.url;
<Route> } else if (URLs.armMaster.isOn) {
<Route index element={<Navigate to='orders' replace />} /> defaultRedirect = URLs.armMaster.url;
<Route path='orders' element={<Orders />} /> }
<Route path='masters' element={<Masters />} />
</Route> return (
</Routes> <Flex h='100vh'>
</Box> <Sidebar />
</Flex> <Box flex='1' bg='gray.50'>
); <Routes>
<Route index element={<Navigate to={defaultRedirect} replace />} />
{URLs.armOrder.isOn && (
<Route path={URLs.armOrder.url} element={<Orders />} />
)}
{URLs.armMaster.isOn && (
<Route path={URLs.armMaster.url} element={<Masters />} />
)}
</Routes>
</Box>
</Flex>
);
};
export default LayoutArm; export default LayoutArm;

View File

@ -3,6 +3,8 @@ import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { URLs } from '../../__data__/urls';
const Sidebar = () => { const Sidebar = () => {
const { t } = useTranslation('~', { const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.master.sideBar', keyPrefix: 'dry-wash.arm.master.sideBar',
@ -23,25 +25,29 @@ const Sidebar = () => {
<VStack align='start' spacing='4'> <VStack align='start' spacing='4'>
<Divider /> <Divider />
<Button {URLs.armOrder.isOn && (
as={Link} <Button
to='orders' as={Link}
w='100%' to={URLs.armOrder.url}
colorScheme='green' w='100%'
variant='ghost' colorScheme='green'
> variant='ghost'
{t('orders')} >
</Button> {t('orders')}
</Button>
)}
<Divider /> <Divider />
<Button {URLs.armMaster.isOn && (
as={Link} <Button
to='masters' as={Link}
w='100%' to={URLs.armMaster.url}
colorScheme='green' w='100%'
variant='ghost' colorScheme='green'
> variant='ghost'
{t('master')} >
</Button> {t('master')}
</Button>
)}
<Divider /> <Divider />
</VStack> </VStack>
</Box> </Box>

View File

@ -17,7 +17,9 @@ const Routers = () => {
<Route path={URLs.landing.url} element={<Landing />} /> <Route path={URLs.landing.url} element={<Landing />} />
<Route path={URLs.orderForm.url} element={<OrderForm />} /> <Route path={URLs.orderForm.url} element={<OrderForm />} />
<Route path={URLs.orderView.url} element={<OrderView />} /> <Route path={URLs.orderView.url} element={<OrderView />} />
<Route path='/dry-wash/arm/*' element={<Arm />}></Route> {URLs.armBase.isOn && (
<Route path={URLs.armBase.url} element={<Arm />}></Route>
)}
<Route path='*' element={<NotFound />} /> <Route path='*' element={<NotFound />} />
</Routes> </Routes>
</Suspense> </Suspense>