From b0c75550eafdbfcc239d12429108aa27b14bff3b Mon Sep 17 00:00:00 2001 From: Mika Munterud Date: Fri, 6 Dec 2024 17:58:32 +0100 Subject: [PATCH 1/3] DIGG-483: Uppdating url structure for concepts, terminologies and specifications --- features/entryscape/concept-page/index.tsx | 11 +-- features/entryscape/dataset-page/index.tsx | 4 +- .../entryscape/specification-page/index.tsx | 7 +- .../search-page-provider-settings.ts | 49 ------------- hooks/use-entry-scape-blocks.ts | 4 -- pages/concepts/[concept]/[param].tsx | 64 +++++++++++------ pages/concepts/[concept]/index.tsx | 60 +++++++++++++--- pages/externalconcept/[...concept].tsx | 45 +++++++++--- pages/externalconcept/index.tsx | 59 ++++++++------- .../[...specification].tsx | 39 ++++++++-- pages/externalspecification/index.tsx | 59 ++++++++------- .../externalterminology/[...terminology].tsx | 47 +++++++++--- pages/externalterminology/index.tsx | 59 ++++++++------- pages/specifications/[spec]/[param].tsx | 44 ++++++++++++ pages/specifications/[spec]/index.tsx | 71 +++++++++++++++++++ .../[specification]/[param].tsx | 29 -------- .../specifications/[specification]/index.tsx | 29 -------- pages/terminology/[term]/[param].tsx | 44 ++++++++++++ pages/terminology/[term]/index.tsx | 69 ++++++++++++++++++ pages/terminology/[terminology]/[param].tsx | 29 -------- pages/terminology/[terminology]/index.tsx | 31 -------- providers/entrystore-provider/index.tsx | 40 ++++------- types/search.d.ts | 1 - utilities/entryscape/blocks/concept.ts | 32 ++------- utilities/entryscape/blocks/config.ts | 54 +------------- utilities/entryscape/blocks/global.ts | 10 +-- utilities/entryscape/blocks/terminology.ts | 32 ++------- utilities/entryscape/entryscape.ts | 8 +-- 28 files changed, 563 insertions(+), 467 deletions(-) create mode 100644 pages/specifications/[spec]/[param].tsx create mode 100644 pages/specifications/[spec]/index.tsx delete mode 100644 pages/specifications/[specification]/[param].tsx delete mode 100644 pages/specifications/[specification]/index.tsx create mode 100644 pages/terminology/[term]/[param].tsx create mode 100644 pages/terminology/[term]/index.tsx delete mode 100644 pages/terminology/[terminology]/[param].tsx delete mode 100644 pages/terminology/[terminology]/index.tsx diff --git a/features/entryscape/concept-page/index.tsx b/features/entryscape/concept-page/index.tsx index 2a800766..d6a818da 100644 --- a/features/entryscape/concept-page/index.tsx +++ b/features/entryscape/concept-page/index.tsx @@ -12,24 +12,17 @@ import { EntrystoreContext } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; import { linkBase } from "@/utilities"; -export const ConceptPage: FC<{ curi?: string; uri?: string }> = ({ - curi, - uri, -}) => { +export const ConceptPage: FC = () => { const { setBreadcrumb, iconSize } = useContext(SettingsContext); const entry = useContext(EntrystoreContext); const { lang, t } = useTranslation(); const { pathname } = useRouter() || {}; - const isTerminology = - pathname.startsWith("/terminology") || - pathname.startsWith("/externalterminology"); + const isTerminology = pathname.startsWith("/terminology"); useEntryScapeBlocks({ entrystoreBase: entry.entrystore.getBaseURI(), env: entry.env, lang, - curi, - uri, iconSize, pageType: isTerminology ? "terminology" : "concept", context: entry.context, diff --git a/features/entryscape/dataset-page/index.tsx b/features/entryscape/dataset-page/index.tsx index 544f40f4..4ee988fc 100644 --- a/features/entryscape/dataset-page/index.tsx +++ b/features/entryscape/dataset-page/index.tsx @@ -14,11 +14,10 @@ import { SettingsContext } from "@/providers/settings-provider"; import { linkBase } from "@/utilities"; export const DatasetPage: FC = () => { - const { pathname, query } = useRouter() || {}; + const { pathname } = useRouter() || {}; const { setBreadcrumb, iconSize } = useContext(SettingsContext); const entry = useContext(EntrystoreContext); const { lang, t } = useTranslation(); - const { dataSet } = query || {}; const [showText, setShowText] = useState(false); const [descriptionHeight, setDescriptionHeight] = useState(0); const [showAllSpecs, setShowAllSpecs] = useState(false); @@ -34,7 +33,6 @@ export const DatasetPage: FC = () => { entrystoreBase: entry.entrystore.getBaseURI(), env: entry.env, lang, - curi: dataSet as string, iconSize, pageType: "dataset", context: entry.context, diff --git a/features/entryscape/specification-page/index.tsx b/features/entryscape/specification-page/index.tsx index 4104837d..9badc6c9 100644 --- a/features/entryscape/specification-page/index.tsx +++ b/features/entryscape/specification-page/index.tsx @@ -13,10 +13,7 @@ import { EntrystoreContext } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; import { linkBase } from "@/utilities"; -export const SpecificationPage: FC<{ curi?: string; uri?: string }> = ({ - curi, - uri, -}) => { +export const SpecificationPage: FC = () => { const { setBreadcrumb, iconSize } = useContext(SettingsContext); const entry = useContext(EntrystoreContext); const { lang, t } = useTranslation(); @@ -34,8 +31,6 @@ export const SpecificationPage: FC<{ curi?: string; uri?: string }> = ({ entrystoreBase: entry.entrystore.getBaseURI(), env: entry.env, lang, - curi, - uri, iconSize, pageType: "specification", context: entry.context, diff --git a/features/search/search-page/search-page-entryscape/search-page-provider-settings.ts b/features/search/search-page/search-page-entryscape/search-page-provider-settings.ts index 588c10c4..1c6ef51e 100644 --- a/features/search/search-page/search-page-entryscape/search-page-provider-settings.ts +++ b/features/search/search-page/search-page-entryscape/search-page-provider-settings.ts @@ -19,8 +19,6 @@ interface HitSpecification { path: string; titleResource: string; descriptionResource: string; - // eslint-disable-next-line no-unused-vars - pathResolver?: (hitMeta: ResourceMeta) => string; } interface SearchProviderConfig { @@ -42,49 +40,6 @@ interface SearchProviderConfig { }[]; }; } -interface ResourceMeta { - getResourceURI: () => string; -} - -interface PathResolverConfig { - externalPath: string; - internalPath: string; - domainLength: number; -} - -function createPathResolver(config: PathResolverConfig) { - return (hitMeta: ResourceMeta) => { - const resourceUri = hitMeta.getResourceURI(); - - if (!resourceUri) return ""; - - if (!resourceUri.includes("dataportal.se")) { - return `${config.externalPath}?resource=${encodeURIComponent( - resourceUri, - )}`; - } - - if (resourceUri.includes(config.internalPath)) { - return resourceUri.slice( - resourceUri.lastIndexOf("dataportal.se/") + config.domainLength, - ); - } - - return resourceUri; - }; -} - -const specsPathResolver = createPathResolver({ - externalPath: "/externalspecification", - internalPath: "dataportal.se/specifications", - domainLength: 13, -}); - -const termsPathResolver = createPathResolver({ - externalPath: "/externalconcept", - internalPath: "dataportal.se/concepts", - domainLength: 13, -}); export function createSearchProviderSettings(env: EnvSettings, lang: string) { return { @@ -161,7 +116,6 @@ export function createSearchProviderSettings(env: EnvSettings, lang: string) { indexOrder: 4, group: "distribution", }, - { resource: "http://data.europa.eu/r5r/applicableLegislation", type: ESType.uri, @@ -202,13 +156,11 @@ export function createSearchProviderSettings(env: EnvSettings, lang: string) { path: `/specifications/`, titleResource: "dcterms:title", descriptionResource: "dcterms:description", - pathResolver: specsPathResolver, }, "http://purl.org/dc/terms/Standard": { path: `/specifications/`, titleResource: "dcterms:title", descriptionResource: "dcterms:description", - pathResolver: specsPathResolver, }, }, facetSpecification: { @@ -291,7 +243,6 @@ export function createSearchProviderSettings(env: EnvSettings, lang: string) { path: `/concepts/`, titleResource: "http://www.w3.org/2004/02/skos/core#prefLabel", descriptionResource: "http://www.w3.org/2004/02/skos/core#definition", - pathResolver: termsPathResolver, }, }, facetSpecification: { diff --git a/hooks/use-entry-scape-blocks.ts b/hooks/use-entry-scape-blocks.ts index cf90b54e..72e1e392 100644 --- a/hooks/use-entry-scape-blocks.ts +++ b/hooks/use-entry-scape-blocks.ts @@ -28,8 +28,6 @@ export const useEntryScapeBlocks = ({ entrystoreBase, env, lang, - curi, - uri, iconSize, pageType, context, @@ -72,8 +70,6 @@ export const useEntryScapeBlocks = ({ entrystoreBase, env, lang, - curi, - uri, iconSize, t, pageType, diff --git a/pages/concepts/[concept]/[param].tsx b/pages/concepts/[concept]/[param].tsx index 0756b76e..8aa547a8 100644 --- a/pages/concepts/[concept]/[param].tsx +++ b/pages/concepts/[concept]/[param].tsx @@ -1,29 +1,47 @@ -import { useRouter } from "next/router"; -import { useContext } from "react"; +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next"; -import { ConceptPage } from "@/features/entryscape/concept-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; +import { SettingsUtil } from "@/env"; export default function Concept() { - const { env } = useContext(SettingsContext); - const { query } = useRouter() || {}; - const { concept, param } = query || {}; + return null; +} + +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { + const env = SettingsUtil.create(); + const { concept, param } = params || {}; const curi = `${concept}/${param}`; - let entryUri = ""; - if (env.ENTRYSCAPE_TERMS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/concepts/${curi}`; - else entryUri = `https://dataportal.se/concepts/${curi}`; + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/concepts/${curi}` + : `https://dataportal.se/concepts/${curi}`; - return ( - - - - ); -} + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/concepts/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/concepts/[concept]/index.tsx b/pages/concepts/[concept]/index.tsx index 01758e46..d0d8e303 100644 --- a/pages/concepts/[concept]/index.tsx +++ b/pages/concepts/[concept]/index.tsx @@ -1,6 +1,9 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next"; import { useRouter } from "next/router"; import { useContext } from "react"; +import { SettingsUtil } from "@/env"; import { ConceptPage } from "@/features/entryscape/concept-page"; import { EntrystoreProvider } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; @@ -9,21 +12,62 @@ export default function Concept() { const { env } = useContext(SettingsContext); const { query } = useRouter() || {}; const { concept } = query || {}; - const curi = concept; - let entryUri = ""; - - if (env.ENTRYSCAPE_TERMS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/concepts/${curi}`; - else entryUri = `https://dataportal.se/concepts/${curi}`; + const ids = (typeof concept === "string" && concept.split("_")) || []; + const eid = ids.pop() || ""; + const cid = ids.join("_"); return ( - + ); } + +export const getServerSideProps: GetServerSideProps = async ({ params }) => { + const env = SettingsUtil.create(); + const { concept } = params || {}; + + if ( + typeof concept === "string" && + /\d/.test(concept) && + concept.includes("_") + ) { + return { props: {} }; + } + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/concepts/${concept}` + : `https://dataportal.se/concepts/${concept}`; + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/concepts/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/externalconcept/[...concept].tsx b/pages/externalconcept/[...concept].tsx index 9bc6b4c3..672a91b2 100644 --- a/pages/externalconcept/[...concept].tsx +++ b/pages/externalconcept/[...concept].tsx @@ -1,6 +1,17 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next/types"; -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +import { SettingsUtil } from "@/env"; + +export default function Concept() { + return null; +} + +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { + const env = SettingsUtil.create(); const concept = (params?.concept as string[]) || []; const scheme = concept[0]; @@ -14,14 +25,30 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { const curi = concept.slice(1).join("/"); const uri = `${scheme}://${curi}`; + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(uri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/concepts/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + return { - redirect: { - destination: `/externalconcept?resource=${encodeURIComponent(uri)}`, - permanent: true, - }, + notFound: true, }; }; - -export default function Concept() { - return null; -} diff --git a/pages/externalconcept/index.tsx b/pages/externalconcept/index.tsx index 39b3db70..eda02673 100644 --- a/pages/externalconcept/index.tsx +++ b/pages/externalconcept/index.tsx @@ -1,32 +1,43 @@ -import { useRouter } from "next/router"; +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next/types"; -import { useContext } from "react"; -import { ConceptPage } from "@/features/entryscape/concept-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; +import { SettingsUtil } from "@/env"; export default function Concept() { - const { env } = useContext(SettingsContext); - const { resource } = useRouter().query; - - if (!resource) return null; - - return ( - - - - ); + return null; } export const getServerSideProps: GetServerSideProps = async ({ query: { resource }, -}) => ({ - notFound: !resource, - props: {}, -}); + locale, +}) => { + const env = SettingsUtil.create(); + const resourceUri = decodeURIComponent(resource as string); + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(resourceUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/concepts/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/externalspecification/[...specification].tsx b/pages/externalspecification/[...specification].tsx index 540c8b32..c264c7c6 100644 --- a/pages/externalspecification/[...specification].tsx +++ b/pages/externalspecification/[...specification].tsx @@ -1,10 +1,17 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next/types"; +import { SettingsUtil } from "@/env"; + export default function Specification() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { + const env = SettingsUtil.create(); const specification = (params?.specification as string[]) || []; const scheme = specification[0]; @@ -18,12 +25,30 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { const curi = specification.slice(1).join("/"); const entryUri = `${scheme}://${curi}`; + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/specifications/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + return { - redirect: { - destination: `/externalspecification?resource=${encodeURIComponent( - entryUri, - )}`, - permanent: true, - }, + notFound: true, }; }; diff --git a/pages/externalspecification/index.tsx b/pages/externalspecification/index.tsx index b1599e7d..ea926f94 100644 --- a/pages/externalspecification/index.tsx +++ b/pages/externalspecification/index.tsx @@ -1,32 +1,43 @@ -import { useRouter } from "next/router"; +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next/types"; -import { useContext } from "react"; -import { SpecificationPage } from "@/features/entryscape/specification-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; +import { SettingsUtil } from "@/env"; export default function Specification() { - const { env } = useContext(SettingsContext); - const { resource } = useRouter().query; - - if (!resource) return null; - - return ( - - - - ); + return null; } export const getServerSideProps: GetServerSideProps = async ({ query: { resource }, -}) => ({ - notFound: !resource, - props: {}, -}); + locale, +}) => { + const env = SettingsUtil.create(); + const resourceUri = decodeURIComponent(resource as string); + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(resourceUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/specifications/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/externalterminology/[...terminology].tsx b/pages/externalterminology/[...terminology].tsx index cd31ca1e..1dd8cb95 100644 --- a/pages/externalterminology/[...terminology].tsx +++ b/pages/externalterminology/[...terminology].tsx @@ -1,6 +1,17 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next"; -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +import { SettingsUtil } from "@/env"; + +export default function Terminology() { + return null; +} + +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { + const env = SettingsUtil.create(); const terminology = (params?.terminology as string[]) || []; const scheme = terminology[0]; @@ -14,16 +25,30 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { const curi = terminology.slice(1).join("/"); const entryUri = `${scheme}://${curi}`; + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/terminology/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + return { - redirect: { - destination: `/externalterminology?resource=${encodeURIComponent( - entryUri, - )}`, - permanent: true, - }, + notFound: true, }; }; - -export default function Terminology() { - return null; -} diff --git a/pages/externalterminology/index.tsx b/pages/externalterminology/index.tsx index 88700d29..b7a867f3 100644 --- a/pages/externalterminology/index.tsx +++ b/pages/externalterminology/index.tsx @@ -1,32 +1,43 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; import { GetServerSideProps } from "next"; -import { useRouter } from "next/router"; -import { useContext } from "react"; -import { ConceptPage } from "@/features/entryscape/concept-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; +import { SettingsUtil } from "@/env"; export default function Terminology() { - const { env } = useContext(SettingsContext); - const { resource } = useRouter().query; - - if (!resource) return null; - - return ( - - - - ); + return null; } export const getServerSideProps: GetServerSideProps = async ({ query: { resource }, -}) => ({ - notFound: !resource, - props: {}, -}); + locale, +}) => { + const env = SettingsUtil.create(); + const resourceUri = decodeURIComponent(resource as string); + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(resourceUri); + + if (entry) { + return { + redirect: { + destination: `/${locale}/terminology/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/specifications/[spec]/[param].tsx b/pages/specifications/[spec]/[param].tsx new file mode 100644 index 00000000..f819db97 --- /dev/null +++ b/pages/specifications/[spec]/[param].tsx @@ -0,0 +1,44 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next"; + +import { SettingsUtil } from "@/env"; + +export default function Specification() { + return null; +} + +export const getServerSideProps: GetServerSideProps = async ({ params }) => { + const env = SettingsUtil.create(); + const { spec, param } = params || {}; + const curi = `${spec}/${param}`; + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_SPECS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/specifications/${curi}` + : `https://dataportal.se/specifications/${curi}`; + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/specifications/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/specifications/[spec]/index.tsx b/pages/specifications/[spec]/index.tsx new file mode 100644 index 00000000..2e790375 --- /dev/null +++ b/pages/specifications/[spec]/index.tsx @@ -0,0 +1,71 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next"; +import { useRouter } from "next/router"; +import { useContext } from "react"; + +import { SettingsUtil } from "@/env"; +import { SpecificationPage } from "@/features/entryscape/specification-page"; +import { EntrystoreProvider } from "@/providers/entrystore-provider"; +import { SettingsContext } from "@/providers/settings-provider"; + +export default function Specification() { + const { env } = useContext(SettingsContext); + const { query } = useRouter() || {}; + const { spec } = query || {}; + const ids = (typeof spec === "string" && spec.split("_")) || []; + const eid = ids.pop() || ""; + const cid = ids.join("_"); + + if (eid && cid) { + return ( + + + + ); + } +} + +export const getServerSideProps: GetServerSideProps = async ({ params }) => { + const env = SettingsUtil.create(); + const { spec } = params || {}; + + if (typeof spec === "string" && /\d/.test(spec) && spec.includes("_")) { + return { props: {} }; + } + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_SPECS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/specifications/${spec}` + : `https://dataportal.se/specifications/${spec}`; + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/specifications/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/specifications/[specification]/[param].tsx b/pages/specifications/[specification]/[param].tsx deleted file mode 100644 index e00b8954..00000000 --- a/pages/specifications/[specification]/[param].tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useRouter } from "next/router"; -import { useContext } from "react"; - -import { SpecificationPage } from "@/features/entryscape/specification-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; - -export default function Specification() { - const { env } = useContext(SettingsContext); - const { query } = useRouter() || {}; - const { specification, param } = query || {}; - const curi = `${specification}/${param}`; - let entryUri = ""; - - if (env.ENTRYSCAPE_SPECS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/specifications/${curi}`; - else entryUri = `https://dataportal.se/specifications/${curi}`; - - return ( - - - - ); -} diff --git a/pages/specifications/[specification]/index.tsx b/pages/specifications/[specification]/index.tsx deleted file mode 100644 index 7f89f0c0..00000000 --- a/pages/specifications/[specification]/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useRouter } from "next/router"; -import { useContext } from "react"; - -import { SpecificationPage } from "@/features/entryscape/specification-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; - -export default function Specification() { - const { env } = useContext(SettingsContext); - const { query } = useRouter() || {}; - const { specification } = query || {}; - const curi = specification; - let entryUri = ""; - - if (env.ENTRYSCAPE_SPECS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/specifications/${curi}`; - else entryUri = `https://dataportal.se/specifications/${curi}`; - - return ( - - - - ); -} diff --git a/pages/terminology/[term]/[param].tsx b/pages/terminology/[term]/[param].tsx new file mode 100644 index 00000000..37c4bb87 --- /dev/null +++ b/pages/terminology/[term]/[param].tsx @@ -0,0 +1,44 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next/types"; + +import { SettingsUtil } from "@/env"; + +export default function Terminology() { + return null; +} + +export const getServerSideProps: GetServerSideProps = async ({ params }) => { + const env = SettingsUtil.create(); + const { terminology, param } = params || {}; + const curi = `${terminology}/${param}`; + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/concepts/${curi}` + : `https://dataportal.se/concepts/${curi}`; + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/terminology/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/terminology/[term]/index.tsx b/pages/terminology/[term]/index.tsx new file mode 100644 index 00000000..7d3d3f3d --- /dev/null +++ b/pages/terminology/[term]/index.tsx @@ -0,0 +1,69 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSideProps } from "next"; +import { useRouter } from "next/router"; +import { useContext } from "react"; + +import { SettingsUtil } from "@/env"; +import { ConceptPage } from "@/features/entryscape/concept-page"; +import { EntrystoreProvider } from "@/providers/entrystore-provider"; +import { SettingsContext } from "@/providers/settings-provider"; + +export default function Terminology() { + const { env } = useContext(SettingsContext); + const { query } = useRouter() || {}; + const { term } = query || {}; + const ids = (typeof term === "string" && term.split("_")) || []; + const eid = ids.pop() || ""; + const cid = ids.join("_"); + + return ( + + + + ); +} + +export const getServerSideProps: GetServerSideProps = async ({ params }) => { + const env = SettingsUtil.create(); + const { term } = params || {}; + + if (typeof term === "string" && /\d/.test(term) && term.includes("_")) { + return { props: {} }; + } + + try { + const es = new EntryStore( + `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") + ? `https://www-sandbox.dataportal.se/concepts/${term}` + : `https://dataportal.se/concepts/${term}`; + + const entry = await esu.getEntryByResourceURI(entryUri); + + if (entry) { + return { + redirect: { + destination: `/terminology/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, // This creates a 301 redirect + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { + notFound: true, + }; +}; diff --git a/pages/terminology/[terminology]/[param].tsx b/pages/terminology/[terminology]/[param].tsx deleted file mode 100644 index 32fc979f..00000000 --- a/pages/terminology/[terminology]/[param].tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useRouter } from "next/router"; -import { useContext } from "react"; - -import { ConceptPage } from "@/features/entryscape/concept-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; - -export default function Concept() { - const { env } = useContext(SettingsContext); - const { query } = useRouter() || {}; - const { terminology, param } = query || {}; - const curi = `${terminology}/${param}`; - let entryUri = ""; - - if (env.ENTRYSCAPE_TERMS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/concepts/${curi}`; - else entryUri = `https://dataportal.se/concepts/${curi}`; - - return ( - - - - ); -} diff --git a/pages/terminology/[terminology]/index.tsx b/pages/terminology/[terminology]/index.tsx deleted file mode 100644 index 198b830f..00000000 --- a/pages/terminology/[terminology]/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useRouter } from "next/router"; -import { useContext } from "react"; - -import { ConceptPage } from "@/features/entryscape/concept-page"; -import { EntrystoreProvider } from "@/providers/entrystore-provider"; -import { SettingsContext } from "@/providers/settings-provider"; - -export default function Concept() { - const { env } = useContext(SettingsContext); - const { query } = useRouter() || {}; - const { terminology } = query || {}; - const curi = terminology; - let entryUri = ""; - - if (env.ENTRYSCAPE_TERMS_PATH.includes("sandbox")) - entryUri = `https://www-sandbox.dataportal.se/concepts/${curi}`; - else entryUri = `https://dataportal.se/concepts/${curi}`; - const hasResourceUri = `https://www.dataportal.se/terminology/${curi}`; - - return ( - - - - ); -} diff --git a/providers/entrystore-provider/index.tsx b/providers/entrystore-provider/index.tsx index 17f3ba15..4a50298d 100644 --- a/providers/entrystore-provider/index.tsx +++ b/providers/entrystore-provider/index.tsx @@ -35,10 +35,9 @@ export type DatasetInfo = { export interface EntrystoreProviderProps { env: EnvSettings; - eid?: string; - cid?: string; + eid: string; + cid: string; children?: ReactNode; - entryUri?: string; entrystoreUrl: string | "admin.dataportal.se"; isConcept?: boolean; hasResourceUri?: string; @@ -136,7 +135,6 @@ export const EntrystoreProvider: FC = ({ children, cid, eid, - entryUri, entrystoreUrl, hasResourceUri, includeContact, @@ -153,7 +151,6 @@ export const EntrystoreProvider: FC = ({ // es.getREST().disableJSONP(); const esu = new EntryStoreUtil(es); esu.loadOnlyPublicEntries(true); - let entry = {} as Entry; // Add background class based on page type useEffect(() => { @@ -176,11 +173,7 @@ export const EntrystoreProvider: FC = ({ const fetchEntry = async () => { try { - if (entryUri) { - entry = await esu.getEntryByResourceURI(entryUri); - } else if (cid && eid) { - entry = await es.getEntry(es.getEntryURI(cid, eid)); - } + const entry: Entry = await es.getEntry(es.getEntryURI(cid, eid)); if (!entry) return router.push("/404"); @@ -566,12 +559,9 @@ export const EntrystoreProvider: FC = ({ data.terms.termsInfo = termsList .map((t) => ({ title: getLocalizedValue(t.getAllMetadata(), "dcterms:title"), - url: t.getResourceURI().startsWith("https://dataportal.se") - ? new URL(t.getResourceURI()).pathname.replace( - "concepts", - "terminology", - ) - : `/${lang}/externalterminology?resource=${t.getResourceURI()}`, + url: `/${lang}/terminology/${t + .getContext() + .getId()}_${t.getId()}`, })) .filter((t) => t.title && t.url); } @@ -627,9 +617,9 @@ export const EntrystoreProvider: FC = ({ return { title: getLocalizedValue(termEntry.getAllMetadata(), "dcterms:title"), - url: termUri.startsWith("https://dataportal.se") - ? new URL(termUri).pathname.replace("concepts", "terminology") - : `/${lang}/externalterminology?resource=${termUri}`, + url: `/${lang}/terminology/${termEntry + .getContext() + .getId()}_${termEntry.getId()}`, }; }; @@ -654,9 +644,9 @@ export const EntrystoreProvider: FC = ({ .filter((e: Entry) => e) .map((e: Entry) => ({ title: getLocalizedValue(e.getAllMetadata(), "dcterms:title"), - url: e.getResourceURI().startsWith("https://dataportal.se") - ? new URL(e.getResourceURI()).pathname - : `/${lang}/externalspecification?resource=${e.getResourceURI()}`, + url: `/${lang}/specifications/${e + .getContext() + .getId()}_${e.getId()}`, })); } else if (pageType === "terminology") { const specifications = await es @@ -673,9 +663,9 @@ export const EntrystoreProvider: FC = ({ .filter((e: Entry) => e) .map((e: Entry) => ({ title: getLocalizedValue(e.getAllMetadata(), "dcterms:title"), - url: e.getResourceURI().startsWith("https://dataportal.se") - ? new URL(e.getResourceURI()).pathname - : `/${lang}/externalspecification?resource=${e.getResourceURI()}`, + url: `/${lang}/specifications/${e + .getContext() + .getId()}_${e.getId()}`, })); } return []; diff --git a/types/search.d.ts b/types/search.d.ts index c7d38a92..ac28cf03 100644 --- a/types/search.d.ts +++ b/types/search.d.ts @@ -25,7 +25,6 @@ export interface HitSpecification { path?: string; titleResource?: string; descriptionResource?: string; - pathResolver?: (_hit: ESEntry) => string; } export interface FacetSpecification { diff --git a/utilities/entryscape/blocks/concept.ts b/utilities/entryscape/blocks/concept.ts index 53f372a7..5f757e93 100644 --- a/utilities/entryscape/blocks/concept.ts +++ b/utilities/entryscape/blocks/concept.ts @@ -44,14 +44,15 @@ export const conceptBlocks = (t: Translate, iconSize: number, lang: string) => [ node.firstElementChild.appendChild(el); - const ruri = entry.getResourceURI(); + const contextId = entry.getContext().getId(); + const id = entry.getId(); const label = getLocalizedValue( entry.getAllMetadata(), "skos:prefLabel", ); el.innerHTML = label; - const dpUri = getDataportalUri(ruri, lang); - el.setAttribute("href", dpUri); + const uri = `/${lang}/concepts/${contextId}_${id}`; + el.setAttribute("href", uri); } }, loadEntry: true, @@ -159,28 +160,3 @@ export const conceptBlocks = (t: Translate, iconSize: number, lang: string) => [ )}
{{hierarchy scale="1.7"}}
{{/ifprop}}`, }, ]; - -function getDataportalUri(resourceUri: string, lang: string) { - if (!resourceUri || !window?.location?.pathname) { - return resourceUri; - } - const currentPath = window.location.pathname; - const encodedResourceUri = encodeURIComponent(resourceUri); - - if (currentPath.includes("/externalconcept")) - return `/${lang}/externalconcept?resource=${encodedResourceUri}`; - - if (currentPath.includes("/concepts/")) { - let entryPath = ""; - if (resourceUri.includes("https://www-sandbox.dataportal.se/concepts")) - entryPath = resourceUri.replace( - "https://www-sandbox.dataportal.se/concepts", - "", - ); - else entryPath = resourceUri.replace("https://dataportal.se/concepts", ""); - - return `/${lang}/concepts${entryPath}`; - } - - return resourceUri; -} diff --git a/utilities/entryscape/blocks/config.ts b/utilities/entryscape/blocks/config.ts index 7387bc6e..1ba4906f 100644 --- a/utilities/entryscape/blocks/config.ts +++ b/utilities/entryscape/blocks/config.ts @@ -13,8 +13,6 @@ interface CreateBlocksConfigProps { entrystoreBase: string; env: EnvSettings; lang: string; - curi?: string; - uri?: string; iconSize?: number; t: Translate; pageType: string; @@ -26,8 +24,6 @@ export const createBlocksConfig = ({ entrystoreBase, env, lang, - curi, - uri, iconSize, context, esId, @@ -48,22 +44,6 @@ export const createBlocksConfig = ({ return [ { ...baseConfig, - routes: [ - { - regex: new RegExp("(/*/externalspecification/)(.+)/"), - uri: `${decodeURIComponent(uri as string)}`, - page_language: `${lang}`, - }, - { - regex: new RegExp("(/*/specifications/)(.+)"), - uri: `https://${ - env.ENTRYSCAPE_SPECS_PATH.startsWith("sandbox") - ? "www-sandbox.dataportal.se" - : "dataportal.se" - }/specifications/${curi}`, - page_language: `${lang}`, - }, - ], clicks: { specification: "details.html", specifications: "index.html", @@ -87,7 +67,7 @@ export const createBlocksConfig = ({ "dcat", `https://${ env.ENTRYSCAPE_SPECS_PATH.includes("sandbox") - ? "sandbox.editera.dataportal.se" + ? "sandbox.admin.dataportal.se" : "editera.dataportal.se" }/theme/templates/adms.json`, `https://${ @@ -104,22 +84,6 @@ export const createBlocksConfig = ({ return [ { ...baseConfig, - routes: [ - { - regex: new RegExp("(/*/externalconcept)(.+)"), - uri: decodeURIComponent(uri as string), - page_language: lang, - }, - { - regex: new RegExp("(/*/concepts/)(.+)"), - uri: `https://${ - env.ENTRYSCAPE_TERMS_PATH.startsWith("sandbox") - ? "www-sandbox.dataportal.se" - : "dataportal.se" - }/concepts/${curi}`, - page_language: lang, - }, - ], clicks: { concept: "details", concepts: "index", @@ -146,22 +110,6 @@ export const createBlocksConfig = ({ return [ { ...baseConfig, - routes: [ - { - regex: new RegExp("(/*/externalterminology)(.+)"), - uri: decodeURIComponent(uri as string), - page_language: lang, - }, - { - regex: new RegExp("(/*/terminology/)(.+)"), - uri: `https://${ - env.ENTRYSCAPE_TERMS_PATH.startsWith("sandbox") - ? "www-sandbox.dataportal.se" - : "dataportal.se" - }/concepts/${curi}`, - page_language: lang, - }, - ], clicks: { concept: "details", concepts: "index", diff --git a/utilities/entryscape/blocks/global.ts b/utilities/entryscape/blocks/global.ts index eee592b0..5419e0a2 100644 --- a/utilities/entryscape/blocks/global.ts +++ b/utilities/entryscape/blocks/global.ts @@ -241,16 +241,10 @@ export const hemvist = (t: Translate) => { const resourceURI = entry.getResourceURI(); let linkTitle = t("pages|concept_page$concept_adress"); - if ( - currentPath.includes("/terminology/") || - currentPath.includes("/externalterminology") - ) + if (currentPath.includes("/terminology/")) linkTitle = t("pages|concept_page$term_adress"); - if ( - currentPath.includes("/specifications/") || - currentPath.includes("/externalspecification") - ) + if (currentPath.includes("/specifications/")) linkTitle = t("pages|specification_page$address"); if ( diff --git a/utilities/entryscape/blocks/terminology.ts b/utilities/entryscape/blocks/terminology.ts index 97615293..a526c235 100644 --- a/utilities/entryscape/blocks/terminology.ts +++ b/utilities/entryscape/blocks/terminology.ts @@ -15,14 +15,15 @@ export const terminologyBlocks = (t: Translate, lang: string) => [ node.firstElementChild.appendChild(el); - const ruri = entry.getResourceURI(); + const contextId = entry.getContext().getId(); + const id = entry.getId(); const label = getLocalizedValue( entry.getAllMetadata(), "skos:prefLabel", ); el.innerHTML = label; - const dpUri = getDataportalUri(ruri, lang); - el.setAttribute("href", dpUri); + const uri = `/${lang}/concepts/${contextId}_${id}`; + el.setAttribute("href", uri); } }, loadEntry: true, @@ -45,28 +46,3 @@ export const terminologyBlocks = (t: Translate, lang: string) => [ click: "", }, ]; - -function getDataportalUri(resourceUri: string, lang: string) { - if (!resourceUri || !window?.location?.pathname) { - return resourceUri; - } - const currentPath = window.location.pathname; - const encodedResourceUri = encodeURIComponent(resourceUri); - - if (currentPath.includes("/externalterminology")) - return `/${lang}/externalconcept?resource=${encodedResourceUri}`; - - if (currentPath.includes("/terminology")) { - let entryPath = ""; - if (resourceUri.includes("https://www-sandbox.dataportal.se/concepts")) - entryPath = resourceUri.replace( - "https://www-sandbox.dataportal.se/concepts", - "", - ); - else entryPath = resourceUri.replace("https://dataportal.se/concepts", ""); - - return `/${lang}/concepts${entryPath}`; - } - - return resourceUri; -} diff --git a/utilities/entryscape/entryscape.ts b/utilities/entryscape/entryscape.ts index d5f06f08..c68467b8 100644 --- a/utilities/entryscape/entryscape.ts +++ b/utilities/entryscape/entryscape.ts @@ -602,11 +602,9 @@ export class Entryscape { ), }; - hit.url = hitSpecification.pathResolver - ? hitSpecification.pathResolver(child) - : `${hitSpecification.path || "datamangd"}${context.getId()}_${ - hit.entryId - }`; + hit.url = `${hitSpecification.path || "datamangd"}${context.getId()}_${ + hit.entryId + }`; hits.push(hit); } From 78e140931f87285e58fe7ceb90753fedd1612e1d Mon Sep 17 00:00:00 2001 From: Mika Munterud Date: Fri, 6 Dec 2024 18:32:35 +0100 Subject: [PATCH 2/3] DIGG-483: Adding lang check on forgotten pages --- pages/concepts/[concept]/index.tsx | 7 +++++-- pages/specifications/[spec]/[param].tsx | 7 +++++-- pages/specifications/[spec]/index.tsx | 7 +++++-- pages/terminology/[term]/[param].tsx | 7 +++++-- pages/terminology/[term]/index.tsx | 7 +++++-- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pages/concepts/[concept]/index.tsx b/pages/concepts/[concept]/index.tsx index d0d8e303..107b492e 100644 --- a/pages/concepts/[concept]/index.tsx +++ b/pages/concepts/[concept]/index.tsx @@ -29,7 +29,10 @@ export default function Concept() { ); } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { const env = SettingsUtil.create(); const { concept } = params || {}; @@ -56,7 +59,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { if (entry) { return { redirect: { - destination: `/concepts/${entry + destination: `/${locale}/concepts/${entry .getContext() .getId()}_${entry.getId()}`, permanent: true, // This creates a 301 redirect diff --git a/pages/specifications/[spec]/[param].tsx b/pages/specifications/[spec]/[param].tsx index f819db97..2f8762fd 100644 --- a/pages/specifications/[spec]/[param].tsx +++ b/pages/specifications/[spec]/[param].tsx @@ -7,7 +7,10 @@ export default function Specification() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { const env = SettingsUtil.create(); const { spec, param } = params || {}; const curi = `${spec}/${param}`; @@ -27,7 +30,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { if (entry) { return { redirect: { - destination: `/specifications/${entry + destination: `/${locale}/specifications/${entry .getContext() .getId()}_${entry.getId()}`, permanent: true, // This creates a 301 redirect diff --git a/pages/specifications/[spec]/index.tsx b/pages/specifications/[spec]/index.tsx index 2e790375..f5842bdf 100644 --- a/pages/specifications/[spec]/index.tsx +++ b/pages/specifications/[spec]/index.tsx @@ -31,7 +31,10 @@ export default function Specification() { } } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { const env = SettingsUtil.create(); const { spec } = params || {}; @@ -54,7 +57,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { if (entry) { return { redirect: { - destination: `/specifications/${entry + destination: `/${locale}/specifications/${entry .getContext() .getId()}_${entry.getId()}`, permanent: true, // This creates a 301 redirect diff --git a/pages/terminology/[term]/[param].tsx b/pages/terminology/[term]/[param].tsx index 37c4bb87..02863bff 100644 --- a/pages/terminology/[term]/[param].tsx +++ b/pages/terminology/[term]/[param].tsx @@ -7,7 +7,10 @@ export default function Terminology() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { const env = SettingsUtil.create(); const { terminology, param } = params || {}; const curi = `${terminology}/${param}`; @@ -27,7 +30,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { if (entry) { return { redirect: { - destination: `/terminology/${entry + destination: `/${locale}/terminology/${entry .getContext() .getId()}_${entry.getId()}`, permanent: true, // This creates a 301 redirect diff --git a/pages/terminology/[term]/index.tsx b/pages/terminology/[term]/index.tsx index 7d3d3f3d..b284414b 100644 --- a/pages/terminology/[term]/index.tsx +++ b/pages/terminology/[term]/index.tsx @@ -29,7 +29,10 @@ export default function Terminology() { ); } -export const getServerSideProps: GetServerSideProps = async ({ params }) => { +export const getServerSideProps: GetServerSideProps = async ({ + params, + locale, +}) => { const env = SettingsUtil.create(); const { term } = params || {}; @@ -52,7 +55,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { if (entry) { return { redirect: { - destination: `/terminology/${entry + destination: `/${locale}/terminology/${entry .getContext() .getId()}_${entry.getId()}`, permanent: true, // This creates a 301 redirect From 4277fa6cf87e63e7afa2ba24d4f19c775d94bd12 Mon Sep 17 00:00:00 2001 From: Mika Munterud Date: Sat, 7 Dec 2024 15:47:16 +0100 Subject: [PATCH 3/3] DIGG-483: Adding utillity function to handle redirects --- pages/concepts/[concept]/[param].tsx | 52 +++---------- pages/concepts/[concept]/index.tsx | 58 +++----------- pages/externalconcept/[...concept].tsx | 58 +++----------- pages/externalconcept/index.tsx | 50 ++++-------- .../[...specification].tsx | 58 +++----------- pages/externalspecification/index.tsx | 50 ++++-------- .../externalterminology/[...terminology].tsx | 58 +++----------- pages/externalterminology/index.tsx | 50 ++++-------- pages/specifications/[spec]/[param].tsx | 52 +++---------- pages/specifications/[spec]/index.tsx | 54 +++---------- pages/terminology/[term]/[param].tsx | 52 +++---------- pages/terminology/[term]/index.tsx | 54 +++---------- utilities/entryscape/entrystore-redirect.ts | 76 +++++++++++++++++++ 13 files changed, 220 insertions(+), 502 deletions(-) create mode 100644 utilities/entryscape/entrystore-redirect.ts diff --git a/pages/concepts/[concept]/[param].tsx b/pages/concepts/[concept]/[param].tsx index 8aa547a8..c0f55c54 100644 --- a/pages/concepts/[concept]/[param].tsx +++ b/pages/concepts/[concept]/[param].tsx @@ -1,47 +1,19 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Concept() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { concept, param } = params || {}; - const curi = `${concept}/${param}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/concepts/${curi}` - : `https://dataportal.se/concepts/${curi}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/concepts/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/concepts", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "concept", + secondParamName: "param", + }); }; diff --git a/pages/concepts/[concept]/index.tsx b/pages/concepts/[concept]/index.tsx index 107b492e..9b17d878 100644 --- a/pages/concepts/[concept]/index.tsx +++ b/pages/concepts/[concept]/index.tsx @@ -1,12 +1,11 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; import { useRouter } from "next/router"; +import { GetServerSidePropsContext } from "next/types"; import { useContext } from "react"; -import { SettingsUtil } from "@/env"; import { ConceptPage } from "@/features/entryscape/concept-page"; import { EntrystoreProvider } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Concept() { const { env } = useContext(SettingsContext); @@ -29,48 +28,13 @@ export default function Concept() { ); } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { concept } = params || {}; - - if ( - typeof concept === "string" && - /\d/.test(concept) && - concept.includes("_") - ) { - return { props: {} }; - } - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/concepts/${concept}` - : `https://dataportal.se/concepts/${concept}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/concepts/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/concepts", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "concept", + }); }; diff --git a/pages/externalconcept/[...concept].tsx b/pages/externalconcept/[...concept].tsx index 672a91b2..6e92c865 100644 --- a/pages/externalconcept/[...concept].tsx +++ b/pages/externalconcept/[...concept].tsx @@ -1,54 +1,18 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Concept() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const concept = (params?.concept as string[]) || []; - const scheme = concept[0]; - - if (scheme != "http" && scheme != "https") { - return { - notFound: true, - }; - } - - // Reconstruct the original URI and redirect to the new format - const curi = concept.slice(1).join("/"); - const uri = `${scheme}://${curi}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(uri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/concepts/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/concepts", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "concept", + }); }; diff --git a/pages/externalconcept/index.tsx b/pages/externalconcept/index.tsx index eda02673..164a1492 100644 --- a/pages/externalconcept/index.tsx +++ b/pages/externalconcept/index.tsx @@ -1,43 +1,21 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Concept() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - query: { resource }, - locale, -}) => { - const env = SettingsUtil.create(); - const resourceUri = decodeURIComponent(resource as string); - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(resourceUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/concepts/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect( + context, + { + pathPrefix: "/concepts", + redirectPath: "/concepts", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + }, + context.query.resource as string, + ); }; diff --git a/pages/externalspecification/[...specification].tsx b/pages/externalspecification/[...specification].tsx index c264c7c6..44ea3802 100644 --- a/pages/externalspecification/[...specification].tsx +++ b/pages/externalspecification/[...specification].tsx @@ -1,54 +1,18 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Specification() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const specification = (params?.specification as string[]) || []; - const scheme = specification[0]; - - if (scheme != "http" && scheme != "https") { - return { - notFound: true, - }; - } - - // Reconstruct the original URI and redirect to the new format - const curi = specification.slice(1).join("/"); - const entryUri = `${scheme}://${curi}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/specifications/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/specifications", + redirectPath: "/specifications", + entrystorePathKey: "ENTRYSCAPE_SPECS_PATH", + paramName: "specification", + }); }; diff --git a/pages/externalspecification/index.tsx b/pages/externalspecification/index.tsx index ea926f94..7ad7db53 100644 --- a/pages/externalspecification/index.tsx +++ b/pages/externalspecification/index.tsx @@ -1,43 +1,21 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Specification() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - query: { resource }, - locale, -}) => { - const env = SettingsUtil.create(); - const resourceUri = decodeURIComponent(resource as string); - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(resourceUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/specifications/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect( + context, + { + pathPrefix: "/specifications", + redirectPath: "/specifications", + entrystorePathKey: "ENTRYSCAPE_SPECS_PATH", + }, + context.query.resource as string, + ); }; diff --git a/pages/externalterminology/[...terminology].tsx b/pages/externalterminology/[...terminology].tsx index 1dd8cb95..bfae1354 100644 --- a/pages/externalterminology/[...terminology].tsx +++ b/pages/externalterminology/[...terminology].tsx @@ -1,54 +1,18 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Terminology() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const terminology = (params?.terminology as string[]) || []; - const scheme = terminology[0]; - - if (scheme != "http" && scheme != "https") { - return { - notFound: true, - }; - } - - // Reconstruct the original URI and redirect to the new format - const curi = terminology.slice(1).join("/"); - const entryUri = `${scheme}://${curi}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/terminology/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/terminology", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "terminology", + }); }; diff --git a/pages/externalterminology/index.tsx b/pages/externalterminology/index.tsx index b7a867f3..bf0a1fd8 100644 --- a/pages/externalterminology/index.tsx +++ b/pages/externalterminology/index.tsx @@ -1,43 +1,21 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Terminology() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - query: { resource }, - locale, -}) => { - const env = SettingsUtil.create(); - const resourceUri = decodeURIComponent(resource as string); - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - - const entry = await esu.getEntryByResourceURI(resourceUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/terminology/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect( + context, + { + pathPrefix: "/concepts", + redirectPath: "/terminology", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + }, + context.query.resource as string, + ); }; diff --git a/pages/specifications/[spec]/[param].tsx b/pages/specifications/[spec]/[param].tsx index 2f8762fd..d322f107 100644 --- a/pages/specifications/[spec]/[param].tsx +++ b/pages/specifications/[spec]/[param].tsx @@ -1,47 +1,19 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Specification() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { spec, param } = params || {}; - const curi = `${spec}/${param}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_SPECS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/specifications/${curi}` - : `https://dataportal.se/specifications/${curi}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/specifications/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/specifications", + redirectPath: "/specifications", + entrystorePathKey: "ENTRYSCAPE_SPECS_PATH", + paramName: "spec", + secondParamName: "param", + }); }; diff --git a/pages/specifications/[spec]/index.tsx b/pages/specifications/[spec]/index.tsx index f5842bdf..ab23a50d 100644 --- a/pages/specifications/[spec]/index.tsx +++ b/pages/specifications/[spec]/index.tsx @@ -1,12 +1,11 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; import { useRouter } from "next/router"; +import { GetServerSidePropsContext } from "next/types"; import { useContext } from "react"; -import { SettingsUtil } from "@/env"; import { SpecificationPage } from "@/features/entryscape/specification-page"; import { EntrystoreProvider } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Specification() { const { env } = useContext(SettingsContext); @@ -31,44 +30,13 @@ export default function Specification() { } } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { spec } = params || {}; - - if (typeof spec === "string" && /\d/.test(spec) && spec.includes("_")) { - return { props: {} }; - } - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_SPECS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/specifications/${spec}` - : `https://dataportal.se/specifications/${spec}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/specifications/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/specifications", + redirectPath: "/specifications", + entrystorePathKey: "ENTRYSCAPE_SPECS_PATH", + paramName: "spec", + }); }; diff --git a/pages/terminology/[term]/[param].tsx b/pages/terminology/[term]/[param].tsx index 02863bff..ead52a15 100644 --- a/pages/terminology/[term]/[param].tsx +++ b/pages/terminology/[term]/[param].tsx @@ -1,47 +1,19 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next/types"; +import { GetServerSidePropsContext } from "next/types"; -import { SettingsUtil } from "@/env"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Terminology() { return null; } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { terminology, param } = params || {}; - const curi = `${terminology}/${param}`; - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_SPECS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/concepts/${curi}` - : `https://dataportal.se/concepts/${curi}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/terminology/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/terminology", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "term", + secondParamName: "param", + }); }; diff --git a/pages/terminology/[term]/index.tsx b/pages/terminology/[term]/index.tsx index b284414b..4400a921 100644 --- a/pages/terminology/[term]/index.tsx +++ b/pages/terminology/[term]/index.tsx @@ -1,12 +1,11 @@ -import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; -import { GetServerSideProps } from "next"; +import { GetServerSidePropsContext } from "next"; import { useRouter } from "next/router"; import { useContext } from "react"; -import { SettingsUtil } from "@/env"; import { ConceptPage } from "@/features/entryscape/concept-page"; import { EntrystoreProvider } from "@/providers/entrystore-provider"; import { SettingsContext } from "@/providers/settings-provider"; +import { handleEntryStoreRedirect } from "@/utilities/entryscape/entrystore-redirect"; export default function Terminology() { const { env } = useContext(SettingsContext); @@ -29,44 +28,13 @@ export default function Terminology() { ); } -export const getServerSideProps: GetServerSideProps = async ({ - params, - locale, -}) => { - const env = SettingsUtil.create(); - const { term } = params || {}; - - if (typeof term === "string" && /\d/.test(term) && term.includes("_")) { - return { props: {} }; - } - - try { - const es = new EntryStore( - `https://${env.ENTRYSCAPE_TERMS_PATH}/store` || - "https://admin.dataportal.se/store", - ); - const esu = new EntryStoreUtil(es); - const entryUri = env.ENTRYSCAPE_TERMS_PATH.includes("sandbox") - ? `https://www-sandbox.dataportal.se/concepts/${term}` - : `https://dataportal.se/concepts/${term}`; - - const entry = await esu.getEntryByResourceURI(entryUri); - - if (entry) { - return { - redirect: { - destination: `/${locale}/terminology/${entry - .getContext() - .getId()}_${entry.getId()}`, - permanent: true, // This creates a 301 redirect - }, - }; - } - } catch (error) { - console.error("Error fetching entry:", error); - } - - return { - notFound: true, - }; +export const getServerSideProps = async ( + context: GetServerSidePropsContext, +) => { + return handleEntryStoreRedirect(context, { + pathPrefix: "/concepts", + redirectPath: "/terminology", + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH", + paramName: "term", + }); }; diff --git a/utilities/entryscape/entrystore-redirect.ts b/utilities/entryscape/entrystore-redirect.ts new file mode 100644 index 00000000..a2767fc9 --- /dev/null +++ b/utilities/entryscape/entrystore-redirect.ts @@ -0,0 +1,76 @@ +import { EntryStore, EntryStoreUtil } from "@entryscape/entrystore-js"; +import { GetServerSidePropsContext } from "next"; + +import { SettingsUtil } from "@/env"; + +type RedirectConfig = { + pathPrefix: string; + redirectPath: "/concepts" | "/specifications" | "/terminology"; + entrystorePathKey: "ENTRYSCAPE_TERMS_PATH" | "ENTRYSCAPE_SPECS_PATH"; + paramName?: string; + secondParamName?: string; +}; + +export async function handleEntryStoreRedirect( + context: GetServerSidePropsContext, + config: RedirectConfig, + resourceUri?: string, +) { + const { locale, params } = context; + const env = SettingsUtil.create(); + + // Handle catch-all routes ([...param]) + const param = params?.[config.paramName || ""]; + if (Array.isArray(param)) { + const scheme = param[0]; + if (scheme !== "http" && scheme !== "https") { + return { notFound: true }; + } + + const curi = param.slice(1).join("/"); + resourceUri = `${scheme}://${curi}`; + } + // Handle regular routes + else if (param) { + if (/\d/.test(param) && param.includes("_")) { + return { props: {} }; + } + + // Construct resourceUri based on number of parameters + const baseUrl = env[config.entrystorePathKey].includes("sandbox") + ? "https://www-sandbox.dataportal.se" + : "https://dataportal.se"; + + const pathSuffix = + config.secondParamName && params?.[config.secondParamName] + ? `${param}/${params[config.secondParamName]}` // Two params + : param; // Single param + + resourceUri = `${baseUrl}${config.pathPrefix}/${pathSuffix}`; + } + + try { + const es = new EntryStore( + `https://${env[config.entrystorePathKey]}/store` || + "https://admin.dataportal.se/store", + ); + const esu = new EntryStoreUtil(es); + + const entry = await esu.getEntryByResourceURI(resourceUri || ""); + + if (entry) { + return { + redirect: { + destination: `/${locale}${config.redirectPath}/${entry + .getContext() + .getId()}_${entry.getId()}`, + permanent: true, + }, + }; + } + } catch (error) { + console.error("Error fetching entry:", error); + } + + return { notFound: true }; +}