diff --git a/packages/openneuro-app/src/scripts/app.tsx b/packages/openneuro-app/src/scripts/app.tsx index 344ae8c594..0c7c7130ff 100644 --- a/packages/openneuro-app/src/scripts/app.tsx +++ b/packages/openneuro-app/src/scripts/app.tsx @@ -5,6 +5,9 @@ import { Cookies, CookiesProvider } from "react-cookie" import { ToastContainer } from "react-toastify" import "react-toastify/dist/ReactToastify.css" import { MediaContextProvider } from "./styles/media" +import { Agreement } from "./components/agreement" +import { LocalStorageProvider } from "./utils/local-storage" +import "./scss/index.scss" interface AppProps { children: ReactNode @@ -19,16 +22,19 @@ const App: FC<AppProps> = ({ children: ReactNode }) => { return ( - <CookiesProvider cookies={cookies}> - <MediaContextProvider> - <Helmet> - <title>{frontPage.pageTitle}</title> - <meta name="description" content={frontPage.pageDescription} /> - </Helmet> - {children} - <ToastContainer position="bottom-right" /> - </MediaContextProvider> - </CookiesProvider> + <LocalStorageProvider defaultValue={{ agreement: false }}> + <CookiesProvider cookies={cookies}> + <MediaContextProvider> + <Helmet> + <title>{frontPage.pageTitle}</title> + <meta name="description" content={frontPage.pageDescription} /> + </Helmet> + {children} + <Agreement /> + <ToastContainer position="bottom-right" /> + </MediaContextProvider> + </CookiesProvider> + </LocalStorageProvider> ) } diff --git a/packages/openneuro-app/src/scripts/components/__tests__/agreement.spec.tsx b/packages/openneuro-app/src/scripts/components/__tests__/agreement.spec.tsx new file mode 100644 index 0000000000..d9137724ea --- /dev/null +++ b/packages/openneuro-app/src/scripts/components/__tests__/agreement.spec.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { fireEvent, render, screen } from "@testing-library/react" +import { Agreement } from "../agreement" +import { LocalStorageProvider } from "../../utils/local-storage" + +describe("Agreement component", () => { + beforeEach(() => { + localStorage.clear() + }) + afterEach(() => { + localStorage.clear() + }) + it("Accepting the agreement sets the 'agreement' property in localStorage", () => { + render( + <LocalStorageProvider defaultValue={{}}> + <Agreement /> + </LocalStorageProvider>, + ) + fireEvent.click(screen.getByRole("button")) + expect(JSON.parse(localStorage.getItem("openneuro")).agreement).toEqual( + true, + ) + }) +}) diff --git a/packages/openneuro-app/src/scripts/components/agreement.tsx b/packages/openneuro-app/src/scripts/components/agreement.tsx new file mode 100644 index 0000000000..243b76e13d --- /dev/null +++ b/packages/openneuro-app/src/scripts/components/agreement.tsx @@ -0,0 +1,74 @@ +import React from "react" +import { useLocalStorage } from "../utils/local-storage" +import styled from "@emotion/styled" + +export const STORAGE_KEY = "agreement" + +const AgreementDiv = styled.div` + overflow: hidden; + position: fixed; + bottom: 0; + width: 100%; + background: white; + z-index: 1005; + -webkit-box-shadow: 0px -4px 3px rgba(50, 50, 50, 0.5); + -moz-box-shadow: 0px -4px 3px rgba(50, 50, 50, 0.5); + box-shadow: 0px -4px 3px rgba(50, 50, 50, 0.5); + padding: 4px; +` + +const AgreementButton = styled.div` + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +` + +/** + * Hook to use the download agreement state from localStorage + */ +export function useAgreement() { + return useLocalStorage(STORAGE_KEY) +} + +/** + * Floating agreement for data use that is only present if the user has not accepted this + */ +export const Agreement = () => { + const [agreed, setAgreed] = useAgreement() + + if (agreed) { + return null + } else { + return ( + <AgreementDiv> + <div className="container"> + <div className="grid grid-between"> + <div className="col col-lg col-11"> + <p> + By clicking "I Agree", I affirm that I have the appropriate + institutional permissions to receive de-identified data for + secondary data analysis, and that neither I nor my collaborators + will attempt to reidentify individuals whose data are contained + in downloads from OpenNeuro. Further, if for any reason the + identity of participants contained in downloads from OpenNeuro + become known to me I will make no effort to recontact such + participants and will provide immediate notice to OpenNeuro + staff. + </p> + </div> + <div className="col col-lg col-1"> + <AgreementButton + className="on-button on-button--small on-button--primary" + onClick={() => setAgreed(true)} + role="button" + > + I Agree + </AgreementButton> + </div> + </div> + </div> + </AgreementDiv> + ) + } +} diff --git a/packages/openneuro-app/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap b/packages/openneuro-app/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap index b03d7be6ad..cef5856449 100644 --- a/packages/openneuro-app/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap +++ b/packages/openneuro-app/src/scripts/dataset/__tests__/__snapshots__/snapshot-container.spec.tsx.snap @@ -408,7 +408,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = ` class="css-1dvuowd" > <span - class="css-1an2ojl" + class="css-1mdlu11" > <span class=" " @@ -432,7 +432,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = ` </span> </span> <span - class="css-1an2ojl" + class="css-aokf2s" > <span class=" " @@ -456,7 +456,7 @@ exports[`SnapshotContainer component > renders successfully 1`] = ` </span> </span> <span - class="css-1an2ojl" + class="css-1mdlu11" > <span class=" " @@ -593,29 +593,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. CHANGES <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - /> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/CHANGES" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -633,29 +611,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. README <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - /> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/README" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -673,29 +629,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. T1w.json <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - /> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/T1w.json" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -713,29 +647,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. dataset_description.json <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - /> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/dataset_description.json" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -753,29 +665,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. participants.tsv <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - /> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/participants.tsv" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-dir" @@ -913,49 +803,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. CHANGES <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - > - <span - class=" " - data-flow="up" - data-tooltip="Download: 52B" - > - <span - class="edit-file download-file" - > - <a - aria-label="download file" - download="" - href="/crn/datasets/ds001032/snapshots/1.0.0/files/CHANGES" - > - <i - class="fa fa-download" - /> - </a> - </span> - </span> - </div> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/CHANGES" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -973,49 +821,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. README <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - > - <span - class=" " - data-flow="up" - data-tooltip="Download: 709B" - > - <span - class="edit-file download-file" - > - <a - aria-label="download file" - download="" - href="/crn/datasets/ds001032/snapshots/1.0.0/files/README" - > - <i - class="fa fa-download" - /> - </a> - </span> - </span> - </div> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/README" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -1033,49 +839,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. T1w.json <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - > - <span - class=" " - data-flow="up" - data-tooltip="Download: 196B" - > - <span - class="edit-file download-file" - > - <a - aria-label="download file" - download="" - href="/crn/datasets/ds001032/snapshots/1.0.0/files/T1w.json" - > - <i - class="fa fa-download" - /> - </a> - </span> - </span> - </div> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/T1w.json" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -1093,49 +857,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. dataset_description.json <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - > - <span - class=" " - data-flow="up" - data-tooltip="Download: 172B" - > - <span - class="edit-file download-file" - > - <a - aria-label="download file" - download="" - href="/crn/datasets/ds001032/snapshots/1.0.0/files/dataset_description.json" - > - <i - class="fa fa-download" - /> - </a> - </span> - </span> - </div> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/dataset_description.json" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-file" @@ -1153,49 +875,7 @@ OCI-1131441 (R. Poldrack, PI) in any publications. participants.tsv <span class="filetree-editfile" - > - <div - class="fresnel-container fresnel-greaterThanOrEqual-medium " - > - <span - class=" " - data-flow="up" - data-tooltip="Download: 36B" - > - <span - class="edit-file download-file" - > - <a - aria-label="download file" - download="" - href="/crn/datasets/ds001032/snapshots/1.0.0/files/participants.tsv" - > - <i - class="fa fa-download" - /> - </a> - </span> - </span> - </div> - <span - class=" " - data-flow="up" - data-tooltip="View" - > - <span - class="edit-file view-file" - > - <a - aria-label="view file" - href="/datasets/ds001032/versions/1.0.0/file-display/participants.tsv" - > - <i - class="fa fa-eye" - /> - </a> - </span> - </span> - </span> + /> </li> <li class="clearfix filetree-item filetree-dir" diff --git a/packages/openneuro-components/src/dataset/BrainLifeButton.tsx b/packages/openneuro-app/src/scripts/dataset/components/BrainLifeButton.tsx similarity index 88% rename from packages/openneuro-components/src/dataset/BrainLifeButton.tsx rename to packages/openneuro-app/src/scripts/dataset/components/BrainLifeButton.tsx index 3c28ff1b49..c07843cc0b 100644 --- a/packages/openneuro-components/src/dataset/BrainLifeButton.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/BrainLifeButton.tsx @@ -1,6 +1,6 @@ import React from "react" -import { Tooltip } from "../tooltip/Tooltip" -import { Button } from "../button/Button" +import { Tooltip } from "@openneuro/components/tooltip" +import { Button } from "@openneuro/components/button" export interface BrainLifeButtonProps { datasetId: string diff --git a/packages/openneuro-components/src/dataset/CloneDropdown.tsx b/packages/openneuro-app/src/scripts/dataset/components/CloneDropdown.tsx similarity index 85% rename from packages/openneuro-components/src/dataset/CloneDropdown.tsx rename to packages/openneuro-app/src/scripts/dataset/components/CloneDropdown.tsx index 2d242c9464..ea51e7cfda 100644 --- a/packages/openneuro-components/src/dataset/CloneDropdown.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/CloneDropdown.tsx @@ -1,6 +1,6 @@ import React from "react" -import { Dropdown } from "../dropdown/Dropdown" -import { Button } from "../button/Button" +import { Dropdown } from "@openneuro/components/dropdown" +import { Button } from "@openneuro/components/button" export interface CloneDropdownProps { gitAccess: React.ReactNode diff --git a/packages/openneuro-components/src/dataset/DatasetAlert.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetAlert.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/DatasetAlert.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetAlert.tsx diff --git a/packages/openneuro-components/src/dataset/DatasetGitAccess.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetGitAccess.tsx similarity index 95% rename from packages/openneuro-components/src/dataset/DatasetGitAccess.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetGitAccess.tsx index b7373956c4..3c87cee830 100644 --- a/packages/openneuro-components/src/dataset/DatasetGitAccess.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/DatasetGitAccess.tsx @@ -1,6 +1,6 @@ import React from "react" -import { Tooltip } from "../tooltip/Tooltip" -import { Button } from "../button/Button" +import { Tooltip } from "@openneuro/components/tooltip" +import { Button } from "@openneuro/components/button" function copyToClipboard(text) { navigator.clipboard.writeText(text) diff --git a/packages/openneuro-components/src/dataset/DatasetHeader.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetHeader.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/DatasetHeader.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetHeader.tsx diff --git a/packages/openneuro-components/src/dataset/DatasetHeaderMeta.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetHeaderMeta.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/DatasetHeaderMeta.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetHeaderMeta.tsx diff --git a/packages/openneuro-components/src/dataset/DatasetToolButton.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetToolButton.tsx similarity index 64% rename from packages/openneuro-components/src/dataset/DatasetToolButton.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetToolButton.tsx index 7c797de9db..6533ecae87 100644 --- a/packages/openneuro-components/src/dataset/DatasetToolButton.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/DatasetToolButton.tsx @@ -1,12 +1,13 @@ import React from "react" import styled, { StyledComponent } from "@emotion/styled" import { Link } from "react-router-dom" -import { Tooltip } from "../tooltip/Tooltip" -import { Icon } from "../icon/Icon" +import { Tooltip } from "@openneuro/components/tooltip" +import { Icon } from "@openneuro/components/icon" import { useLocation } from "react-router-dom" interface DatasetToolStyleProps { active: boolean + disable: boolean } export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled @@ -18,7 +19,10 @@ export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled padding: 0 15px; justify-content: center; a { - color: var(--current-theme-primary); + pointer-events: ${props.disable ? "none" : "auto"}; + color: ${ + props.disable ? "rgba(0, 0, 0, 0.5);" : "var(--current-theme-primary);" + } font-size: 17px; text-decoration: none; font-weight: 400; @@ -38,10 +42,20 @@ export const DatasetToolStyle: StyledComponent<DatasetToolStyleProps> = styled `, ) -export const DatasetToolButton = ({ path, icon, tooltip, label }) => { +interface DatasetToolButtonProps { + path: string + label: string + tooltip: string + icon: string + disable?: boolean +} + +export const DatasetToolButton = ( + { path, icon, tooltip, label, disable = false }: DatasetToolButtonProps, +) => { const location = useLocation() return ( - <DatasetToolStyle active={location.pathname == path}> + <DatasetToolStyle active={location.pathname == path} disable={disable}> <Tooltip tooltip={tooltip} flow="up"> <Link to={path}> <Icon icon={`fa ${icon}`} label={label} /> diff --git a/packages/openneuro-components/src/dataset/DatasetTools.tsx b/packages/openneuro-app/src/scripts/dataset/components/DatasetTools.tsx similarity index 97% rename from packages/openneuro-components/src/dataset/DatasetTools.tsx rename to packages/openneuro-app/src/scripts/dataset/components/DatasetTools.tsx index b0fcf52cc8..1c3dbca7f5 100644 --- a/packages/openneuro-components/src/dataset/DatasetTools.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/DatasetTools.tsx @@ -1,6 +1,7 @@ import React from "react" import { DatasetToolButton } from "./DatasetToolButton" import styled, { StyledComponent } from "@emotion/styled" +import { useAgreement } from "../../components/agreement" interface DatasetToolStyleProps {} @@ -32,6 +33,7 @@ export const DatasetTools = ({ isDatasetAdmin, hasDerivatives, }: DatasetToolsProps) => { + const [agree] = useAgreement() const isSnapshot = snapshotId return ( <DatasetToolStyle> @@ -103,6 +105,7 @@ export const DatasetTools = ({ : `/datasets/${datasetId}/download`} icon="fa-download" label="Download" + disable={!agree} /> {hasDerivatives && ( <DatasetToolButton diff --git a/packages/openneuro-components/src/dataset/MetaDataBlock.tsx b/packages/openneuro-app/src/scripts/dataset/components/MetaDataBlock.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/MetaDataBlock.tsx rename to packages/openneuro-app/src/scripts/dataset/components/MetaDataBlock.tsx diff --git a/packages/openneuro-components/src/dataset/MetaDataListBlock.tsx b/packages/openneuro-app/src/scripts/dataset/components/MetaDataListBlock.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/MetaDataListBlock.tsx rename to packages/openneuro-app/src/scripts/dataset/components/MetaDataListBlock.tsx diff --git a/packages/openneuro-components/src/dataset/ModalitiesMetaDataBlock.tsx b/packages/openneuro-app/src/scripts/dataset/components/ModalitiesMetaDataBlock.tsx similarity index 95% rename from packages/openneuro-components/src/dataset/ModalitiesMetaDataBlock.tsx rename to packages/openneuro-app/src/scripts/dataset/components/ModalitiesMetaDataBlock.tsx index ce10646d92..8388657e43 100644 --- a/packages/openneuro-components/src/dataset/ModalitiesMetaDataBlock.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/ModalitiesMetaDataBlock.tsx @@ -1,6 +1,5 @@ import React from "react" import { Link } from "react-router-dom" -import Markdown from "markdown-to-jsx" export interface ModalitiesMetaDataBlockProps { items: string[] diff --git a/packages/openneuro-components/src/dataset/NemarButton.tsx b/packages/openneuro-app/src/scripts/dataset/components/NemarButton.tsx similarity index 86% rename from packages/openneuro-components/src/dataset/NemarButton.tsx rename to packages/openneuro-app/src/scripts/dataset/components/NemarButton.tsx index 8660200527..5bff38864d 100644 --- a/packages/openneuro-components/src/dataset/NemarButton.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/NemarButton.tsx @@ -1,6 +1,6 @@ import React from "react" -import { Tooltip } from "../tooltip/Tooltip" -import { Button } from "../button/Button" +import { Tooltip } from "@openneuro/components/tooltip" +import { Button } from "@openneuro/components/button" export interface NemarButtonProps { datasetId: string diff --git a/packages/openneuro-components/src/dataset/ValidationBlock.tsx b/packages/openneuro-app/src/scripts/dataset/components/ValidationBlock.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/ValidationBlock.tsx rename to packages/openneuro-app/src/scripts/dataset/components/ValidationBlock.tsx diff --git a/packages/openneuro-components/src/dataset/VersionList.tsx b/packages/openneuro-app/src/scripts/dataset/components/VersionList.tsx similarity index 96% rename from packages/openneuro-components/src/dataset/VersionList.tsx rename to packages/openneuro-app/src/scripts/dataset/components/VersionList.tsx index 9a97a0b37c..5bd0179bd8 100644 --- a/packages/openneuro-components/src/dataset/VersionList.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/VersionList.tsx @@ -1,8 +1,6 @@ import React from "react" import { Link } from "react-router-dom" -import { Dropdown } from "../dropdown/Dropdown" -import "../dropdown/dropdown.scss" -import "./version-dropdown.scss" +import { Dropdown } from "@openneuro/components/dropdown" export interface VersionListProps { items: { diff --git a/packages/openneuro-components/src/dataset/__tests__/DatasetAlert.spec.tsx b/packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetAlert.spec.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/__tests__/DatasetAlert.spec.tsx rename to packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetAlert.spec.tsx diff --git a/packages/openneuro-components/src/dataset/__tests__/DatasetHeaders.spec.tsx b/packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetHeaders.spec.tsx similarity index 100% rename from packages/openneuro-components/src/dataset/__tests__/DatasetHeaders.spec.tsx rename to packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetHeaders.spec.tsx diff --git a/packages/openneuro-components/src/dataset/__tests__/DatasetTools.spec.tsx b/packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetTools.spec.tsx similarity index 92% rename from packages/openneuro-components/src/dataset/__tests__/DatasetTools.spec.tsx rename to packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetTools.spec.tsx index e901526b43..e1813ec994 100644 --- a/packages/openneuro-components/src/dataset/__tests__/DatasetTools.spec.tsx +++ b/packages/openneuro-app/src/scripts/dataset/components/__tests__/DatasetTools.spec.tsx @@ -2,6 +2,15 @@ import React from "react" import { render, screen } from "@testing-library/react" import { MemoryRouter } from "react-router-dom" import { DatasetTools } from "../DatasetTools" +import { LocalStorageProvider } from "../../../utils/local-storage" + +const wrapper = ({ children }) => ( + <MemoryRouter> + <LocalStorageProvider defaultValue={{ agreement: true }}> + {children} + </LocalStorageProvider> + </MemoryRouter> +) describe("DatasetTools component", () => { it("provides expected tools for a draft (admin)", () => { @@ -14,7 +23,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={true} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Files")).toBeInTheDocument() expect(screen.queryByLabelText("Share")).toBeInTheDocument() @@ -36,7 +45,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={true} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Files")).toBeInTheDocument() expect(screen.queryByLabelText("View Draft")).toBeInTheDocument() @@ -55,7 +64,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={false} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Files")).toBeInTheDocument() expect(screen.queryByLabelText("View Draft")).not.toBeInTheDocument() @@ -75,7 +84,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={false} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Files")).toBeInTheDocument() expect(screen.queryByLabelText("View Draft")).not.toBeInTheDocument() @@ -94,7 +103,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={false} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Download")).toBeInTheDocument() expect(screen.queryByRole("link", { name: "Download" })).toHaveAttribute( @@ -113,7 +122,7 @@ describe("DatasetTools component", () => { hasSnapshot={true} isDatasetAdmin={false} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.queryByLabelText("Download")).toBeInTheDocument() expect(screen.queryByRole("link", { name: "Download" })).toHaveAttribute( diff --git a/packages/openneuro-app/src/scripts/dataset/draft-container.tsx b/packages/openneuro-app/src/scripts/dataset/draft-container.tsx index 6bc88a6b86..3dddec4ce0 100644 --- a/packages/openneuro-app/src/scripts/dataset/draft-container.tsx +++ b/packages/openneuro-app/src/scripts/dataset/draft-container.tsx @@ -17,17 +17,15 @@ import { } from "../authentication/profile" import { useCookies } from "react-cookie" import { DatasetAlertDraft } from "./fragments/dataset-alert-draft" -import { - BrainLifeButton, - CloneDropdown, - DatasetGitAccess, - DatasetHeader, - DatasetTools, - MetaDataBlock, - ModalitiesMetaDataBlock, - ValidationBlock, - VersionList, -} from "@openneuro/components/dataset" +import { BrainLifeButton } from "./components/BrainLifeButton" +import { CloneDropdown } from "./components/CloneDropdown" +import { DatasetGitAccess } from "./components/DatasetGitAccess" +import { DatasetHeader } from "./components/DatasetHeader" +import { DatasetTools } from "./components/DatasetTools" +import { MetaDataBlock } from "./components/MetaDataBlock" +import { ModalitiesMetaDataBlock } from "./components/ModalitiesMetaDataBlock" +import { ValidationBlock } from "./components/ValidationBlock" +import { VersionList } from "./components/VersionList" import { Username } from "../users/username" import { FollowDataset } from "./mutations/follow" diff --git a/packages/openneuro-app/src/scripts/dataset/files/__tests__/file.spec.jsx b/packages/openneuro-app/src/scripts/dataset/files/__tests__/file.spec.jsx index 5de8cb4664..130fb6b1d0 100644 --- a/packages/openneuro-app/src/scripts/dataset/files/__tests__/file.spec.jsx +++ b/packages/openneuro-app/src/scripts/dataset/files/__tests__/file.spec.jsx @@ -1,13 +1,22 @@ import React from "react" import { render, screen } from "@testing-library/react" import { MemoryRouter } from "react-router-dom" +import { LocalStorageProvider } from "../../../utils/local-storage.tsx" import File from "../file" +const wrapper = ({ children }) => ( + <MemoryRouter> + <LocalStorageProvider defaultValue={{ agreement: true }}> + {children} + </LocalStorageProvider> + </MemoryRouter> +) + describe("File component", () => { it("renders with common props", () => { const { asFragment } = render( <File datasetId="ds001" path="" filename="README" size={500} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(asFragment()).toMatchSnapshot() }) @@ -20,13 +29,13 @@ describe("File component", () => { filename="README" size={500} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(asFragment()).toMatchSnapshot() }) it("generates correct download links for top level files", () => { render(<File datasetId="ds001" path="" filename="README" size={500} />, { - wrapper: MemoryRouter, + wrapper, }) expect(screen.getByRole("link", { name: "download file" })).toHaveAttribute( "href", @@ -41,7 +50,7 @@ describe("File component", () => { filename="sub-01_T1w.nii.gz" size={2000000} />, - { wrapper: MemoryRouter }, + { wrapper }, ) expect(screen.getByRole("link", { name: "download file" })).toHaveAttribute( "href", diff --git a/packages/openneuro-app/src/scripts/dataset/files/file.tsx b/packages/openneuro-app/src/scripts/dataset/files/file.tsx index 0d7c944f1c..3eea0956b3 100644 --- a/packages/openneuro-app/src/scripts/dataset/files/file.tsx +++ b/packages/openneuro-app/src/scripts/dataset/files/file.tsx @@ -11,6 +11,7 @@ import { getProfile, hasEditPermissions } from "../../authentication/profile" import { Icon } from "@openneuro/components/icon" import { Tooltip } from "@openneuro/components/tooltip" import { useCookies } from "react-cookie" +import { useAgreement } from "../../components/agreement" const filePath = (path, filename) => `${(path && path + ":") || ""}${filename}` @@ -130,6 +131,7 @@ const File = ({ filename, ) }` + const [agreed] = useAgreement() const [cookies] = useCookies() const user = getProfile(cookies) return ( @@ -138,29 +140,33 @@ const File = ({ {filename} <span className="filetree-editfile"> - <Media greaterThanOrEqual="medium"> - <Tooltip - tooltip={`Download: ${bytes.format(Number(size)) as string}`} - > - <span className="edit-file download-file"> - <a - href={urls?.[0] || - apiPath(datasetId, snapshotTag, filePath(path, filename))} - download - aria-label="download file" - > - <i className="fa fa-download" /> - </a> + {agreed && ( + <Media greaterThanOrEqual="medium"> + <Tooltip + tooltip={`Download: ${bytes.format(Number(size)) as string}`} + > + <span className="edit-file download-file"> + <a + href={urls?.[0] || + apiPath(datasetId, snapshotTag, filePath(path, filename))} + download + aria-label="download file" + > + <i className="fa fa-download" /> + </a> + </span> + </Tooltip> + </Media> + )} + {agreed && ( + <Tooltip tooltip="View"> + <span className="edit-file view-file"> + <Link to={viewerPath} aria-label="view file"> + <i className="fa fa-eye" /> + </Link> </span> </Tooltip> - </Media> - <Tooltip tooltip="View"> - <span className="edit-file view-file"> - <Link to={viewerPath} aria-label="view file"> - <i className="fa fa-eye" /> - </Link> - </span> - </Tooltip> + )} {editMode && ( <Media greaterThanOrEqual="medium"> <Tooltip tooltip="Update"> diff --git a/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-draft.tsx b/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-draft.tsx index 17df01b0a7..fbf33352d9 100644 --- a/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-draft.tsx +++ b/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-draft.tsx @@ -1,6 +1,6 @@ import React from "react" import { Link } from "react-router-dom" -import { DatasetAlert } from "@openneuro/components/dataset" +import { DatasetAlert } from "../components/DatasetAlert" export interface DatasetAlertDraftProps { isPrivate: boolean diff --git a/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-version.tsx b/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-version.tsx index badbba0f4f..eb82a7ba8d 100644 --- a/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-version.tsx +++ b/packages/openneuro-app/src/scripts/dataset/fragments/dataset-alert-version.tsx @@ -1,5 +1,5 @@ import React from "react" -import { DatasetAlert } from "@openneuro/components/dataset" +import { DatasetAlert } from "../components/DatasetAlert" import { UndoDeprecateVersion } from "../mutations/undo-deprecate-version" export interface DatasetAlertVersionProps { diff --git a/packages/openneuro-app/src/scripts/dataset/routes/dataset-default.tsx b/packages/openneuro-app/src/scripts/dataset/routes/dataset-default.tsx index 657ca09ad4..385ef6bce2 100644 --- a/packages/openneuro-app/src/scripts/dataset/routes/dataset-default.tsx +++ b/packages/openneuro-app/src/scripts/dataset/routes/dataset-default.tsx @@ -1,7 +1,7 @@ import React from "react" import Markdown from "markdown-to-jsx" import { ReadMore } from "@openneuro/components/read-more" -import { MetaDataBlock } from "@openneuro/components/dataset" +import { MetaDataBlock } from "../components/MetaDataBlock" import Files from "../files/files" import Comments from "../comments/comments" import EditDescriptionField from "../fragments/edit-description-field" diff --git a/packages/openneuro-app/src/scripts/dataset/routes/download-dataset.tsx b/packages/openneuro-app/src/scripts/dataset/routes/download-dataset.tsx index a3e89b76ef..09592d6ecc 100644 --- a/packages/openneuro-app/src/scripts/dataset/routes/download-dataset.tsx +++ b/packages/openneuro-app/src/scripts/dataset/routes/download-dataset.tsx @@ -1,7 +1,7 @@ /* global globalThis */ import React from "react" import PropTypes from "prop-types" -import { useParams } from "react-router-dom" +import { Navigate, useParams } from "react-router-dom" import DownloadLink from "../download/download-link.jsx" import DownloadS3 from "../download/download-s3.jsx" import DownloadCommandLine from "../download/download-command-line.jsx" @@ -9,9 +9,15 @@ import DownloadDatalad from "../download/download-datalad.jsx" import { DatasetPageBorder } from "./styles/dataset-page-border" import { HeaderRow3 } from "./styles/header-row" import { DownloadScript } from "../download/download-script" +import { useAgreement } from "../../components/agreement" const DownloadDataset = ({ worker, datasetPermissions }) => { const { datasetId, tag: snapshotTag } = useParams() + const [agreed] = useAgreement() + // If the download page is directly visited without the agreement, return to the dataset page + if (!agreed) { + return <Navigate to={`/datasets/${datasetId}`} replace={true} /> + } const workerId = worker?.split("-").pop() return ( <DatasetPageBorder> diff --git a/packages/openneuro-app/src/scripts/dataset/routes/snapshot-default.tsx b/packages/openneuro-app/src/scripts/dataset/routes/snapshot-default.tsx index 55f42b7a83..d4e496e0c9 100644 --- a/packages/openneuro-app/src/scripts/dataset/routes/snapshot-default.tsx +++ b/packages/openneuro-app/src/scripts/dataset/routes/snapshot-default.tsx @@ -1,7 +1,7 @@ import React from "react" import Markdown from "markdown-to-jsx" import { ReadMore } from "@openneuro/components/read-more" -import { MetaDataBlock } from "@openneuro/components/dataset" +import { MetaDataBlock } from "../components/MetaDataBlock" import Files from "../files/files" import Comments from "../comments/comments" diff --git a/packages/openneuro-app/src/scripts/dataset/snapshot-container.tsx b/packages/openneuro-app/src/scripts/dataset/snapshot-container.tsx index cb233001a4..19ebe410ab 100644 --- a/packages/openneuro-app/src/scripts/dataset/snapshot-container.tsx +++ b/packages/openneuro-app/src/scripts/dataset/snapshot-container.tsx @@ -13,18 +13,16 @@ import { config } from "../config" import DatasetCitation from "./fragments/dataset-citation.jsx" import { DatasetAlertVersion } from "./fragments/dataset-alert-version" -import { - BrainLifeButton, - CloneDropdown, - DatasetGitAccess, - DatasetHeader, - DatasetTools, - MetaDataBlock, - ModalitiesMetaDataBlock, - NemarButton, - ValidationBlock, - VersionList, -} from "@openneuro/components/dataset" +import { BrainLifeButton } from "./components/BrainLifeButton" +import { CloneDropdown } from "./components/CloneDropdown" +import { DatasetGitAccess } from "./components/DatasetGitAccess" +import { DatasetHeader } from "./components/DatasetHeader" +import { DatasetTools } from "./components/DatasetTools" +import { MetaDataBlock } from "./components/MetaDataBlock" +import { ModalitiesMetaDataBlock } from "./components/ModalitiesMetaDataBlock" +import { ValidationBlock } from "./components/ValidationBlock" +import { VersionList } from "./components/VersionList" +import { NemarButton } from "./components/NemarButton" import { Username } from "../users/username" import { Loading } from "@openneuro/components/loading" diff --git a/packages/openneuro-app/src/scripts/scss/README.md b/packages/openneuro-app/src/scripts/scss/README.md new file mode 100644 index 0000000000..26d005a208 --- /dev/null +++ b/packages/openneuro-app/src/scripts/scss/README.md @@ -0,0 +1,3 @@ +Adding to the global SASS should be avoided if possible. New styles should be added as reusable components with the [Emotion package](https://emotion.sh). + +These global styles cross many components that haven't been refactored. Style changes that can do this would allow for more isolated component styles with less chance of breaking on cross component changes. diff --git a/packages/openneuro-components/src/dataset/comments.scss b/packages/openneuro-app/src/scripts/scss/dataset/comments.scss similarity index 100% rename from packages/openneuro-components/src/dataset/comments.scss rename to packages/openneuro-app/src/scripts/scss/dataset/comments.scss diff --git a/packages/openneuro-components/src/dataset/dataset-page.scss b/packages/openneuro-app/src/scripts/scss/dataset/dataset-page.scss similarity index 99% rename from packages/openneuro-components/src/dataset/dataset-page.scss rename to packages/openneuro-app/src/scripts/scss/dataset/dataset-page.scss index 10111b9f03..c47b636ff5 100644 --- a/packages/openneuro-components/src/dataset/dataset-page.scss +++ b/packages/openneuro-app/src/scripts/scss/dataset/dataset-page.scss @@ -1,4 +1,4 @@ -@import '../scss/variables'; +@import '../variables.scss'; .dataset { .dataset-header { h1 { diff --git a/packages/openneuro-components/src/dataset/dataset-tool.scss b/packages/openneuro-app/src/scripts/scss/dataset/dataset-tool.scss similarity index 99% rename from packages/openneuro-components/src/dataset/dataset-tool.scss rename to packages/openneuro-app/src/scripts/scss/dataset/dataset-tool.scss index 4ecd743eeb..9f222c3c79 100644 --- a/packages/openneuro-components/src/dataset/dataset-tool.scss +++ b/packages/openneuro-app/src/scripts/scss/dataset/dataset-tool.scss @@ -1,4 +1,4 @@ -@import '../scss/variables'; +@import '../variables.scss'; //share table .download-link { .return-link { diff --git a/packages/openneuro-app/src/scripts/scss/dataset/dropdown.scss b/packages/openneuro-app/src/scripts/scss/dataset/dropdown.scss new file mode 100644 index 0000000000..23aed85357 --- /dev/null +++ b/packages/openneuro-app/src/scripts/scss/dataset/dropdown.scss @@ -0,0 +1,29 @@ +@import '../variables.scss'; + +.dropdown-wrapper { + display: inline-block; + .toggle { + cursor: pointer; + } + .menu { + position: absolute; + overflow: hidden; + height: 0; + z-index: 9999; + right: 0; + background-color: #fff; + border-radius: $border-radius-default; + @media (max-width: 800px) { + width: 290px; + right: 0; + } + @media (max-width: 435px) { + right: 0; + left: 0; + } + + &.expanded { + height: auto; + } + } +} diff --git a/packages/openneuro-components/src/dataset/validation.scss b/packages/openneuro-app/src/scripts/scss/dataset/validation.scss similarity index 100% rename from packages/openneuro-components/src/dataset/validation.scss rename to packages/openneuro-app/src/scripts/scss/dataset/validation.scss diff --git a/packages/openneuro-components/src/dataset/version-dropdown.scss b/packages/openneuro-app/src/scripts/scss/dataset/version-dropdown.scss similarity index 98% rename from packages/openneuro-components/src/dataset/version-dropdown.scss rename to packages/openneuro-app/src/scripts/scss/dataset/version-dropdown.scss index 331d031dc7..03e3bf7d52 100644 --- a/packages/openneuro-components/src/dataset/version-dropdown.scss +++ b/packages/openneuro-app/src/scripts/scss/dataset/version-dropdown.scss @@ -1,4 +1,4 @@ -@import '../scss/variables'; +@import '../variables.scss'; .version-dropdown { .toggle { diff --git a/packages/openneuro-app/src/scripts/scss/index.scss b/packages/openneuro-app/src/scripts/scss/index.scss new file mode 100644 index 0000000000..55543d9fdc --- /dev/null +++ b/packages/openneuro-app/src/scripts/scss/index.scss @@ -0,0 +1,6 @@ +@import './dataset/comments.scss'; +@import './dataset/dataset-page.scss'; +@import './dataset/dataset-tool.scss'; +@import './dataset/dropdown.scss'; +@import './dataset/validation.scss'; +@import './dataset/version-dropdown.scss'; \ No newline at end of file diff --git a/packages/openneuro-app/src/scripts/scss/variables.scss b/packages/openneuro-app/src/scripts/scss/variables.scss new file mode 100644 index 0000000000..d13709ddc1 --- /dev/null +++ b/packages/openneuro-app/src/scripts/scss/variables.scss @@ -0,0 +1,205 @@ +$font-sans: 'Open Sans', sans-serif; + +//old vars +$white: #fff; +$black: #000; +$mine-shaft: #222; +$stanford-red: #8c1515; +$coral: #eb472c; +$salmon: #ec7764; + +$rock: #5f574f; +$stone: #928b81; +$driftwood: #b6b1a9; +$misty: #dad7cb; + +$fuchsia: #9169a7; + +$ocean: #00505c; +$algae: #175e54; +$sky: rgb(0, 124, 146); +$turquoise: #009b76; +$persian-green: #00b489; +$night: #012a30; +$jungle-mist: #b5cbd3; +$dodger-blue: #5890ff; + +$yellow: #ffd820; +$honey: #fffcee; + +$success: #24c85e; +$info: #24c8c8; +$warning: #f7ba4b; +$danger: #c82424; + +$notification-green: #77e6a3; + +$warning-orange-cream: #ffefdb; +$warning-orange: #df7600; + +//end old vars + +$charcoal: #333; +$newspaper: #dfdfdf; + +/* SCSS RGB */ +$on-light-aqua: rgb(55, 188, 210); +$on-dark-aqua: rgba(32, 78, 90, 1); +$on-secondary: #196583; +$on-dark-aqua-light: #e5f4f7; + +$mri-theme: rgba(79, 51, 130, 1); +$mri-hover: adjust-color($mri-theme, $lightness: 10%); +$mri-dark: darken($mri-theme, 25%); +$mri-secondary: adjust-color($mri-theme, $lightness: 15%); +$mri-light: adjust-color($mri-theme, $lightness: 45%); + +$eeg-theme: rgba(134, 31, 55, 1); +$eeg-hover: adjust-color($eeg-theme, $lightness: 10%); +$eeg-dark: darken($eeg-theme, 25%); +$eeg-secondary: adjust-color($eeg-theme, $lightness: 15%); +$eeg-light: adjust-color($eeg-theme, $lightness: 45%); + +$pet-theme: rgba(0, 105, 192, 1); +$pet-hover: adjust-color($pet-theme, $lightness: 10%); +$pet-dark: darken($pet-theme, 25%); +$pet-secondary: adjust-color($pet-theme, $lightness: 15%); +$pet-light: adjust-color($pet-theme, $lightness: 45%); + +$ieeg-theme: rgba(18, 109, 62, 1); +$ieeg-hover: adjust-color($ieeg-theme, $lightness: 10%); +$ieeg-dark: darken($ieeg-theme, 25%); +$ieeg-secondary: adjust-color($ieeg-theme, $lightness: 15%); +$ieeg-light: rgb(200, 212, 153); + +$meg-theme: rgba(156, 57, 0, 1); +$meg-hover: adjust-color($meg-theme, $lightness: 10%); +$meg-dark: darken($meg-theme, 25%); +$meg-secondary: adjust-color($meg-theme, $lightness: 15%); +$meg-light: adjust-color($meg-theme, $lightness: 45%); + +$on-light-green: #00eeb5; +$on-light-red: #c00342; +$on-light-orange: rgb(255, 110, 43); + +$primary: $on-dark-aqua; + +$chiclet-color: #a2059e; + +/* CSS HEX */ +:root { + --mri-theme: #{$mri-theme}; + --eeg-theme: #{$eeg-theme}; + --pet-theme: #{$pet-theme}; + --ieeg-theme: #{$ieeg-theme}; + --meg-theme: #{$meg-theme}; + + --on-light-aqua: #{$on-light-aqua}; + --on-dark-aqua: #{$on-dark-aqua}; + --on-light-green: #{on-light-green}; + + --current-theme-primary: #{$on-dark-aqua}; + --current-theme-primary-hover: #{$on-light-aqua}; + --current-theme-secondary: #{$on-secondary}; + --current-theme-primary-dark: #{$on-dark-aqua}; + --current-theme-primary-light: #{$on-dark-aqua-light}; + --current-theme-header: #333; + --current-theme-header-dark: #333; +} + +.mri-theme { + background-color: $mri-theme; +} +.eeg-theme { + background-color: $eeg-theme; +} + +.pet-theme { + background-color: $pet-theme; +} +.ieeg-theme { + background-color: $ieeg-theme; +} + +.on-light-aqua { + background-color: $on-light-aqua; +} +.on-light-green { + background-color: $on-light-green; +} +.on-dark-aqua { + background-color: $on-dark-aqua; +} + +.meg-theme { + background-color: $meg-theme; +} + +.gray-bg { + background: #f3f3f3; +} + +//Base unit used for spacing gutters +$base-unit: 20px; + +//Screen Sizes +$screen-sm: 480px; +$screen-md: 767px; +$screen-lg: 989px; + +$border-radius-default: 4px; + +.search-page-mri, +.dataset-page-mri { + --current-theme-primary: #{$mri-theme}; + --current-theme-primary-hover: #{$mri-hover}; + --current-theme-primary-dark: #{$mri-dark}; + --current-theme-secondary: #{$mri-secondary}; + --current-theme-primary-light: #{$mri-light}; + --current-theme-header: #{$mri-theme}; + --current-theme-header-dark: #{$mri-dark}; +} + +.search-page-eeg, +.dataset-page-eeg { + --current-theme-primary: #{$eeg-theme}; + --current-theme-primary-hover: #{$eeg-hover}; + --current-theme-primary-dark: #{$eeg-dark}; + --current-theme-secondary: #{$eeg-secondary}; + --current-theme-primary-light: #{$eeg-light}; + --current-theme-header: #{$eeg-theme}; + --current-theme-header-dark: #{$eeg-dark}; +} + +.search-page-pet, +.dataset-page-pet { + --current-theme-primary: #{$pet-theme}; + --current-theme-primary-hover: #{$pet-hover}; + --current-theme-primary-dark: #{$pet-dark}; + --current-theme-secondary: #{$pet-secondary}; + --current-theme-primary-light: #{$pet-light}; + --current-theme-header: #{$pet-theme}; + --current-theme-header-dark: #{$pet-dark}; +} + +.search-page-ieeg, +.dataset-page-ieeg { + --current-theme-primary: #{$ieeg-theme}; + --current-theme-primary-hover: #{$ieeg-hover}; + --current-theme-primary-dark: #{$ieeg-dark}; + --current-theme-secondary: #{$ieeg-secondary}; + --current-theme-primary-light: #{$ieeg-light}; + --current-theme-header: #{$ieeg-theme}; + --current-theme-header-dark: #{$ieeg-dark}; +} + +.search-page-meg, +.dataset-page-meg { + --current-theme-primary: #{$meg-theme}; + --current-theme-primary-hover: #{$meg-hover}; + --current-theme-primary-dark: #{$meg-dark}; + --current-theme-secondary: #{$meg-secondary}; + --current-theme-primary-light: #{$meg-light}; + --current-theme-header: #{$meg-theme}; + --current-theme-header-dark: #{$meg-dark}; +} diff --git a/packages/openneuro-app/src/scripts/utils/__tests__/local-storage.spec.tsx b/packages/openneuro-app/src/scripts/utils/__tests__/local-storage.spec.tsx new file mode 100644 index 0000000000..da06759a0e --- /dev/null +++ b/packages/openneuro-app/src/scripts/utils/__tests__/local-storage.spec.tsx @@ -0,0 +1,32 @@ +import React, { useEffect } from "react" +import { render } from "@testing-library/react" +import { LocalStorageProvider, useLocalStorage } from "../local-storage" + +const STORAGE_KEY = "tests" + +const TestComponent = () => { + const [value, setValue] = useLocalStorage(STORAGE_KEY) + useEffect(() => { + setValue("testing") + }, [value]) + return null +} + +describe("localStorage hooks", () => { + beforeEach(() => { + localStorage.clear() + }) + afterEach(() => { + localStorage.clear() + }) + it("sets and retrieves a value", () => { + render( + <LocalStorageProvider defaultValue={{}}> + <TestComponent /> + </LocalStorageProvider>, + ) + expect(JSON.parse(localStorage.getItem("openneuro")).tests).toEqual( + "testing", + ) + }) +}) diff --git a/packages/openneuro-app/src/scripts/utils/local-storage.tsx b/packages/openneuro-app/src/scripts/utils/local-storage.tsx new file mode 100644 index 0000000000..8d6a9faef8 --- /dev/null +++ b/packages/openneuro-app/src/scripts/utils/local-storage.tsx @@ -0,0 +1,53 @@ +import React from "react" +import { createContext, useContext, useEffect, useState } from "react" + +/** Shared context for all local storage updates */ +const LocalStorageContext = createContext({ + localStorageValue: { agreement: false }, + setLocalStorageValue: undefined, +}) + +const LOCAL_STORAGE_KEY = "openneuro" + +function getStorageValue<T>(key: string, defaultValue: T): T { + const saved = localStorage.getItem(key) + if (saved) return JSON.parse(saved) + else return defaultValue +} + +/** + * Local storage hook that updates across components + * @param key Field name for localstorage object + */ +export function useLocalStorage<T>( + key: string, +): [T, (value: T) => void] { + const context = useContext(LocalStorageContext) + const setValue = (value: T) => { + const update = {} + update[key] = value + context?.setLocalStorageValue(update) + } + return [context?.localStorageValue[key], setValue] +} + +export function LocalStorageProvider({ children, defaultValue }) { + const [localStorageValue, setLocalStorageValue] = useState(() => { + return getStorageValue(LOCAL_STORAGE_KEY, defaultValue) + }) + + useEffect(() => { + const val = localStorage.getItem(LOCAL_STORAGE_KEY) + const prev = val ? JSON.parse(val) : {} + const updateValue = { ...prev, ...defaultValue, ...localStorageValue } + localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(updateValue)) + }, [localStorageValue]) + + return ( + <LocalStorageContext.Provider + value={{ localStorageValue, setLocalStorageValue }} + > + {children} + </LocalStorageContext.Provider> + ) +} diff --git a/packages/openneuro-components/src/dataset/index.ts b/packages/openneuro-components/src/dataset/index.ts deleted file mode 100644 index 06d2b06c24..0000000000 --- a/packages/openneuro-components/src/dataset/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { MetaDataBlock } from "./MetaDataBlock" -import { MetaDataListBlock } from "./MetaDataListBlock" -import { ModalitiesMetaDataBlock } from "./ModalitiesMetaDataBlock" -import { NemarButton } from "./NemarButton" -import { BrainLifeButton } from "./BrainLifeButton" -import { ValidationBlock } from "./ValidationBlock" -import { CloneDropdown } from "./CloneDropdown" -import { DatasetHeader } from "./DatasetHeader" -import { DatasetAlert } from "./DatasetAlert" -import { DatasetHeaderMeta } from "./DatasetHeaderMeta" -import { DatasetGitAccess } from "./DatasetGitAccess" -import { DatasetTools } from "./DatasetTools" -import { VersionList } from "./VersionList" - -export { - BrainLifeButton, - CloneDropdown, - DatasetAlert, - DatasetGitAccess, - DatasetHeader, - DatasetHeaderMeta, - DatasetTools, - MetaDataBlock, - MetaDataListBlock, - ModalitiesMetaDataBlock, - NemarButton, - ValidationBlock, - VersionList, -} diff --git a/packages/openneuro-components/src/page/page.scss b/packages/openneuro-components/src/page/page.scss index 2587f1cf82..3b8d9b9e17 100644 --- a/packages/openneuro-components/src/page/page.scss +++ b/packages/openneuro-components/src/page/page.scss @@ -36,11 +36,10 @@ @import '../search-page/search-result.scss'; @import '../search-page/search-sort.scss'; @import '../search-page/filters-block.scss'; -@import '../dataset/dataset-page.scss'; -@import '../dataset/dataset-tool.scss'; -@import '../dataset/comments.scss'; - -@import '../dataset/validation.scss'; +//@import '../dataset/dataset-page.scss'; +//@import '../dataset/dataset-tool.scss'; +//@import '../dataset/comments.scss'; +//@import '../dataset/validation.scss'; @import '../json-tree/json-tree.scss'; .page {