From 93ef17a132d0bcc5f77242ad41aa577d2c1be5bc Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 23 Jan 2025 16:09:49 -0500 Subject: [PATCH 1/3] Refactor asyncRouteType to appType --- src/apps/dashboard/routes/_asyncRoutes.ts | 27 ++++++++++--------- src/apps/dashboard/routes/routes.tsx | 1 + .../experimental/routes/asyncRoutes/user.ts | 18 ++++++------- src/components/router/AsyncRoute.tsx | 23 +++++----------- src/constants/appType.ts | 8 ++++++ 5 files changed, 38 insertions(+), 39 deletions(-) create mode 100644 src/constants/appType.ts diff --git a/src/apps/dashboard/routes/_asyncRoutes.ts b/src/apps/dashboard/routes/_asyncRoutes.ts index f0c3e13586..eb42010cf3 100644 --- a/src/apps/dashboard/routes/_asyncRoutes.ts +++ b/src/apps/dashboard/routes/_asyncRoutes.ts @@ -1,16 +1,17 @@ -import { AsyncRouteType, type AsyncRoute } from 'components/router/AsyncRoute'; +import type { AsyncRoute } from 'components/router/AsyncRoute'; +import { AppType } from 'constants/appType'; export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [ - { path: 'activity', type: AsyncRouteType.Dashboard }, - { path: 'branding', type: AsyncRouteType.Dashboard }, - { path: 'keys', type: AsyncRouteType.Dashboard }, - { path: 'logs', type: AsyncRouteType.Dashboard }, - { path: 'playback/trickplay', type: AsyncRouteType.Dashboard }, - { path: 'plugins/:pluginId', page: 'plugins/plugin', 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 } + { path: 'activity', type: AppType.Dashboard }, + { path: 'branding', type: AppType.Dashboard }, + { path: 'keys', type: AppType.Dashboard }, + { path: 'logs', type: AppType.Dashboard }, + { path: 'playback/trickplay', type: AppType.Dashboard }, + { path: 'plugins/:pluginId', page: 'plugins/plugin', type: AppType.Dashboard }, + { path: 'users', type: AppType.Dashboard }, + { path: 'users/access', type: AppType.Dashboard }, + { path: 'users/add', type: AppType.Dashboard }, + { path: 'users/parentalcontrol', type: AppType.Dashboard }, + { path: 'users/password', type: AppType.Dashboard }, + { path: 'users/profile', type: AppType.Dashboard } ]; diff --git a/src/apps/dashboard/routes/routes.tsx b/src/apps/dashboard/routes/routes.tsx index bd7d926f03..576bdd6202 100644 --- a/src/apps/dashboard/routes/routes.tsx +++ b/src/apps/dashboard/routes/routes.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { RouteObject } from 'react-router-dom'; + import ConnectionRequired from 'components/ConnectionRequired'; import { ASYNC_ADMIN_ROUTES } from './_asyncRoutes'; import { toAsyncPageRoute } from 'components/router/AsyncRoute'; diff --git a/src/apps/experimental/routes/asyncRoutes/user.ts b/src/apps/experimental/routes/asyncRoutes/user.ts index 20af699bf1..7c9fd8ba5a 100644 --- a/src/apps/experimental/routes/asyncRoutes/user.ts +++ b/src/apps/experimental/routes/asyncRoutes/user.ts @@ -1,15 +1,15 @@ -import { AsyncRoute, AsyncRouteType } from '../../../../components/router/AsyncRoute'; +import { AsyncRoute } from 'components/router/AsyncRoute'; +import { AppType } from 'constants/appType'; export const ASYNC_USER_ROUTES: AsyncRoute[] = [ - { path: 'home.html', page: 'home', type: AsyncRouteType.Experimental }, + { path: 'home.html', page: 'home', type: AppType.Experimental }, { path: 'quickconnect', page: 'quickConnect' }, { path: 'search.html', page: 'search' }, { path: 'userprofile.html', page: 'user/userprofile' }, - { path: 'movies.html', page: 'movies', type: AsyncRouteType.Experimental }, - { path: 'tv.html', page: 'shows', type: AsyncRouteType.Experimental }, - { path: 'music.html', page: 'music', type: AsyncRouteType.Experimental }, - { path: 'livetv.html', page: 'livetv', type: AsyncRouteType.Experimental }, - { path: 'mypreferencesdisplay.html', page: 'user/display', type: AsyncRouteType.Experimental }, - - { path: 'homevideos.html', page: 'homevideos', type: AsyncRouteType.Experimental } + { path: 'movies.html', page: 'movies', type: AppType.Experimental }, + { path: 'tv.html', page: 'shows', type: AppType.Experimental }, + { path: 'music.html', page: 'music', type: AppType.Experimental }, + { path: 'livetv.html', page: 'livetv', type: AppType.Experimental }, + { path: 'mypreferencesdisplay.html', page: 'user/display', type: AppType.Experimental }, + { path: 'homevideos.html', page: 'homevideos', type: AppType.Experimental } ]; diff --git a/src/components/router/AsyncRoute.tsx b/src/components/router/AsyncRoute.tsx index c18cd05396..cab2144a1b 100644 --- a/src/components/router/AsyncRoute.tsx +++ b/src/components/router/AsyncRoute.tsx @@ -1,10 +1,6 @@ import type { RouteObject } from 'react-router-dom'; -export enum AsyncRouteType { - Stable, - Experimental, - Dashboard -} +import { AppType } from 'constants/appType'; export interface AsyncRoute { /** The URL path for this route. */ @@ -14,25 +10,18 @@ export interface AsyncRoute { * Will fallback to using the `path` value if not specified. */ page?: string - /** The page type used to load the correct page element. */ - type?: AsyncRouteType + /** The app that this page is part of. */ + type?: AppType } -const importRoute = (page: string, type: AsyncRouteType) => { - switch (type) { - case AsyncRouteType.Dashboard: - return import(/* webpackChunkName: "[request]" */ `../../apps/dashboard/routes/${page}`); - case AsyncRouteType.Experimental: - return import(/* webpackChunkName: "[request]" */ `../../apps/experimental/routes/${page}`); - case AsyncRouteType.Stable: - return import(/* webpackChunkName: "[request]" */ `../../apps/stable/routes/${page}`); - } +const importRoute = (page: string, type: AppType) => { + return import(/* webpackChunkName: "[request]" */ `../../apps/${type}/routes/${page}`); }; export const toAsyncPageRoute = ({ path, page, - type = AsyncRouteType.Stable + type = AppType.Stable }: AsyncRoute): RouteObject => { return { path, diff --git a/src/constants/appType.ts b/src/constants/appType.ts new file mode 100644 index 0000000000..efed1f5ffa --- /dev/null +++ b/src/constants/appType.ts @@ -0,0 +1,8 @@ +/** + * App types represented in src/apps. + */ +export enum AppType { + Dashboard = 'dashboard', + Experimental = 'experimental', + Stable = 'stable' +} From 80a26d58227c603b054078ef41febb987f2ac778 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 23 Jan 2025 16:26:49 -0500 Subject: [PATCH 2/3] Add appType support for legacy routes --- src/apps/dashboard/routes/_legacyRoutes.ts | 22 +++++++++++++++++++ .../viewManager/ViewManagerPage.tsx | 14 +++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/apps/dashboard/routes/_legacyRoutes.ts b/src/apps/dashboard/routes/_legacyRoutes.ts index 342a8ee65c..56e19ccc11 100644 --- a/src/apps/dashboard/routes/_legacyRoutes.ts +++ b/src/apps/dashboard/routes/_legacyRoutes.ts @@ -1,129 +1,151 @@ import type { LegacyRoute } from 'components/router/LegacyRoute'; +import { AppType } from 'constants/appType'; export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [ { path: '/dashboard', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/dashboard', view: 'dashboard/dashboard.html' } }, { path: 'settings', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/general', view: 'dashboard/general.html' } }, { path: 'networking', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/networking', view: 'dashboard/networking.html' } }, { path: 'devices', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/devices/devices', view: 'dashboard/devices/devices.html' } }, { path: 'devices/edit', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/devices/device', view: 'dashboard/devices/device.html' } }, { path: 'libraries', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/library', view: 'dashboard/library.html' } }, { path: 'libraries/display', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/librarydisplay', view: 'dashboard/librarydisplay.html' } }, { path: 'playback/transcoding', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/encodingsettings', view: 'dashboard/encodingsettings.html' } }, { path: 'libraries/metadata', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/metadataImages', view: 'dashboard/metadataimages.html' } }, { path: 'libraries/nfo', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/metadatanfo', view: 'dashboard/metadatanfo.html' } }, { path: 'playback/resume', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/playback', view: 'dashboard/playback.html' } }, { path: 'plugins/catalog', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/plugins/available/index', view: 'dashboard/plugins/available/index.html' } }, { path: 'plugins/repositories', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/plugins/repositories/index', view: 'dashboard/plugins/repositories/index.html' } }, { path: 'livetv/guide', pageProps: { + appType: AppType.Dashboard, controller: 'livetvguideprovider', view: 'livetvguideprovider.html' } }, { path: 'recordings', pageProps: { + appType: AppType.Dashboard, controller: 'livetvsettings', view: 'livetvsettings.html' } }, { path: 'livetv', pageProps: { + appType: AppType.Dashboard, controller: 'livetvstatus', view: 'livetvstatus.html' } }, { path: 'livetv/tuner', pageProps: { + appType: AppType.Dashboard, controller: 'livetvtuner', view: 'livetvtuner.html' } }, { path: 'plugins', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/plugins/installed/index', view: 'dashboard/plugins/installed/index.html' } }, { path: 'tasks/edit', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/scheduledtasks/scheduledtask', view: 'dashboard/scheduledtasks/scheduledtask.html' } }, { path: 'tasks', pageProps: { + appType: AppType.Dashboard, controller: 'dashboard/scheduledtasks/scheduledtasks', view: 'dashboard/scheduledtasks/scheduledtasks.html' } }, { path: 'playback/streaming', pageProps: { + appType: AppType.Dashboard, view: 'dashboard/streaming.html', controller: 'dashboard/streaming' } diff --git a/src/components/viewManager/ViewManagerPage.tsx b/src/components/viewManager/ViewManagerPage.tsx index efba34f2d6..3f6d258d98 100644 --- a/src/components/viewManager/ViewManagerPage.tsx +++ b/src/components/viewManager/ViewManagerPage.tsx @@ -6,8 +6,10 @@ import globalize from 'lib/globalize'; import type { RestoreViewFailResponse } from 'types/viewManager'; import viewManager from './viewManager'; +import { AppType } from 'constants/appType'; export interface ViewManagerPageProps { + appType?: AppType controller: string view: string type?: string @@ -31,7 +33,12 @@ interface ViewOptions { } } -const loadView = async (controller: string, view: string, viewOptions: ViewOptions) => { +const loadView = async ( + appType: AppType, + controller: string, + view: string, + viewOptions: ViewOptions +) => { const [ controllerFactory, viewHtml ] = await Promise.all([ import(/* webpackChunkName: "[request]" */ `../../controllers/${controller}`), import(/* webpackChunkName: "[request]" */ `../../controllers/${view}`) @@ -50,6 +57,7 @@ const loadView = async (controller: string, view: string, viewOptions: ViewOptio * NOTE: Any new pages should use the generic Page component instead. */ const ViewManagerPage: FunctionComponent = ({ + appType = AppType.Stable, controller, view, type, @@ -78,7 +86,7 @@ const ViewManagerPage: FunctionComponent = ({ if (navigationType !== Action.Pop) { console.debug('[ViewManagerPage] loading view [%s]', view); - return loadView(controller, view, viewOptions); + return loadView(appType, controller, view, viewOptions); } console.debug('[ViewManagerPage] restoring view [%s]', view); @@ -86,7 +94,7 @@ const ViewManagerPage: FunctionComponent = ({ .catch(async (result?: RestoreViewFailResponse) => { if (!result?.cancelled) { console.debug('[ViewManagerPage] restore failed; loading view [%s]', view); - return loadView(controller, view, viewOptions); + return loadView(appType, controller, view, viewOptions); } }); }; From 91d8a3fffda507e128bc623945dbc30f0de3a113 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 23 Jan 2025 16:51:14 -0500 Subject: [PATCH 3/3] Revert importRoute simplification This caused tests to be included in the built files --- src/components/router/AsyncRoute.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/router/AsyncRoute.tsx b/src/components/router/AsyncRoute.tsx index cab2144a1b..ac878e01c8 100644 --- a/src/components/router/AsyncRoute.tsx +++ b/src/components/router/AsyncRoute.tsx @@ -15,7 +15,14 @@ export interface AsyncRoute { } const importRoute = (page: string, type: AppType) => { - return import(/* webpackChunkName: "[request]" */ `../../apps/${type}/routes/${page}`); + switch (type) { + case AppType.Dashboard: + return import(/* webpackChunkName: "[request]" */ `../../apps/dashboard/routes/${page}`); + case AppType.Experimental: + return import(/* webpackChunkName: "[request]" */ `../../apps/experimental/routes/${page}`); + case AppType.Stable: + return import(/* webpackChunkName: "[request]" */ `../../apps/stable/routes/${page}`); + } }; export const toAsyncPageRoute = ({