@openneuro/app 5.0.0-alpha.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openneuro/app",
3
- "version": "5.0.0-alpha.0",
3
+ "version": "5.0.0",
4
4
  "description": "React JS web frontend for the OpenNeuro platform.",
5
5
  "license": "MIT",
6
6
  "main": "public/client.js",
@@ -79,5 +79,5 @@
79
79
  "publishConfig": {
80
80
  "access": "public"
81
81
  },
82
- "gitHead": "ee5b58a1623626ef79a439918e6c065a1c7d5e2e"
82
+ "gitHead": "437b7f1a10abf79d6e49058b86cf0ddb625de684"
83
83
  }
@@ -0,0 +1,20 @@
1
+ import { datasetCanonicalUrl } from "../dataset-canonical-url"
2
+ import { dataset } from "../../fixtures/dataset-query"
3
+ import { vitest } from "vitest"
4
+
5
+ vitest.mock("../../config", () => ({
6
+ config: { url: "http://localhost:9876" },
7
+ }))
8
+
9
+ describe("datasetCanonicalUrl", () => {
10
+ it("returns the canonical URL for a dataset with snapshots", () => {
11
+ const url = datasetCanonicalUrl(dataset)
12
+ expect(url.href).toBe("http://localhost:9876/datasets/ds001032/versions/2.0.0")
13
+ })
14
+
15
+ it("returns the canonical URL for a draft dataset", () => {
16
+ const draftDataset = { ...dataset, snapshots: [] }
17
+ const url = datasetCanonicalUrl(draftDataset)
18
+ expect(url.href).toBe("http://localhost:9876/datasets/ds001032")
19
+ })
20
+ })
@@ -0,0 +1,14 @@
1
+ import { config } from "../config"
2
+
3
+ export function datasetCanonicalUrl(dataset): URL {
4
+ const siteUrl = config.url
5
+ if (dataset.snapshots.length) {
6
+ const latestSnapshot = dataset.snapshots.slice(-1)[0]
7
+ return new URL(
8
+ `/datasets/${dataset.id}/versions/${latestSnapshot.tag}`,
9
+ siteUrl,
10
+ )
11
+ } else {
12
+ return new URL(`/datasets/${dataset.id}`, siteUrl)
13
+ }
14
+ }
@@ -3,6 +3,7 @@ import * as Sentry from "@sentry/react"
3
3
  import PropTypes from "prop-types"
4
4
  import { useNavigate, useParams } from "react-router-dom"
5
5
  import { useApolloClient, useQuery } from "@apollo/client"
6
+ import Helmet from "react-helmet"
6
7
  import { Loading } from "../components/loading/Loading"
7
8
 
8
9
  import DatasetQueryContext from "../datalad/dataset/dataset-query-context.js"
@@ -16,6 +17,7 @@ import { trackAnalytics } from "../utils/datalad"
16
17
  import FourOFourPage from "../errors/404page"
17
18
  import FourOThreePage from "../errors/403page"
18
19
  import { getDatasetPage, getDraftPage } from "../queries/dataset"
20
+ import { datasetCanonicalUrl } from "./dataset-canonical-url"
19
21
 
20
22
  /**
21
23
  * Query to load and render dataset page - most dataset loading is done here
@@ -63,6 +65,12 @@ export const DatasetQueryHook = ({ datasetId, draft }) => {
63
65
  }
64
66
  return (
65
67
  <DatasetContext.Provider value={data.dataset}>
68
+ <Helmet>
69
+ <link
70
+ rel="canonical"
71
+ href={datasetCanonicalUrl(data.dataset).toString()}
72
+ />
73
+ </Helmet>
66
74
  <ErrorBoundary subject={"error in dataset page"}>
67
75
  <DatasetQueryContext.Provider
68
76
  value={{