Skip to content

Commit 161a968

Browse files
committed
Improve event route handling for legacy URLs
Replaces the redirect function with a beforeEnter guard to support old-style event URLs without repetitionId or tab. The new logic normalizes paths, distinguishes between repetitionId and tab segments, and ensures users are redirected to the correct route format, improving backward compatibility.
1 parent 61a76be commit 161a968

File tree

1 file changed

+70
-7
lines changed

1 file changed

+70
-7
lines changed

src/router.ts

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,79 @@ const router = createRouter({
123123
path: 'event/:eventId/:repetitionId?',
124124
name: 'event',
125125
component: () => import(/* webpackChunkName: 'event-overview' */ './components/event/Layout.vue'),
126-
redirect: (to) => {
127-
const projectId = to.params.projectId as string;
128-
const eventId = to.params.eventId as string;
129-
const repetitionId = to.params.repetitionId as string | undefined;
126+
// eslint-disable-next-line jsdoc/require-param
127+
/**
128+
* Support old-style event urls:
129+
* - without repetitionId
130+
* - without tab
131+
*/
132+
beforeEnter: (to, from, next) => {
133+
/**
134+
* Normalize path by removing trailing slashes
135+
*/
136+
const normalizedPath = to.path.replace(/\/+$/, '');
130137

131-
if (repetitionId !== undefined && repetitionId !== '') {
132-
return `/project/${projectId}/event/${eventId}/${repetitionId}/overview`;
138+
/**
139+
* Match the event route path pattern:
140+
* /project/:projectId/event/:eventId[/:repetitionId][/:tab]
141+
*/
142+
const pathMatch = normalizedPath.match(
143+
/^\/project\/([^/]+)\/event\/([^/]+)(?:\/([^/]+))?(?:\/([^/]+))?$/
144+
);
145+
146+
if (!pathMatch) {
147+
next();
148+
149+
return;
150+
}
151+
152+
const projectId = pathMatch[1];
153+
const eventId = pathMatch[2];
154+
const segment3 = pathMatch[3];
155+
const segment4 = pathMatch[4];
156+
const knownTabs = new Set(['overview', 'repetitions', 'daily', 'affected']);
157+
158+
/**
159+
* Determine if segment3 is a tab name or a repetitionId
160+
*/
161+
const isSegment3Tab = segment3 !== undefined && knownTabs.has(segment3);
162+
163+
/**
164+
* Legacy format: /project/:projectId/event/:eventId/:tab
165+
* segment3 is a tab, segment4 is undefined
166+
*/
167+
if (isSegment3Tab && segment4 === undefined) {
168+
next(`/project/${projectId}/event/${eventId}/${eventId}/${segment3}`);
169+
170+
return;
171+
}
172+
173+
/**
174+
* Normal format: /project/:projectId/event/:eventId/:repetitionId/:tab
175+
* segment3 is repetitionId, segment4 is tab
176+
*/
177+
if (segment3 !== undefined && !isSegment3Tab && segment4 !== undefined) {
178+
/**
179+
* Already in correct format, continue
180+
*/
181+
next();
182+
183+
return;
184+
}
185+
186+
/**
187+
* Missing tab: /project/:projectId/event/:eventId[/:repetitionId]
188+
* Redirect to overview
189+
*/
190+
if (segment4 === undefined) {
191+
const repetitionId = segment3 && !isSegment3Tab ? segment3 : eventId;
192+
193+
next(`/project/${projectId}/event/${eventId}/${repetitionId}/overview`);
194+
195+
return;
133196
}
134197

135-
return `/project/${projectId}/event/${eventId}/${eventId}/overview`;
198+
next();
136199
},
137200
children: [
138201
{

0 commit comments

Comments
 (0)