1
0
Fork 0
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:
Grady Hallenbeck 2023-10-06 20:09:19 -07:00
parent ff885b9b21
commit cd11e6e36f
9 changed files with 107 additions and 100 deletions

View file

@ -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>
</>
);
};

View file

@ -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}) {

View file

@ -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;

View file

@ -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 }
];

View 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' />
}
]
}
]
}
];

View file

@ -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[] = [
{

View file

@ -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 }) {

View file

@ -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';

View file

@ -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,