From 1cc59aeb343ec861e41cd4797ca0baa6a34eff11 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 23 Oct 2024 15:50:51 -0400 Subject: [PATCH] [ALS-7605] Add a confirm modal to downloads (#271) --- src/lib/assets/configuration.json | 4 +- src/lib/components/Footer.svelte | 2 +- .../explorer/export/ExportStepper.svelte | 44 ++++++++++++++++--- src/lib/components/modals/Confirmation.svelte | 44 +++++++++++++++++++ .../{ => modals}/FilterWarning.svelte | 0 .../{ => modals}/ModalWrapper.svelte | 0 .../components/{ => modals}/TermsModal.svelte | 2 +- src/lib/configuration.ts | 2 + src/lib/types.ts | 2 + src/routes/(picsure)/+layout.svelte | 4 +- 10 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 src/lib/components/modals/Confirmation.svelte rename src/lib/components/{ => modals}/FilterWarning.svelte (100%) rename src/lib/components/{ => modals}/ModalWrapper.svelte (100%) rename src/lib/components/{ => modals}/TermsModal.svelte (92%) diff --git a/src/lib/assets/configuration.json b/src/lib/assets/configuration.json index cd6e4d97..bbb8871a 100644 --- a/src/lib/assets/configuration.json +++ b/src/lib/assets/configuration.json @@ -73,7 +73,9 @@ "tourSearchIntro": "PIC-SURE Search allows you to search for variable level data.", "totalPatientsText": "Filtered Participants", "queryErrorText": "There was an error with your query. If this persists, please contact you PIC-SURE admin.", - "filterErrorText": "There was an error when adding the filter to the query. Please remove your most recent filter and try again. If this error persists, please contact us by filling out the form at Avillach Lab Software Requests. We will respond to your request as soon as we can." + "filterErrorText": "There was an error when adding the filter to the query. Please remove your most recent filter and try again. If this error persists, please contact us by filling out the form at Avillach Lab Software Requests. We will respond to your request as soon as we can.", + "confirmDownloadTitle": "Are you sure you want to download data?", + "confirmDownloadMessage": "This action will download the data to your local machine. Are you sure you want to proceed?" }, "landing": { "searchPlaceholder": "Search terms or variables of interest…", diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index 04557047..fc7dcf2c 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -6,7 +6,7 @@ import { branding } from '$lib/configuration'; import { user } from '$lib/stores/User'; - import TermsModal from '$lib/components/TermsModal.svelte'; + import TermsModal from '$lib/components/modals/TermsModal.svelte'; export let showSitemap: boolean = branding?.footer?.showSitemap || false; $: hideSitemap = diff --git a/src/lib/components/explorer/export/ExportStepper.svelte b/src/lib/components/explorer/export/ExportStepper.svelte index b51f7bb8..4fe8d42e 100644 --- a/src/lib/components/explorer/export/ExportStepper.svelte +++ b/src/lib/components/explorer/export/ExportStepper.svelte @@ -21,10 +21,14 @@ import CardButton from '$lib/components/buttons/CardButton.svelte'; import type { ExpectedResultType } from '$lib/models/query/Query.ts'; import codeBlocks from '$lib/assets/codeBlocks.json'; - + import { getModalStore, type ModalSettings } from '@skeletonlabs/skeleton'; + import Confirmation from '$lib/components/modals/Confirmation.svelte'; + import { branding, features, settings } from '$lib/configuration'; export let query: QueryRequestInterface; export let showTreeStep = false; export let rows: ExportRowInterface[] = []; + + const modalStore = getModalStore(); let statusPromise: Promise; let preparePromise: Promise; let datasetNameInput: string = ''; @@ -40,8 +44,34 @@ { dataElement: 'type', label: 'Type', sort: true }, ]; - // todo: make configurable - const MAX_DATA_POINTS_FOR_EXPORT = 1000000; + const MAX_DATA_POINTS_FOR_EXPORT = settings.maxDataPointsForExport || 1000000; + + function openConfirmationModal() { + const onConfirm = async () => { + await download(); + modalStore.close(); + }; + const onCancel = () => { + modalStore.close(); + }; + const modal: ModalSettings = { + type: 'component', + title: branding.explorePage.confirmDownloadTitle || 'Are you sure you want to download data?', + component: 'modalWrapper', + modalClasses: 'bg-surface-100-800-token p-4 block', + meta: { + component: Confirmation, + message: branding.explorePage.confirmDownloadMessage, + onConfirm, + onCancel, + confirmText: 'Download', + }, + response: (r: string) => { + console.log(r); + }, + }; + modalStore.trigger(modal); + } async function download(): Promise { try { @@ -333,7 +363,10 @@ > {:else if tabSet === 2}
-
@@ -402,7 +435,8 @@
diff --git a/src/lib/components/modals/Confirmation.svelte b/src/lib/components/modals/Confirmation.svelte new file mode 100644 index 00000000..dd368382 --- /dev/null +++ b/src/lib/components/modals/Confirmation.svelte @@ -0,0 +1,44 @@ + + +
+

{message}

+
+ + +
+
diff --git a/src/lib/components/FilterWarning.svelte b/src/lib/components/modals/FilterWarning.svelte similarity index 100% rename from src/lib/components/FilterWarning.svelte rename to src/lib/components/modals/FilterWarning.svelte diff --git a/src/lib/components/ModalWrapper.svelte b/src/lib/components/modals/ModalWrapper.svelte similarity index 100% rename from src/lib/components/ModalWrapper.svelte rename to src/lib/components/modals/ModalWrapper.svelte diff --git a/src/lib/components/TermsModal.svelte b/src/lib/components/modals/TermsModal.svelte similarity index 92% rename from src/lib/components/TermsModal.svelte rename to src/lib/components/modals/TermsModal.svelte index e2af3b2b..e930f9bf 100644 --- a/src/lib/components/TermsModal.svelte +++ b/src/lib/components/modals/TermsModal.svelte @@ -4,7 +4,7 @@ // Ideally, this should be a value from the database that has timestamps, author, etc. // For now, the easiest place to find and update the html used here is in the src folder. - import Terms from '../../terms.svelte'; + import Terms from '../../../terms.svelte';
diff --git a/src/lib/configuration.ts b/src/lib/configuration.ts index 8415a97b..9c4b20b5 100644 --- a/src/lib/configuration.ts +++ b/src/lib/configuration.ts @@ -135,6 +135,7 @@ export const features: Indexable = { distributionExplorer: import.meta.env?.VITE_DIST_EXPLORER === 'true', }, dashboard: import.meta.env?.VITE_DASHBOARD === 'true', + confirmDownload: import.meta.env?.VITE_CONFIRM_DOWNLOAD === 'true', }; export const settings: Indexable = { @@ -152,6 +153,7 @@ export const settings: Indexable = { analytics: import.meta.env?.VITE_GOOGLE_ANALYTICS_ID || '', tagManager: import.meta.env?.VITE_GOOGLE_TAG_MANAGER_ID || '', }, + maxDataPointsForExport: parseInt(import.meta.env?.VITE_MAX_DATA_POINTS_FOR_EXPORT || 1000000), }; export const resources = { diff --git a/src/lib/types.ts b/src/lib/types.ts index dcb1fc48..bc517924 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -45,6 +45,8 @@ export interface ExplorePageConfig { totalPatientsText: string; queryErrorText: string; filterErrorText: string; + confirmDownloadTitle: string; + confirmDownloadMessage: string; } export interface LandingConfig { diff --git a/src/routes/(picsure)/+layout.svelte b/src/routes/(picsure)/+layout.svelte index c20ec63d..6d938ef3 100644 --- a/src/routes/(picsure)/+layout.svelte +++ b/src/routes/(picsure)/+layout.svelte @@ -7,11 +7,11 @@ import { page } from '$app/stores'; import ExportStepper from '$lib/components/explorer/export/ExportStepper.svelte'; import Footer from '$lib/components/Footer.svelte'; - import ModalWrapper from '$lib/components/ModalWrapper.svelte'; + import ModalWrapper from '$lib/components/modals/ModalWrapper.svelte'; import { getModalStore } from '@skeletonlabs/skeleton'; import { beforeNavigate } from '$app/navigation'; import { hasInvalidFilter, hasGenomicFilter, hasUnallowedFilter } from '$lib/stores/Filter.ts'; - import FilterWarning from '$lib/components/FilterWarning.svelte'; + import FilterWarning from '$lib/components/modals/FilterWarning.svelte'; const modalStore = getModalStore();