+
+
-
+
>
);
}
diff --git a/website/src/components/subscriptions/create/SubscriptionsCreate.tsx b/website/src/components/subscriptions/create/SubscriptionsCreate.tsx
index 3c8e6c90..4a9acc04 100644
--- a/website/src/components/subscriptions/create/SubscriptionsCreate.tsx
+++ b/website/src/components/subscriptions/create/SubscriptionsCreate.tsx
@@ -2,8 +2,6 @@ import '@genspectrum/dashboard-components/components';
import '@genspectrum/dashboard-components/style.css';
import { useMutation } from '@tanstack/react-query';
import { useState } from 'react';
-import { toast } from 'react-toastify';
-import { v4 as uuidv4 } from 'uuid';
import { FilterDisplay } from './FilterDisplay.tsx';
import { IntervalInput } from './IntervalInput.tsx';
@@ -22,7 +20,7 @@ import { type EvaluationInterval, EvaluationIntervals } from '../../../types/Eva
import { type Organism, Organisms } from '../../../types/Organism.ts';
import type { SubscriptionRequest, Trigger } from '../../../types/Subscription.ts';
import { getErrorLogMessage } from '../../../util/getErrorLogMessage.ts';
-import { ErrorReportToastModal } from '../../ErrorReportInstruction.tsx';
+import { useErrorToast } from '../../ErrorReportInstruction.tsx';
import { GsApp } from '../../genspectrum/GsApp.tsx';
import { getBackendServiceForClientside } from '../backendApi/backendService.ts';
import { withQueryProvider } from '../backendApi/withQueryProvider.tsx';
@@ -42,6 +40,8 @@ export function SubscriptionsCreateInner({
// TODO: Enable notificationChannels in #82, #128
// notificationChannels: NotificationChannels;
}) {
+ const { showErrorToast } = useErrorToast(logger);
+
const createSubscription = useMutation({
mutationFn: () =>
getBackendServiceForClientside().postSubscription({
@@ -49,20 +49,11 @@ export function SubscriptionsCreateInner({
userId,
}),
onError: (error) => {
- const errorId = uuidv4();
- logger.error(`Failed to create a new subscription: ${getErrorLogMessage(error)}`, {
- errorId,
+ showErrorToast({
+ error,
+ logMessage: `Failed to create a new subscription: ${getErrorLogMessage(error)}`,
+ errorToastMessages: ['We could not create your subscription. Please try again later.'],
});
- toast.error(
- <>
-
We could not create your subscription. Please try again later.
-
- >,
- {
- position: 'bottom-left',
- autoClose: false,
- },
- );
},
});
diff --git a/website/src/components/subscriptions/overview/SubscriptionEntry.tsx b/website/src/components/subscriptions/overview/SubscriptionEntry.tsx
index 625e9933..82f330b9 100644
--- a/website/src/components/subscriptions/overview/SubscriptionEntry.tsx
+++ b/website/src/components/subscriptions/overview/SubscriptionEntry.tsx
@@ -1,7 +1,6 @@
import { useMutation } from '@tanstack/react-query';
import { type JSX, type RefObject } from 'react';
import { toast } from 'react-toastify';
-import { v4 as uuidv4 } from 'uuid';
import { SubscriptionDisplay } from './SubscriptionDisplay.tsx';
import { getClientLogger } from '../../../clientLogger.ts';
@@ -13,7 +12,7 @@ import { ModalHeader } from '../../../styles/containers/ModalHeader.tsx';
import { organismConfig } from '../../../types/Organism.ts';
import type { Subscription } from '../../../types/Subscription.ts';
import { getErrorLogMessage } from '../../../util/getErrorLogMessage.ts';
-import { ErrorReportToastModal } from '../../ErrorReportInstruction.tsx';
+import { useErrorToast } from '../../ErrorReportInstruction.tsx';
import { getBackendServiceForClientside } from '../backendApi/backendService.ts';
const logger = getClientLogger('SubscriptionEntry');
@@ -102,6 +101,8 @@ function MoreDropdown({
userId: string;
refetchSubscriptions: () => void;
}) {
+ const { showErrorToast } = useErrorToast(logger);
+
const deleteSubscription = useMutation({
mutationFn: () =>
getBackendServiceForClientside().deleteSubscription({
@@ -116,22 +117,13 @@ function MoreDropdown({
});
},
onError: (error) => {
- const errorId = uuidv4();
- logger.error(`Failed to delete subscription with id '${subscription.id}': ${getErrorLogMessage(error)}`, {
- errorId,
+ showErrorToast({
+ error,
+ logMessage: `Failed to delete subscription with id '${subscription.id}': ${getErrorLogMessage(error)}`,
+ errorToastMessages: [
+ `We could not delete your subscription "${subscription.name}". Please try again later.`,
+ ],
});
- toast.error(
- <>
-
- We could not delete your subscription "{subscription.name}". Please try again later.
-
-
- >,
- {
- position: 'bottom-left',
- autoClose: false,
- },
- );
},
});
diff --git a/website/src/components/views/analyzeSingleVariant/CollectionsList.tsx b/website/src/components/views/analyzeSingleVariant/CollectionsList.tsx
index 8c6048c6..20b67ff3 100644
--- a/website/src/components/views/analyzeSingleVariant/CollectionsList.tsx
+++ b/website/src/components/views/analyzeSingleVariant/CollectionsList.tsx
@@ -2,9 +2,11 @@ import { useQuery } from '@tanstack/react-query';
import { useMemo, useState } from 'react';
import { z } from 'zod';
+import { getClientLogger } from '../../../clientLogger.ts';
import type { OrganismsConfig } from '../../../config.ts';
import { type CovidVariantData } from '../../../views/covid.ts';
import { Routing } from '../../../views/routing.ts';
+import { useErrorToast } from '../../ErrorReportInstruction.tsx';
import { withQueryProvider } from '../../subscriptions/backendApi/withQueryProvider.tsx';
type CollectionVariant = {
@@ -98,14 +100,51 @@ const querySchema = z.object({
function CollectionVariantList({ collection, organismsConfig }: CollectionVariantListProps) {
const variants = collection.variants;
+ const selectVariant = useSelectVariant(organismsConfig, collection);
+
+ return (
+
+ {variants.map((variant, index) => (
+
+ ))}
+
+ );
+}
+
+const logger = getClientLogger('CollectionList');
+
+function useSelectVariant(organismsConfig: OrganismsConfig, collection: Collection) {
const routing = useMemo(() => new Routing(organismsConfig), [organismsConfig]);
- const selectVariant = (variant: CollectionVariant) => {
+ const { showErrorToast } = useErrorToast(logger);
+
+ return (variant: CollectionVariant) => {
const currentPageState = routing
.getOrganismView('covid.singleVariantView')
.pageStateHandler.parsePageStateFromUrl(new URL(window.location.href));
let newPageState: CovidVariantData;
- const query = querySchema.parse(JSON.parse(variant.query));
+
+ const queryParseResult = querySchema.safeParse(JSON.parse(variant.query));
+
+ if (!queryParseResult.success) {
+ showErrorToast({
+ error: queryParseResult.error,
+ logMessage: `Failed to parse query of variant ${variant.name} of collection ${collection.id}: ${queryParseResult.error.message}`,
+ errorToastMessages: [
+ `The variant filter of the collection variant "${variant.name}" seems to be invalid.`,
+ ],
+ });
+ return;
+ }
+
+ const query = queryParseResult.data;
+
if (query.variantQuery !== undefined) {
newPageState = {
...currentPageState,
@@ -135,18 +174,4 @@ function CollectionVariantList({ collection, organismsConfig }: CollectionVarian
}
window.location.href = routing.getOrganismView('covid.singleVariantView').pageStateHandler.toUrl(newPageState);
};
-
- return (
-
- {variants.map((variant, index) => (
-
- ))}
-
- );
}
diff --git a/website/src/styles/containers/Modal.tsx b/website/src/styles/containers/Modal.tsx
index 6b9b4c1d..e7b7cd30 100644
--- a/website/src/styles/containers/Modal.tsx
+++ b/website/src/styles/containers/Modal.tsx
@@ -6,7 +6,11 @@ export function useModalRef() {
return useRef
(null);
}
-type ModalProps =
+const modalSize = {
+ large: 'max-w-screen-lg',
+};
+
+type ModalProps = (
| {
/** set this when using from React and open it via `modalRef.current?.showModal()` */
modalRef: RefObject;
@@ -16,12 +20,15 @@ type ModalProps =
/** set this when using from Astro and open it via `onclick="id.showModal()"` */
id: string;
modalRef?: undefined;
- };
+ }
+) & {
+ size?: keyof typeof modalSize;
+};
-export const Modal: FC> = ({ children, modalRef, id }) => {
+export const Modal: FC> = ({ children, modalRef, id, size }) => {
return (