diff --git a/CHANGELOG b/CHANGELOG index 1d7d4dced848af18241ebcafff8fd6d03dcc40bb..75a4c94b11dc7c8924866b8a7f6113dbfcf522c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,13 @@ minerva-front (19.0.0~alpha.0) stable; urgency=medium -- Piotr Gawron <piotr.gawron@uni.lu> Fri, 18 Oct 2024 13:00:00 +0200 +minerva-front (18.1.1) stable; urgency=medium + * Bug fix: styling of notes reset only for a href (#334) + * Bug fix: disable searching for chemicals in projects without disease (#347) + * Bug fix: public overlays were not sorted (#349) + +-- Piotr Gawron <piotr.gawron@uni.lu> Tue, 04 Feb 2025 16:00:00 +0200 + minerva-front (18.1.0) stable; urgency=medium * Small improvement: support for links that should be opened immediately (#342) @@ -22,7 +29,6 @@ minerva-front (18.1.0) stable; urgency=medium * Bug fix: submap download did not download selected map (#337) * Bug fix: styling of notes contains original styling for links (#344) - -- Piotr Gawron <piotr.gawron@uni.lu> Thu, 30 Jan 2025 15:00:00 +0200 minerva-front (18.0.7) stable; urgency=medium diff --git a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.test.tsx b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.test.tsx index c0bb50583b1e19999dafd406aa4cadf0e9a7bbf5..2946b8e5470c880bb1a371c172d7216f280b58c8 100644 --- a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.test.tsx +++ b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.test.tsx @@ -14,6 +14,8 @@ import { MODEL_ELEMENT_LINKING_TO_SUBMAP, MODEL_ELEMENTS_SEARCH_INITIAL_STATE_MOCK, } from '@/redux/modelElements/modelElements.mock'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { PROJECT_STATE_INITIAL_MOCK } from '@/redux/project/project.mock'; import { BioEntityDrawer } from './BioEntityDrawer.component'; const renderComponent = ( @@ -261,6 +263,13 @@ describe('BioEntityDrawer - component', () => { it('should fetch chemicals on chemicals for target click', () => { const { store } = renderComponent({ + ...INITIAL_STORE_STATE_MOCK, + project: { + data: projectFixture, + loading: 'succeeded', + error: { message: '', name: '' }, + projectId: projectFixture.projectId, + }, modelElements: { data: { 0: { @@ -311,6 +320,10 @@ describe('BioEntityDrawer - component', () => { chemicals: {}, }, }, + project: { + ...PROJECT_STATE_INITIAL_MOCK, + data: projectFixture, + }, }); const button = screen.getByText('Drugs for target', { exact: false }); diff --git a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx index 259e7ac69bc3abc1420022fa0440f892d2f5c67d..8800a362a9d96b222701f48937be2451bb4bd808 100644 --- a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx +++ b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx @@ -18,6 +18,8 @@ import { currentDrawerModelElementRelatedSubmapSelector, currentDrawerModelElementSelector, } from '@/redux/modelElements/modelElements.selector'; +import { projectDataSelector } from '@/redux/project/project.selectors'; +import { showToast } from '@/utils/showToast'; import { CollapsibleSection } from '../ExportDrawer/CollapsibleSection'; import { AssociatedSubmap } from './AssociatedSubmap'; import { ChemicalsList } from './ChemicalsList'; @@ -32,8 +34,18 @@ export const BioEntityDrawer = (): React.ReactNode => { const commentsData = useAppSelector(currentDrawerElementCommentsSelector); const relatedSubmap = useAppSelector(currentDrawerModelElementRelatedSubmapSelector); const currentTargetId = modelElement?.id ? `${TARGET_PREFIX}:${modelElement.id}` : ''; + + const project = useAppSelector(projectDataSelector); + const fetchChemicalsForTarget = (): void => { - dispatch(getChemicalsForBioEntityDrawerTarget(currentTargetId)); + if (project === undefined || project.disease === null || project.disease === undefined) { + showToast({ + type: 'info', + message: `Project disease not defined. Only projects with defined disease have chemical search available`, + }); + } else { + dispatch(getChemicalsForBioEntityDrawerTarget(currentTargetId)); + } }; const compartmentName = useAppSelector(state => compartmentNameByIdSelector(state, modelElement?.compartment), @@ -74,7 +86,7 @@ export const BioEntityDrawer = (): React.ReactNode => { </div> )} {modelElement.notes && ( - <span className="visited:text-purple-600 text-blue-600 underline hover:text-blue-800"> + <span className="[&_a]:text-blue-600 [&_a]:underline [&_a]:hover:text-blue-800"> <hr className="border-b border-b-divide" /> <div className="mt-2 text-sm font-normal" diff --git a/src/components/Map/Drawer/OverlaysDrawer/UserOverlays/UserOverlaysGroup/UserOverlaysGroup.component.tsx b/src/components/Map/Drawer/OverlaysDrawer/UserOverlays/UserOverlaysGroup/UserOverlaysGroup.component.tsx index 872cf5847758f5109deb9287654e132e34f6d823..cc98213947b5761934a64624f2efed57e8c9d27e 100644 --- a/src/components/Map/Drawer/OverlaysDrawer/UserOverlays/UserOverlaysGroup/UserOverlaysGroup.component.tsx +++ b/src/components/Map/Drawer/OverlaysDrawer/UserOverlays/UserOverlaysGroup/UserOverlaysGroup.component.tsx @@ -67,7 +67,7 @@ export const UserOverlaysGroup = ({ sideMenu={ groupId && ( <button onClick={openEditGroup} type="button" className="mr-2"> - <Icon name="edit-image" /> + <Icon name="pencil" /> </button> ) } diff --git a/src/models/disease.ts b/src/models/disease.ts deleted file mode 100644 index b83325f70086e89274803983a72e495687a9bb58..0000000000000000000000000000000000000000 --- a/src/models/disease.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { z } from 'zod'; - -export const disease = z.object({ - id: z.number().int().positive(), - link: z.string().nullable(), - type: z.string(), - resource: z.string(), - annotatorClassName: z.string(), -}); diff --git a/src/models/generators/diseaseGenerator.ts b/src/models/generators/diseaseGenerator.ts index 1e8ae525f101fe84da27ec49f665e0481af429aa..83dabef632bdda9938c8f67940a2d35b3aa5d9fb 100644 --- a/src/models/generators/diseaseGenerator.ts +++ b/src/models/generators/diseaseGenerator.ts @@ -1,8 +1,8 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { createFixture, Generator } from 'zod-fixture'; -import { disease } from '@/models/disease'; import { ZOD_SEED } from '@/constants'; import { ZodNullable } from 'zod'; +import { referenceSchema } from '@/models/referenceSchema'; export const diseaseGenerator = Generator({ schema: ZodNullable, @@ -11,7 +11,7 @@ export const diseaseGenerator = Generator({ return context.path.at(-1) === 'disease'; }, output: () => - createFixture(disease, { + createFixture(referenceSchema, { seed: ZOD_SEED, array: { min: 2, max: 2 }, }), diff --git a/src/models/projectSchema.ts b/src/models/projectSchema.ts index eeb1f6f33a0212a9b77638bce5ec4ca39509f014..23886962f938acdc929fd5f4df6015b403d5bc37 100644 --- a/src/models/projectSchema.ts +++ b/src/models/projectSchema.ts @@ -1,13 +1,13 @@ import { z } from 'zod'; import { licenseSchema } from '@/models/licenseSchema'; -import { disease } from './disease'; +import { referenceSchema } from '@/models/referenceSchema'; import { organism } from './organism'; import { overviewImageView } from './overviewImageView'; export const projectSchema = z.object({ id: z.number().int().nonnegative(), version: z.string(), - disease: disease.nullable(), + disease: referenceSchema.nullable(), diseaseName: z.string().nullable(), organism: organism.nullable(), organismName: z.string().nullable(), diff --git a/src/redux/overlays/overlays.thunks.ts b/src/redux/overlays/overlays.thunks.ts index 11352f9f0b7705f1813139121f1564720b054f4a..53274ba876c08aa9693241b54edfd5069ccca89e 100644 --- a/src/redux/overlays/overlays.thunks.ts +++ b/src/redux/overlays/overlays.thunks.ts @@ -44,7 +44,9 @@ export const getAllPublicOverlaysByProjectId = createAsyncThunk<MapOverlay[], st pageableSchema(mapOverlaySchema), ); - return isDataValid ? response.data.content : []; + return isDataValid + ? response.data.content.sort((overlayA, overlayB) => overlayA.order - overlayB.order) + : []; } catch (error) { return Promise.reject(getError({ error, prefix: OVERLAYS_FETCHING_ERROR_PREFIX })); } diff --git a/src/shared/Toast/Toast.component.tsx b/src/shared/Toast/Toast.component.tsx index c8d7804c2ddc4f79dd6424ba7085d9b6d6f9537a..6706cb84001b96e452c7e2765d48b67ef747760a 100644 --- a/src/shared/Toast/Toast.component.tsx +++ b/src/shared/Toast/Toast.component.tsx @@ -2,23 +2,32 @@ import { twMerge } from 'tailwind-merge'; import { Icon } from '../Icon'; type ToastArgs = { - type: 'success' | 'error'; + type: 'success' | 'error' | 'info'; message: string; onDismiss: () => void; }; +const textColors = { + error: 'text-red-500', + success: 'text-green-500', + info: 'text-blue-500', +}; + +const bgColors = { + error: 'before:bg-red-500', + success: 'before:bg-green-500', + info: 'before:bg-blue-500', +}; + export const Toast = ({ type, message, onDismiss }: ToastArgs): React.ReactNode => ( <div className={twMerge( 'flex h-[76px] w-[700px] items-center rounded-l rounded-r-lg bg-white p-4 drop-shadow before:absolute before:inset-y-0 before:left-0 before:block before:w-1 before:rounded-l-lg before:content-[""]', - type === 'error' ? 'before:bg-red-500' : 'before:bg-green-500', + bgColors[type], )} > <p - className={twMerge( - 'h-full overflow-y-auto text-base font-bold', - type === 'error' ? 'text-red-500' : 'text-green-500', - )} + className={twMerge('h-full overflow-y-auto text-base font-bold', textColors[type])} dangerouslySetInnerHTML={{ __html: message }} /> diff --git a/src/utils/showToast.tsx b/src/utils/showToast.tsx index 19cf088efa33e211ecc440c0ca3b5ceb96d4ef61..101491abea7ff7efe4dcce65d0d4af0a8133181d 100644 --- a/src/utils/showToast.tsx +++ b/src/utils/showToast.tsx @@ -4,7 +4,7 @@ import { Toast } from '@/shared/Toast'; const DEFAULT_DURATION_MS = 5000; type ShowToastArgs = { - type: 'success' | 'error'; + type: 'success' | 'error' | 'info'; message: string; duration?: number; };