mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
feat: migrate dashboard app to use react data router
This commit is contained in:
parent
ff885b9b21
commit
cd11e6e36f
9 changed files with 107 additions and 100 deletions
|
@ -5,15 +5,13 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import React from 'react';
|
||||
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/App';
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/routes/routes';
|
||||
import AppHeader from 'components/AppHeader';
|
||||
import Backdrop from 'components/Backdrop';
|
||||
import { ApiProvider } from 'hooks/useApi';
|
||||
import { WebConfigProvider } from 'hooks/useWebConfig';
|
||||
import theme from 'themes/theme';
|
||||
import { HistoryRouter } from 'components/router/HistoryRouter';
|
||||
|
||||
const DashboardApp = loadable(() => import('./apps/dashboard/App'));
|
||||
const StableAppRouter = loadable(() => import('./apps/stable/AppRouter'));
|
||||
const RootAppRouter = loadable(() => import('./RootAppRouter'));
|
||||
|
||||
|
@ -35,10 +33,6 @@ const RootAppLayout = ({ history }: { history: History }) => {
|
|||
<RootAppRouter history={history} /> :
|
||||
<StableAppRouter history={history} />
|
||||
}
|
||||
|
||||
<HistoryRouter history={history}>
|
||||
<DashboardApp />
|
||||
</HistoryRouter>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
|
||||
import { History } from '@remix-run/router';
|
||||
import React from 'react';
|
||||
import { RouterProvider, createHashRouter } from 'react-router-dom';
|
||||
import {
|
||||
RouterProvider,
|
||||
createHashRouter
|
||||
} from 'react-router-dom';
|
||||
|
||||
import { EXPERIMENTAL_APP_ROUTES } from 'apps/experimental/routes/routes';
|
||||
import { useLegacyRouterSync } from 'hooks/useLegacyRouterSync';
|
||||
import { DASHBOARD_APP_ROUTES } from 'apps/dashboard/routes/routes';
|
||||
|
||||
const router = createHashRouter([
|
||||
...EXPERIMENTAL_APP_ROUTES
|
||||
...EXPERIMENTAL_APP_ROUTES,
|
||||
...DASHBOARD_APP_ROUTES
|
||||
]);
|
||||
|
||||
export default function RootAppRouter({ history }: { history: History}) {
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
import loadable from '@loadable/component';
|
||||
import React from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
|
||||
import ConnectionRequired from 'components/ConnectionRequired';
|
||||
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
|
||||
import { AsyncPageProps, AsyncRoute, toAsyncPageRoute } from 'components/router/AsyncRoute';
|
||||
import { toRedirectRoute } from 'components/router/Redirect';
|
||||
import ServerContentPage from 'components/ServerContentPage';
|
||||
|
||||
import AppLayout from './AppLayout';
|
||||
import { REDIRECTS } from './routes/_redirects';
|
||||
import { ASYNC_ADMIN_ROUTES } from './routes/_asyncRoutes';
|
||||
import { LEGACY_ADMIN_ROUTES } from './routes/_legacyRoutes';
|
||||
|
||||
const DashboardAsyncPage = loadable(
|
||||
(props: { page: string }) => import(/* webpackChunkName: "[request]" */ `./routes/${props.page}`),
|
||||
{ cacheKey: (props: AsyncPageProps) => props.page }
|
||||
);
|
||||
|
||||
const toDashboardAsyncPageRoute = (route: AsyncRoute) => (
|
||||
toAsyncPageRoute({
|
||||
...route,
|
||||
element: DashboardAsyncPage
|
||||
})
|
||||
);
|
||||
|
||||
export const DASHBOARD_APP_PATHS = {
|
||||
Dashboard: 'dashboard',
|
||||
MetadataManager: 'metadata',
|
||||
PluginConfig: 'configurationpage'
|
||||
};
|
||||
|
||||
const DashboardApp = () => (
|
||||
<Routes>
|
||||
<Route element={<ConnectionRequired isAdminRequired />}>
|
||||
<Route element={<AppLayout drawerlessPaths={[ DASHBOARD_APP_PATHS.MetadataManager ]} />}>
|
||||
<Route path={DASHBOARD_APP_PATHS.Dashboard}>
|
||||
{ASYNC_ADMIN_ROUTES.map(toDashboardAsyncPageRoute)}
|
||||
{LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}
|
||||
</Route>
|
||||
|
||||
{/* NOTE: The metadata editor might deserve a dedicated app in the future */}
|
||||
{toViewManagerPageRoute({
|
||||
path: DASHBOARD_APP_PATHS.MetadataManager,
|
||||
pageProps: {
|
||||
controller: 'edititemmetadata',
|
||||
view: 'edititemmetadata.html'
|
||||
}
|
||||
})}
|
||||
|
||||
<Route path={DASHBOARD_APP_PATHS.PluginConfig} element={
|
||||
<ServerContentPage view='/web/configurationpage' />
|
||||
} />
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
{/* Suppress warnings for unhandled routes */}
|
||||
<Route path='*' element={null} />
|
||||
|
||||
{/* Redirects for old paths */}
|
||||
{REDIRECTS.map(toRedirectRoute)}
|
||||
</Routes>
|
||||
);
|
||||
|
||||
export default DashboardApp;
|
|
@ -1,12 +1,12 @@
|
|||
import type { AsyncRoute } from 'components/router/AsyncRoute';
|
||||
import { AsyncRouteType, type AsyncRoute } from 'components/router/AsyncRoute';
|
||||
|
||||
export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [
|
||||
{ path: 'activity' },
|
||||
{ path: 'notifications' },
|
||||
{ path: 'users' },
|
||||
{ path: 'users/access' },
|
||||
{ path: 'users/add' },
|
||||
{ path: 'users/parentalcontrol' },
|
||||
{ path: 'users/password' },
|
||||
{ path: 'users/profile' }
|
||||
{ path: 'activity', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'notifications', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users/access', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users/add', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users/parentalcontrol', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users/password', type: AsyncRouteType.Dashboard },
|
||||
{ path: 'users/profile', type: AsyncRouteType.Dashboard }
|
||||
];
|
||||
|
|
49
src/apps/dashboard/routes/routes.tsx
Normal file
49
src/apps/dashboard/routes/routes.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
import { RouteObject } from 'react-router-dom';
|
||||
import AppLayout from '../AppLayout';
|
||||
import ConnectionRequired from 'components/ConnectionRequired';
|
||||
import { ASYNC_ADMIN_ROUTES } from './_asyncRoutes';
|
||||
import { toAsyncPageRouteConfig } from 'components/router/AsyncRoute';
|
||||
import { toViewManagerPageRouteConfig } from 'components/router/LegacyRoute';
|
||||
import { LEGACY_ADMIN_ROUTES } from './_legacyRoutes';
|
||||
import ServerContentPage from 'components/ServerContentPage';
|
||||
|
||||
export const DASHBOARD_APP_PATHS = {
|
||||
Dashboard: 'dashboard',
|
||||
MetadataManager: 'metadata',
|
||||
PluginConfig: 'configurationpage'
|
||||
};
|
||||
|
||||
export const DASHBOARD_APP_ROUTES: RouteObject[] = [
|
||||
{
|
||||
element: <ConnectionRequired isAdminRequired />,
|
||||
children: [
|
||||
{
|
||||
element: <AppLayout drawerlessPaths={[ DASHBOARD_APP_PATHS.MetadataManager ]} />,
|
||||
children: [
|
||||
{
|
||||
path: DASHBOARD_APP_PATHS.Dashboard,
|
||||
children: [
|
||||
...ASYNC_ADMIN_ROUTES.map(toAsyncPageRouteConfig),
|
||||
...LEGACY_ADMIN_ROUTES.map(toViewManagerPageRouteConfig)
|
||||
]
|
||||
},
|
||||
|
||||
/* NOTE: The metadata editor might deserve a dedicated app in the future */
|
||||
toViewManagerPageRouteConfig({
|
||||
path: DASHBOARD_APP_PATHS.MetadataManager,
|
||||
pageProps: {
|
||||
controller: 'edititemmetadata',
|
||||
view: 'edititemmetadata.html'
|
||||
}
|
||||
}),
|
||||
|
||||
{
|
||||
path: DASHBOARD_APP_PATHS.PluginConfig,
|
||||
element: <ServerContentPage view='/web/configurationpage' />
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||
import { RouteObject, redirect } from 'react-router-dom';
|
||||
|
||||
import { REDIRECTS } from 'apps/dashboard/routes/_redirects';
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/routes/routes';
|
||||
import ConnectionRequired from 'components/ConnectionRequired';
|
||||
import { toAsyncPageRouteConfig } from 'components/router/AsyncRoute';
|
||||
import { toViewManagerPageRouteConfig } from 'components/router/LegacyRoute';
|
||||
|
@ -9,7 +10,6 @@ import { toRedirectRouteConfig } from 'components/router/Redirect';
|
|||
import AppLayout from '../AppLayout';
|
||||
import { ASYNC_USER_ROUTES } from './asyncRoutes';
|
||||
import { LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes';
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/App';
|
||||
|
||||
export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [
|
||||
{
|
||||
|
|
|
@ -2,11 +2,13 @@ import { History } from '@remix-run/router';
|
|||
import React from 'react';
|
||||
import { RouterProvider, createHashRouter } from 'react-router-dom';
|
||||
|
||||
import { STABLE_APP_ROUTES } from './routes/routes';
|
||||
import { DASHBOARD_APP_ROUTES } from 'apps/dashboard/routes/routes';
|
||||
import { useLegacyRouterSync } from 'hooks/useLegacyRouterSync';
|
||||
import { STABLE_APP_ROUTES } from './routes/routes';
|
||||
|
||||
const router = createHashRouter([
|
||||
...STABLE_APP_ROUTES
|
||||
...STABLE_APP_ROUTES,
|
||||
...DASHBOARD_APP_ROUTES
|
||||
]);
|
||||
|
||||
export default function StableAppRouter({ history }: { history: History }) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { RouteObject, redirect } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/App';
|
||||
import { DASHBOARD_APP_PATHS } from 'apps/dashboard/routes/routes';
|
||||
import ConnectionRequired from 'components/ConnectionRequired';
|
||||
import { toAsyncPageRouteConfig } from 'components/router/AsyncRoute';
|
||||
import { toViewManagerPageRouteConfig } from 'components/router/LegacyRoute';
|
||||
|
|
|
@ -4,7 +4,8 @@ import { Route } from 'react-router-dom';
|
|||
|
||||
export enum AsyncRouteType {
|
||||
Stable,
|
||||
Experimental
|
||||
Experimental,
|
||||
Dashboard,
|
||||
}
|
||||
|
||||
export interface AsyncRoute {
|
||||
|
@ -26,6 +27,11 @@ export interface AsyncPageProps {
|
|||
page: string
|
||||
}
|
||||
|
||||
const DashboardAsyncPage = loadable(
|
||||
(props: { page: string }) => import(/* webpackChunkName: "[request]" */ `../../apps/dashboard/routes/${props.page}`),
|
||||
{ cacheKey: (props: AsyncPageProps) => props.page }
|
||||
);
|
||||
|
||||
const ExperimentalAsyncPage = loadable(
|
||||
(props: { page: string }) => import(/* webpackChunkName: "[request]" */ `../../apps/experimental/routes/${props.page}`),
|
||||
{ cacheKey: (props: AsyncPageProps) => props.page }
|
||||
|
@ -37,12 +43,20 @@ const StableAsyncPage = loadable(
|
|||
);
|
||||
|
||||
export const toAsyncPageRoute = ({ path, page, element, type = AsyncRouteType.Stable }: AsyncRoute) => {
|
||||
const Element = element
|
||||
|| (
|
||||
type === AsyncRouteType.Experimental ?
|
||||
ExperimentalAsyncPage :
|
||||
StableAsyncPage
|
||||
);
|
||||
let Element = element;
|
||||
if (!Element) {
|
||||
switch (type) {
|
||||
case AsyncRouteType.Dashboard:
|
||||
Element = DashboardAsyncPage;
|
||||
break;
|
||||
case AsyncRouteType.Experimental:
|
||||
Element = ExperimentalAsyncPage;
|
||||
break;
|
||||
case AsyncRouteType.Stable:
|
||||
default:
|
||||
Element = StableAsyncPage;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Route
|
||||
|
@ -54,11 +68,20 @@ export const toAsyncPageRoute = ({ path, page, element, type = AsyncRouteType.St
|
|||
};
|
||||
|
||||
export function toAsyncPageRouteConfig({ path, page, element, type = AsyncRouteType.Stable }: AsyncRoute) {
|
||||
const Element = element || (
|
||||
type === AsyncRouteType.Experimental ?
|
||||
ExperimentalAsyncPage :
|
||||
StableAsyncPage
|
||||
);
|
||||
let Element = element;
|
||||
if (!Element) {
|
||||
switch (type) {
|
||||
case AsyncRouteType.Dashboard:
|
||||
Element = DashboardAsyncPage;
|
||||
break;
|
||||
case AsyncRouteType.Experimental:
|
||||
Element = ExperimentalAsyncPage;
|
||||
break;
|
||||
case AsyncRouteType.Stable:
|
||||
default:
|
||||
Element = StableAsyncPage;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue