From 65d152dc0b1ae97981b76bc0a24755e6e69c763a Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Thu, 2 Nov 2023 17:43:27 +0100 Subject: [PATCH 1/2] Utilize `keyOfId` function in appropriate places --- frontend/src/routes/Search.tsx | 5 +++-- frontend/src/routes/manage/Video/Access.tsx | 4 ++-- frontend/src/routes/manage/Video/Details.tsx | 4 ++-- frontend/src/routes/manage/Video/Shared.tsx | 4 ++-- frontend/src/routes/manage/Video/TechnicalDetails.tsx | 3 ++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/frontend/src/routes/Search.tsx b/frontend/src/routes/Search.tsx index 6fc36f8f9..84564ad79 100644 --- a/frontend/src/routes/Search.tsx +++ b/frontend/src/routes/Search.tsx @@ -18,6 +18,7 @@ import { MissingRealmName } from "./util"; import { ellipsisOverflowCss } from "../ui"; import { COLORS } from "../color"; import { BREAKPOINT_SMALL } from "../GlobalStyle"; +import { keyOfId } from "../util"; export const isSearchActive = (): boolean => document.location.pathname === "/~search"; @@ -195,8 +196,8 @@ const SearchEvent: React.FC = ({ // TODO: decide what to do in the case of more than two host realms. Direct // link should be avoided. const link = hostRealms.length !== 1 - ? `/!v/${id.slice(2)}` - : `${hostRealms[0].path.replace(/^\/$/, "")}/v/${id.slice(2)}`; + ? `/!v/${(keyOfId(id))}` + : `${hostRealms[0].path.replace(/^\/$/, "")}/v/${keyOfId(id)}`; return ( diff --git a/frontend/src/routes/manage/Video/Access.tsx b/frontend/src/routes/manage/Video/Access.tsx index b398180c6..801c48743 100644 --- a/frontend/src/routes/manage/Video/Access.tsx +++ b/frontend/src/routes/manage/Video/Access.tsx @@ -10,7 +10,7 @@ import { isRealUser, useUser } from "../../../User"; import { NotAuthorized } from "../../../ui/error"; import { WithTooltip } from "@opencast/appkit"; import { Modal, ModalHandle } from "../../../ui/Modal"; -import { currentRef } from "../../../util"; +import { currentRef, keyOfId } from "../../../util"; import { COMMON_ROLES } from "../../../util/roles"; import { Acl, AclSelector, knownRolesFragement } from "../../../ui/Access"; import { useNavBlocker } from "../../util"; @@ -45,7 +45,7 @@ const AclPage: React.FC = ({ event, data }) => { const breadcrumbs = [ { label: t("user.manage-content"), link: "/~manage" }, { label: t("manage.my-videos.title"), link: "/~manage/videos" }, - { label: event.title, link: `/~manage/videos/${event.id.substring(2)}` }, + { label: event.title, link: `/~manage/videos/${keyOfId(event.id)}` }, ]; return <> diff --git a/frontend/src/routes/manage/Video/Details.tsx b/frontend/src/routes/manage/Video/Details.tsx index 210374268..17ddcfa27 100644 --- a/frontend/src/routes/manage/Video/Details.tsx +++ b/frontend/src/routes/manage/Video/Details.tsx @@ -14,7 +14,7 @@ import { AuthorizedEvent, makeManageVideoRoute, PAGE_WIDTH } from "./Shared"; import { ExternalLink } from "../../../relay/auth"; import { buttonStyle } from "../../../ui/Button"; import { COLORS } from "../../../color"; -import { secondsToTimeString } from "../../../util"; +import { keyOfId, secondsToTimeString } from "../../../util"; export const ManageVideoDetailsRoute = makeManageVideoRoute( @@ -79,7 +79,7 @@ const DirectLink: React.FC = ({ event }) => { const [timestamp, setTimestamp] = useState(0); const [checkboxChecked, setCheckboxChecked] = useState(false); - let url = new URL(`/!v/${event.id.slice(2)}`, document.baseURI); + let url = new URL(`/!v/${keyOfId(event.id)}`, document.baseURI); if (timestamp && checkboxChecked) { url = new URL(url + `?t=${secondsToTimeString(timestamp)}`); } diff --git a/frontend/src/routes/manage/Video/Shared.tsx b/frontend/src/routes/manage/Video/Shared.tsx index 4ccd35ab2..9e7ce4b52 100644 --- a/frontend/src/routes/manage/Video/Shared.tsx +++ b/frontend/src/routes/manage/Video/Shared.tsx @@ -13,7 +13,7 @@ import { b64regex } from "../../util"; import { Thumbnail } from "../../../ui/Video"; import { SharedVideoManageQuery } from "./__generated__/SharedVideoManageQuery.graphql"; import { Link } from "../../../router"; -import { isExperimentalFlagSet } from "../../../util"; +import { isExperimentalFlagSet, keyOfId } from "../../../util"; export const PAGE_WIDTH = 1100; @@ -133,7 +133,7 @@ const ManageVideoNav: React.FC = ({ event, active }) => { return null; } - const id = event.id.substring(2); + const id = keyOfId(event.id); const entries = [ { diff --git a/frontend/src/routes/manage/Video/TechnicalDetails.tsx b/frontend/src/routes/manage/Video/TechnicalDetails.tsx index f69bf18d8..3b264a273 100644 --- a/frontend/src/routes/manage/Video/TechnicalDetails.tsx +++ b/frontend/src/routes/manage/Video/TechnicalDetails.tsx @@ -7,6 +7,7 @@ import { PageTitle } from "../../../layout/header/ui"; import { AuthorizedEvent, makeManageVideoRoute, PAGE_WIDTH } from "./Shared"; import { CopyableInput } from "../../../ui/Input"; import { COLORS } from "../../../color"; +import { keyOfId } from "../../../util"; export const ManageVideoTechnicalDetailsRoute = makeManageVideoRoute( @@ -35,7 +36,7 @@ const Page: React.FC = ({ event }) => { const breadcrumbs = [ { label: t("user.manage-content"), link: "/~manage" }, { label: t("manage.my-videos.title"), link: "/~manage/videos" }, - { label: event.title, link: `/~manage/videos/${event.id.substring(2)}` }, + { label: event.title, link: `/~manage/videos/${keyOfId(event.id)}` }, ]; const user = useUser(); From f20a150f8731850b7c6efa4e30dfdd64092d2a1a Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Thu, 2 Nov 2023 18:00:33 +0100 Subject: [PATCH 2/2] Add gql id building functions --- frontend/src/routes/Embed.tsx | 5 ++--- frontend/src/routes/Series.tsx | 4 ++-- frontend/src/routes/Video.tsx | 7 +++---- frontend/src/routes/manage/Video/Shared.tsx | 4 ++-- frontend/src/util/index.ts | 6 ++++++ 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/frontend/src/routes/Embed.tsx b/frontend/src/routes/Embed.tsx index 4502691af..c2a5649a4 100644 --- a/frontend/src/routes/Embed.tsx +++ b/frontend/src/routes/Embed.tsx @@ -4,7 +4,7 @@ import { Translation, useTranslation } from "react-i18next"; import { graphql, PreloadedQuery, usePreloadedQuery } from "react-relay"; import { unreachable } from "@opencast/appkit"; -import { isSynced } from "../util"; +import { eventId, isSynced } from "../util"; import { GlobalErrorBoundary } from "../util/err"; import { loadQuery } from "../relay"; import { makeRoute } from "../rauta"; @@ -46,9 +46,8 @@ export const EmbedVideoRoute = makeRoute(url => { return null; } const videoId = decodeURIComponent(params[1]); - const eventId = `ev${videoId}`; - const queryRef = loadQuery(query, { id: eventId }); + const queryRef = loadQuery(query, { id: eventId(videoId) }); return { render: () => diff --git a/frontend/src/routes/Series.tsx b/frontend/src/routes/Series.tsx index 619ab1099..ea472db4c 100644 --- a/frontend/src/routes/Series.tsx +++ b/frontend/src/routes/Series.tsx @@ -8,7 +8,7 @@ import { RootLoader } from "../layout/Root"; import { Nav } from "../layout/Navigation"; import { PageTitle } from "../layout/header/ui"; import { WaitingPage } from "../ui/Waiting"; -import { isSynced } from "../util"; +import { isSynced, seriesId } from "../util"; import { NotFound } from "./NotFound"; import { SeriesByOpencastIdQuery } from "./__generated__/SeriesByOpencastIdQuery.graphql"; @@ -65,7 +65,7 @@ export const DirectSeriesRoute = makeRoute(url => { rootRealm { ... NavigationData } } `; - const queryRef = loadQuery(query, { id: `sr${id}` }); + const queryRef = loadQuery(query, { id: seriesId(id) }); return { diff --git a/frontend/src/routes/Video.tsx b/frontend/src/routes/Video.tsx index e2d29b7c5..b8b0ef3ff 100644 --- a/frontend/src/routes/Video.tsx +++ b/frontend/src/routes/Video.tsx @@ -31,6 +31,7 @@ import { translatedConfig, currentRef, secondsToTimeString, + eventId, } from "../util"; import { BREAKPOINT_SMALL, BREAKPOINT_MEDIUM } from "../GlobalStyle"; import { Button, LinkButton } from "../ui/Button"; @@ -102,8 +103,7 @@ export const VideoRoute = makeRoute(url => { } `; const realmPath = "/" + realmPathParts.join("/"); - const eventId = `ev${videoId}`; - const queryRef = loadQuery(query, { id: eventId, realmPath }); + const queryRef = loadQuery(query, { id: eventId(videoId), realmPath }); return { render: () => { } `; const videoId = decodeURIComponent(params[1]); - const eventId = `ev${videoId}`; - const queryRef = loadQuery(query, { id: eventId }); + const queryRef = loadQuery(query, { id: eventId(videoId) }); return matchedDirectRoute(query, queryRef); }); diff --git a/frontend/src/routes/manage/Video/Shared.tsx b/frontend/src/routes/manage/Video/Shared.tsx index 9e7ce4b52..cfb0e10f1 100644 --- a/frontend/src/routes/manage/Video/Shared.tsx +++ b/frontend/src/routes/manage/Video/Shared.tsx @@ -13,7 +13,7 @@ import { b64regex } from "../../util"; import { Thumbnail } from "../../../ui/Video"; import { SharedVideoManageQuery } from "./__generated__/SharedVideoManageQuery.graphql"; import { Link } from "../../../router"; -import { isExperimentalFlagSet, keyOfId } from "../../../util"; +import { eventId, isExperimentalFlagSet, keyOfId } from "../../../util"; export const PAGE_WIDTH = 1100; @@ -38,7 +38,7 @@ export const makeManageVideoRoute = ( } const videoId = decodeURIComponent(params[1]); - const queryRef = loadQuery(query, { id: `ev${videoId}` }); + const queryRef = loadQuery(query, { id: eventId(videoId) }); return { render: () => `ev${key}`; + +/** Constructs series ID for graphQL by adding the "sr" prefix. */ +export const seriesId = (key: string) => `sr${key}`; + /** * Create a comparison function for `Array.prototype.sort` comparing whatever * the given key function returns as numbers.