Skip to content

Commit 68fc926

Browse files
committed
misc: add WEBUI_PREFIX to define where the web ui should be mounted
1 parent 7cba228 commit 68fc926

29 files changed

+57
-48
lines changed

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
"parserOptions": {
2222
"project": "./tsconfig.json"
2323
},
24+
"globals": {
25+
"WEBUI_PREFIX": true
26+
},
2427
"settings": {
2528
"import/resolver": {
2629
"typescript": {}

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4+
<script>globalThis.WEBUI_PREFIX='/webui';if(!WEBUI_PREFIX)WEBUI_PREFIX='/';</script>
45
<meta charset="utf-8">
56
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
67
<title>Shoko</title>

src/components/Collection/CollectionTitle.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const CollectionTitle = React.memo(({ count, filterActive, filterName, groupName
2727
return (
2828
<div className="flex min-w-0 items-center gap-x-2 text-xl font-semibold">
2929
<Link
30-
to="/webui/collection"
30+
to="/collection"
3131
className={cx((filterName ?? groupName ?? filterActive) ? 'text-panel-text-primary' : 'pointer-events-none')}
3232
>
3333
Collection
@@ -36,7 +36,7 @@ const CollectionTitle = React.memo(({ count, filterActive, filterName, groupName
3636
<>
3737
<Icon className="flex-none" path={mdiChevronRight} size={1} />
3838
<Link
39-
to={`/webui/collection/group/${groupId}`}
39+
to={`/collection/group/${groupId}`}
4040
className={cx(
4141
(filterName ?? filterActive) ? 'text-panel-text-primary' : 'pointer-events-none',
4242
'truncate',

src/components/Collection/Series/EditSeriesTabs/DeleteActionsTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const DeleteActionsTab = ({ seriesId }: Props) => {
1414

1515
const { mutate: deleteSeries } = useDeleteSeriesMutation();
1616

17-
const navigateToCollection = () => navigate('/webui/collection');
17+
const navigateToCollection = () => navigate('/collection');
1818

1919
return (
2020
<div className="flex grow flex-col gap-y-4 overflow-y-auto">

src/components/Collection/SeriesInfo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const SeriesInfo = ({ series }: SeriesInfoProps) => {
5858
const [season, year] = overview.FirstAirSeason.split(' ');
5959
addFilterCriteriaToStore('InSeason').then(() => {
6060
dispatch(setFilterValues({ InSeason: [`${year}: ${season}`] }));
61-
navigate('/webui/collection/filter/live');
61+
navigate('/collection/filter/live');
6262
}).catch(console.error);
6363
});
6464

src/components/Collection/TagButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const TagButton = React.memo(({ tagType, text, type }: Props) => {
2323
dispatch(resetFilter());
2424
addFilterCriteriaToStore('HasTag').then(() => {
2525
dispatch(setFilterTag({ HasTag: [{ Name: text, isExcluded: false }] }));
26-
navigate('/webui/collection/filter/live');
26+
navigate('/collection/filter/live');
2727
}).catch(console.error);
2828
});
2929

src/components/Collection/Tags/TagDetailsModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import type { TagType } from '@/core/types/api/tags';
1616

1717
const SeriesLink = React.memo(({ extraPadding, series }: { series: SeriesType, extraPadding: boolean }) => (
1818
<Link
19-
to={`/webui/collection/series/${series.IDs.ID}`}
19+
to={`/collection/series/${series.IDs.ID}`}
2020
className={cx(
2121
'flex justify-between align-middle hover:text-panel-text-primary transition-colors',
2222
extraPadding && ('pr-4'),

src/components/Collection/TimelineSidebar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const TimelineItem = ({ series }: { series: SeriesType }) => {
1717

1818
return (
1919
<div className="flex gap-x-3" key={series.IDs.ID}>
20-
<Link to={`/webui/collection/series/${series.IDs.ID}`}>
20+
<Link to={`/collection/series/${series.IDs.ID}`}>
2121
<BackgroundImagePlaceholderDiv
2222
image={mainPoster}
2323
className="group h-24 w-[4.4375rem] shrink-0 rounded-lg border border-panel-border drop-shadow-md"
@@ -33,7 +33,7 @@ const TimelineItem = ({ series }: { series: SeriesType }) => {
3333
</div>
3434
<div className="line-clamp-2">
3535
<Link
36-
to={`/webui/collection/series/${series.IDs.ID}`}
36+
to={`/collection/series/${series.IDs.ID}`}
3737
className="transition-colors hover:text-panel-text-primary"
3838
data-tooltip-id="tooltip"
3939
data-tooltip-content={series.Name}

src/components/Collection/Tmdb/TopPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const TopPanel = (props: Props) => {
8686
buttonType="secondary"
8787
buttonSize="normal"
8888
className="flex flex-row flex-wrap items-center gap-x-2 py-3"
89-
onClick={() => navigate(`/webui/collection/series/${seriesId}`)}
89+
onClick={() => navigate(`/collection/series/${seriesId}`)}
9090
>
9191
Cancel
9292
</Button>

src/components/Dialogs/FilterPresetsModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const Item = ({ item, onClose }: { item: CollectionFilterType, onClose: () => vo
5252
)}
5353
key={item.IDs.ID}
5454
>
55-
<Link to={`/webui/collection/filter/${item.IDs.ID}`} onClick={handleClose}>{item.Name}</Link>
55+
<Link to={`/collection/filter/${item.IDs.ID}`} onClick={handleClose}>{item.Name}</Link>
5656
<span className="text-panel-text-important">{item.Size}</span>
5757
</div>
5858
);

src/components/ErrorBoundary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const ErrorBoundary = ({ error, resetError }: { error?: Error, resetError?: () =
6060
{routeError?.status === 404
6161
? (
6262
<Button
63-
onClick={() => navigate('/webui', { replace: true })}
63+
onClick={() => navigate('/', { replace: true })}
6464
className="px-4 py-2 drop-shadow-md"
6565
buttonType="primary"
6666
>

src/components/Layout/TopNav.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ function TopNav() {
130130
<Button
131131
onClick={() => {
132132
toast.dismiss('webui-update');
133-
navigate('/webui/dashboard');
133+
navigate('/dashboard');
134134
setTimeout(() => window.location.reload(), 100);
135135
}}
136136
buttonType="primary"
@@ -169,7 +169,7 @@ function TopNav() {
169169
)}
170170
>
171171
<div className="mx-auto flex w-full max-w-[120rem] items-center justify-between px-6 py-2">
172-
<Link to="/webui/dashboard" className="flex items-center gap-x-3">
172+
<Link to="/dashboard" className="flex items-center gap-x-3">
173173
<ShokoIcon className="w-20" />
174174
<span className="mt-1 text-2xl font-semibold text-header-text">Shoko</span>
175175
</Link>
@@ -235,7 +235,7 @@ function TopNav() {
235235
closeModalsAndSubmenus(undefined, 'utilities');
236236
setShowUtilitiesMenu(prev => !prev);
237237
}}
238-
isHighlighted={showUtilitiesMenu || startsWith(pathname, '/webui/utilities/')}
238+
isHighlighted={showUtilitiesMenu || startsWith(pathname, '/utilities/')}
239239
/>
240240
<LinkMenuItem
241241
onClick={closeModalsAndSubmenus}
@@ -255,7 +255,7 @@ function TopNav() {
255255
/>
256256
</div>
257257
<div className="flex justify-end gap-6">
258-
{pathname === '/webui/dashboard' && (
258+
{pathname === '/dashboard' && (
259259
<MenuItem
260260
id="dashboard-settings"
261261
text="Dashboard Settings"

src/components/SeriesPoster.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const SeriesPoster = React.memo((props: Props) => {
8383

8484
if (shokoId) {
8585
return (
86-
<Link className={cx(baseClassName, 'group')} to={`/webui/collection/series/${shokoId}`}>
86+
<Link className={cx(baseClassName, 'group')} to={`/collection/series/${shokoId}`}>
8787
{content}
8888
</Link>
8989
);

src/components/Utilities/ReleaseManagement/SeriesList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const seriesColumns: UtilityHeaderType<ReleaseManagementSeriesType>[] = [
4444
</div>
4545
</a>
4646
<span>|</span>
47-
<Link to={`/webui/collection/series/${series.IDs.ID}`}>
47+
<Link to={`/collection/series/${series.IDs.ID}`}>
4848
<div className="flex items-center gap-x-2 font-semibold text-panel-text-primary">
4949
<ShokoIcon className="size-6" />
5050
{series.IDs.ID}

src/core/router/AuthenticatedRoute.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function AuthenticatedRoute(props: Props) {
1919

2020
return (serverState === 'Started' && isAuthenticated)
2121
? props.children
22-
: <Navigate to={from === '/' || from === '/webui/' ? '/webui/login' : `/webui/login?redirectTo=${from}`} replace />;
22+
: <Navigate to={from === '/' ? '/login' : `/login?redirectTo=${from}`} replace />;
2323
}
2424

2525
export default AuthenticatedRoute;

src/core/router/index.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,13 @@ import AuthenticatedRoute from './AuthenticatedRoute';
5252

5353
import type { RootState } from '@/core/store';
5454

55-
const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV7(createBrowserRouter);
55+
const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV7(createBrowserRouter) as typeof createBrowserRouter;
5656

5757
const router = sentryCreateBrowserRouter(
5858
createRoutesFromElements(
5959
<Route path="/" errorElement={<ErrorBoundary />}>
60-
<Route index element={<Navigate to="/webui" replace />} />
61-
<Route path="index.html" element={<Navigate to="/webui" replace />} />
62-
<Route path="webui" element={<SentryErrorBoundaryWrapper />}>
63-
<Route path="index.html" element={<Navigate to="/webui" replace />} />
60+
<Route element={<SentryErrorBoundaryWrapper />}>
61+
<Route path="index.html" element={<Navigate to="/" replace />} />
6462
<Route path="login" element={<LoginPage />} />
6563
<Route path="firstrun" element={<FirstRunPage />}>
6664
<Route index element={<Navigate to="acknowledgement" replace />} />
@@ -128,6 +126,9 @@ const router = sentryCreateBrowserRouter(
128126
</Route>
129127
</Route>,
130128
),
129+
{
130+
basename: WEBUI_PREFIX.slice(0, -1) || '/',
131+
},
131132
);
132133

133134
const Router = () => {

src/env.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
/// <reference types="vite/client" />
2+
3+
// eslint-disable-next-line no-var
4+
declare var WEBUI_PREFIX: string;
5+
26
/* eslint-disable-next-line @typescript-eslint/consistent-type-definitions */
37
interface ImportMetaEnv {
48
readonly VITE_GITHASH: string;

src/hooks/collection/useRouteLink.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const useRouteLink = (item: CollectionGroupType | SeriesType) => {
88
const { filterId, groupId } = useParams();
99

1010
return useMemo(() => {
11-
let link = '/webui/collection';
11+
let link = '/collection';
1212

1313
if (groupId) {
1414
return `${link}/series/${item.IDs.ID}`;

src/pages/SentryErrorBoundaryWrapper.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ const SentryErrorBoundaryWrapper = () => {
3131
if (semverVersion && semver.lt(semverVersion, minimumVersion)) isServerSupported = false;
3232

3333
if (!isServerSupported) {
34-
navigate('/webui/unsupported');
35-
} else if (pathname === '/webui/unsupported') {
36-
navigate('/webui');
34+
navigate('/unsupported');
35+
} else if (pathname === '/unsupported') {
36+
navigate('/');
3737
}
3838
}, [navigate, pathname, versionQuery.data]);
3939

src/pages/collection/Series.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ const Series = () => {
112112
<div className="flex flex-col gap-y-6" ref={containerRef}>
113113
<div className="my-6 flex flex-col items-center gap-y-3">
114114
<div className="flex flex-row items-center gap-x-4">
115-
<Link className="text-xl font-semibold text-panel-text-primary" to="/webui/collection">
115+
<Link className="text-xl font-semibold text-panel-text-primary" to="/collection">
116116
Collection
117117
</Link>
118118
<Icon className="flex-none text-panel-icon" path={mdiChevronRight} size={1} />
119119
{groupQuery.isSuccess && groupQuery.data.Size > 1 && (
120120
<>
121121
<Link
122122
className="text-xl font-semibold text-panel-text-primary"
123-
to={`/webui/collection/group/${series.IDs.ParentGroup}`}
123+
to={`/collection/group/${series.IDs.ParentGroup}`}
124124
>
125125
{groupQuery.data.Name}
126126
</Link>

src/pages/dashboard/panels/CollectionStats.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const Item = (
2020
const handleMissingFilter = useEventCallback((filterName: string) => {
2121
dispatch(resetFilter());
2222
addFilterCriteriaToStore(filterName).then(() => {
23-
navigate('/webui/collection/filter/live');
23+
navigate('/collection/filter/live');
2424
}).catch(console.error);
2525
});
2626

@@ -67,25 +67,25 @@ function CollectionStats() {
6767
key="files"
6868
title="Files"
6969
value={statsQuery.data?.FileCount}
70-
link="/webui/utilities/file-search"
70+
link="/utilities/file-search"
7171
/>,
7272
<Item
7373
key="unrecognized-files"
7474
title="Unknown Files"
7575
value={statsQuery.data?.UnrecognizedFiles}
76-
link="/webui/utilities/unrecognized"
76+
link="/utilities/unrecognized"
7777
/>,
7878
<Item
7979
key="multiple-files"
8080
title="Duplicate Episodes"
8181
value={statsQuery.data?.EpisodesWithMultipleFiles}
82-
link="/webui/utilities/release-management/multiples"
82+
link="/utilities/release-management/multiples"
8383
/>,
8484
<Item
8585
key="duplicate-files"
8686
title="Duplicate Hashes"
8787
value={statsQuery.data?.FilesWithDuplicateLocations}
88-
link="/webui/utilities/release-management/duplicates"
88+
link="/utilities/release-management/duplicates"
8989
/>,
9090
];
9191

@@ -100,13 +100,13 @@ function CollectionStats() {
100100
key="missing-episodes-collecting"
101101
title="Missing Episodes (Collecting)"
102102
value={statsQuery.data?.MissingEpisodesCollecting}
103-
link="/webui/utilities/release-management/missing-episodes?onlyCollecting=true"
103+
link="/utilities/release-management/missing-episodes?onlyCollecting=true"
104104
/>,
105105
<Item
106106
key="missing-episodes"
107107
title="Missing Episodes (Total)"
108108
value={statsQuery.data?.MissingEpisodes}
109-
link="/webui/utilities/release-management/missing-episodes"
109+
link="/utilities/release-management/missing-episodes"
110110
/>,
111111
];
112112

src/pages/firstrun/FirstRunPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const MenuItem = ({ id, text }: { text: string, id: string }) => {
1919
const saved = useSelector((state: RootState) => state.firstrun.saved);
2020

2121
const path = useMemo(() => {
22-
if (pathname === `/webui/firstrun/${id}`) return mdiCircleHalfFull;
22+
if (pathname === `/firstrun/${id}`) return mdiCircleHalfFull;
2323
if (saved[id]) return mdiCheckboxMarkedCircleOutline;
2424
return mdiCheckboxBlankCircleOutline;
2525
}, [pathname, saved, id]);

src/pages/firstrun/Footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function Footer(props: Props) {
3131

3232
const handleFinish = useEventCallback(() => {
3333
runAction('RunImport');
34-
navigate('/webui/dashboard', { replace: true, state: { firstRun: true } });
34+
navigate('/dashboard', { replace: true, state: { firstRun: true } });
3535
});
3636

3737
const {

src/pages/login/LoginPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function LoginPage() {
5050

5151
const setRedirect = () => {
5252
if (seriesId === 0) return;
53-
setSearchParams(`redirectTo=/webui/collection/series/${seriesId}`, { replace: true });
53+
setSearchParams(`redirectTo=/collection/series/${seriesId}`, { replace: true });
5454
};
5555

5656
useEffect(() => {
@@ -72,7 +72,7 @@ function LoginPage() {
7272
else if (serverStatusQuery.data?.State !== 'Starting') setPollingInterval(0);
7373

7474
if (serverStatusQuery.data?.State === 'Started' && apiSession.apikey !== '') {
75-
navigate(searchParams.get('redirectTo') ?? '/webui', { replace: true });
75+
navigate(searchParams.get('redirectTo') ?? '/', { replace: true });
7676
}
7777
}, [serverStatusQuery.data, apiSession, navigate, searchParams]);
7878

@@ -90,7 +90,7 @@ function LoginPage() {
9090
{
9191
onSuccess: () => {
9292
setLoginError(false);
93-
navigate(searchParams.get('redirectTo') ?? '/webui');
93+
navigate(searchParams.get('redirectTo') ?? '/');
9494
},
9595
onError: () => setLoginError(true),
9696
},
@@ -224,7 +224,7 @@ function LoginPage() {
224224
</div>
225225
</div>
226226
<Button
227-
onClick={() => navigate('/webui/firstrun')}
227+
onClick={() => navigate('/firstrun')}
228228
buttonType="primary"
229229
className="py-2 font-semibold"
230230
>

src/pages/utilities/FileSearch.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ const Menu = (
133133

134134
const handleRename = useEventCallback(() => {
135135
dispatch(addFiles(selectedRows));
136-
navigate('/webui/utilities/renamer');
136+
navigate('/utilities/renamer');
137137
});
138138

139139
return (
@@ -306,7 +306,7 @@ const FileDetails = React.memo(({ fileId }: { fileId: number }) => {
306306
<div className="flex flex-col gap-y-1">
307307
<div className="flex justify-between">
308308
<span className="font-semibold">Series Name</span>
309-
<Link to={`/webui/collection/series/${seriesId}`}>
309+
<Link to={`/collection/series/${seriesId}`}>
310310
<div className="flex items-center gap-x-2 font-semibold text-panel-text-primary">
311311
<ShokoIcon className="size-6" />
312312
Shoko

src/pages/utilities/SeriesWithoutFilesUtility.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const columns: UtilityHeaderType<SeriesType>[] = [
4040
className: 'w-32',
4141
item: series => (
4242
<Link
43-
to={`/webui/collection/series/${series.IDs.ID}`}
43+
to={`/collection/series/${series.IDs.ID}`}
4444
className="flex gap-x-2 text-panel-text-primary"
4545
>
4646
{series.IDs.ID}

0 commit comments

Comments
 (0)