From 72cd46f80034679053175d4f916be4d6102dd92e Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Thu, 12 Sep 2024 11:33:40 +0200 Subject: [PATCH] show license for project --- .../LicenseModal/LicenseModal.component.tsx | 19 +++++++++++++++++ .../Modal/LicenseModal/index.ts | 1 + .../FunctionalArea/Modal/Modal.component.tsx | 6 ++++++ .../ProjectInfoDrawer.component.tsx | 21 ++++++++++++++++++- src/models/licenseSchema.ts | 1 + src/models/projectSchema.ts | 6 +++--- src/redux/modal/modal.reducers.ts | 6 ++++++ src/redux/modal/modal.slice.ts | 3 +++ src/types/modal.ts | 1 + 9 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/components/FunctionalArea/Modal/LicenseModal/LicenseModal.component.tsx create mode 100644 src/components/FunctionalArea/Modal/LicenseModal/index.ts diff --git a/src/components/FunctionalArea/Modal/LicenseModal/LicenseModal.component.tsx b/src/components/FunctionalArea/Modal/LicenseModal/LicenseModal.component.tsx new file mode 100644 index 00000000..bdb79d2d --- /dev/null +++ b/src/components/FunctionalArea/Modal/LicenseModal/LicenseModal.component.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { useAppSelector } from '@/redux/hooks/useAppSelector'; +import { projectSelector } from '@/redux/project/project.selectors'; + +export const LicenseModal = (): React.ReactNode => { + const project = useAppSelector(projectSelector).data; + + let licenseDescription = ''; + if (project) { + licenseDescription = project.license + ? `<a href="${project.license.url}" target="_blank">Link</a><br/><br/>${project.license.content}` + : `<a href="${project.customLicenseUrl}" target="_blank">Link: ${project.customLicenseUrl}</a>`; + } + return ( + <div className="w-full overflow-auto border border-t-[#E1E0E6] bg-white p-[24px]"> + <div dangerouslySetInnerHTML={{ __html: licenseDescription }} /> + </div> + ); +}; diff --git a/src/components/FunctionalArea/Modal/LicenseModal/index.ts b/src/components/FunctionalArea/Modal/LicenseModal/index.ts new file mode 100644 index 00000000..b05258c6 --- /dev/null +++ b/src/components/FunctionalArea/Modal/LicenseModal/index.ts @@ -0,0 +1 @@ +export { LicenseModal } from './LicenseModal.component'; diff --git a/src/components/FunctionalArea/Modal/Modal.component.tsx b/src/components/FunctionalArea/Modal/Modal.component.tsx index 10ee738f..8b97ece7 100644 --- a/src/components/FunctionalArea/Modal/Modal.component.tsx +++ b/src/components/FunctionalArea/Modal/Modal.component.tsx @@ -3,6 +3,7 @@ import { modalSelector } from '@/redux/modal/modal.selector'; import dynamic from 'next/dynamic'; import { AccessDeniedModal } from '@/components/FunctionalArea/Modal/AccessDeniedModal/AccessDeniedModal.component'; import { AddCommentModal } from '@/components/FunctionalArea/Modal/AddCommentModal/AddCommentModal.component'; +import { LicenseModal } from '@/components/FunctionalArea/Modal/LicenseModal'; import { EditOverlayModal } from './EditOverlayModal'; import { LoginModal } from './LoginModal'; import { ErrorReportModal } from './ErrorReportModal'; @@ -41,6 +42,11 @@ export const Modal = (): React.ReactNode => { <ErrorReportModal /> </ModalLayout> )} + {isOpen && modalName === 'license' && ( + <ModalLayout> + <LicenseModal /> + </ModalLayout> + )} {isOpen && modalName === 'publications' && <PublicationsModal />} {isOpen && modalName === 'edit-overlay' && ( <ModalLayout> diff --git a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx index 5a04b6fa..9bf8267c 100644 --- a/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx +++ b/src/components/Map/Drawer/ProjectInfoDrawer/ProjectInfoDrawer.component.tsx @@ -1,7 +1,7 @@ import { apiPath } from '@/redux/apiPath'; import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; import { useAppSelector } from '@/redux/hooks/useAppSelector'; -import { openPublicationsModal } from '@/redux/modal/modal.slice'; +import { openLicenseModal, openPublicationsModal } from '@/redux/modal/modal.slice'; import { mainMapModelDescriptionSelector } from '@/redux/models/models.selectors'; import { diseaseLinkSelector, @@ -9,6 +9,7 @@ import { organismLinkSelector, organismNameSelector, projectNameSelector, + projectSelector, versionSelector, } from '@/redux/project/project.selectors'; import { DrawerHeading } from '@/shared/DrawerHeading'; @@ -23,11 +24,18 @@ export const ProjectInfoDrawer = (): JSX.Element => { const organismLink = useAppSelector(organismLinkSelector); const organismName = useAppSelector(organismNameSelector); const projectName = useAppSelector(projectNameSelector); + const project = useAppSelector(projectSelector).data; const version = useAppSelector(versionSelector); const description = useAppSelector(mainMapModelDescriptionSelector); const sourceDownloadLink = window.location.hostname + apiPath.getSourceFile(); + let licenseName: string = ''; + if (project) { + licenseName = project.license ? project.license.name : project.customLicenseName; + } + const licenseExists = licenseName !== ''; + useEffect(() => { // dispatch(getPublications()); }, [dispatch]); @@ -36,6 +44,10 @@ export const ProjectInfoDrawer = (): JSX.Element => { dispatch(openPublicationsModal()); }; + const onLicenseClick = (): void => { + dispatch(openLicenseModal(licenseName)); + }; + return ( <div data-testid="export-drawer" className="h-full max-h-full"> <DrawerHeading title="Project info" /> @@ -76,6 +88,13 @@ export const ProjectInfoDrawer = (): JSX.Element => { </a> </li> )} + {licenseExists && ( + <li className="mt-2 text-hyperlink-blue"> + <button type="button" onClick={onLicenseClick} className="text-base font-semibold"> + License: {licenseName} + </button> + </li> + )} {organismName && ( <li className="mt-2 text-hyperlink-blue"> <span className="text-black">Organism: </span> diff --git a/src/models/licenseSchema.ts b/src/models/licenseSchema.ts index 54d6f478..3111314e 100644 --- a/src/models/licenseSchema.ts +++ b/src/models/licenseSchema.ts @@ -3,5 +3,6 @@ import { z } from 'zod'; export const licenseSchema = z.object({ id: z.number().int().positive(), name: z.string(), + url: z.string(), content: z.string(), }); diff --git a/src/models/projectSchema.ts b/src/models/projectSchema.ts index 5bfb3634..39862947 100644 --- a/src/models/projectSchema.ts +++ b/src/models/projectSchema.ts @@ -24,7 +24,7 @@ export const projectSchema = z.object({ creationDate: z.string(), overviewImageViews: z.array(overviewImageView), topOverviewImage: overviewImageView.nullable(), - license: z.optional(licenseSchema), - customLicenseName: z.string().nullable(), - customLicenseUrl: z.string().nullable(), + license: z.optional(licenseSchema).nullable(), + customLicenseName: z.string(), + customLicenseUrl: z.string(), }); diff --git a/src/redux/modal/modal.reducers.ts b/src/redux/modal/modal.reducers.ts index f2eecb87..4556c17c 100644 --- a/src/redux/modal/modal.reducers.ts +++ b/src/redux/modal/modal.reducers.ts @@ -103,3 +103,9 @@ export const openEditOverlayModalReducer = ( state.modalTitle = action.payload.name; state.editOverlayState = action.payload; }; + +export const openLicenseModalReducer = (state: ModalState, action: PayloadAction<string>): void => { + state.isOpen = true; + state.modalName = 'license'; + state.modalTitle = `License: ${action.payload}`; +}; diff --git a/src/redux/modal/modal.slice.ts b/src/redux/modal/modal.slice.ts index 33263ed3..3e945e4a 100644 --- a/src/redux/modal/modal.slice.ts +++ b/src/redux/modal/modal.slice.ts @@ -14,6 +14,7 @@ import { openErrorReportModalReducer, openAccessDeniedModalReducer, openSelectProjectModalReducer, + openLicenseModalReducer, } from './modal.reducers'; const modalSlice = createSlice({ @@ -33,6 +34,7 @@ const modalSlice = createSlice({ openErrorReportModal: openErrorReportModalReducer, openAccessDeniedModal: openAccessDeniedModalReducer, openSelectProjectModal: openSelectProjectModalReducer, + openLicenseModal: openLicenseModalReducer, }, }); @@ -50,6 +52,7 @@ export const { openErrorReportModal, openAccessDeniedModal, openSelectProjectModal, + openLicenseModal, } = modalSlice.actions; export default modalSlice.reducer; diff --git a/src/types/modal.ts b/src/types/modal.ts index 867b764c..1030c46b 100644 --- a/src/types/modal.ts +++ b/src/types/modal.ts @@ -4,6 +4,7 @@ export type ModalName = | 'overview-images' | 'mol-art' | 'login' + | 'license' | 'publications' | 'edit-overlay' | 'error-report' -- GitLab