Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ALS-7605] Add a confirm modal to downloads #271

Merged
merged 5 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/lib/assets/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a class=\"anchor\" href=\"https://hms-dbmi.atlassian.net/servicedesk/customer/portal/5\" target=\"_blank\" class=\"underline\">Avillach Lab Software Requests</a>. 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 <a class=\"anchor\" href=\"https://hms-dbmi.atlassian.net/servicedesk/customer/portal/5\" target=\"_blank\" class=\"underline\">Avillach Lab Software Requests</a>. 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…",
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
44 changes: 39 additions & 5 deletions src/lib/components/explorer/export/ExportStepper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>;
let preparePromise: Promise<void>;
let datasetNameInput: string = '';
Expand All @@ -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<void> {
try {
Expand Down Expand Up @@ -333,7 +363,10 @@
></CodeBlock>
{:else if tabSet === 2}
<div>
<button class="btn variant-filled-primary" on:click={() => download()}
<button
class="btn variant-filled-primary"
on:click={() =>
features.confirmDownload ? openConfirmationModal() : download()}
><i class="fa-solid fa-download mr-1"></i>Download as CSV</button
>
</div>
Expand Down Expand Up @@ -402,7 +435,8 @@
<div>
<button
class="flex-initial w-64 btn variant-filled-primary"
on:click={() => download()}
on:click={() =>
features.confirmDownload ? openConfirmationModal() : download()}
><i class="fa-solid fa-download"></i>Download as PFB</button
>
</div>
Expand Down
44 changes: 44 additions & 0 deletions src/lib/components/modals/Confirmation.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script lang="ts">
import { onMount } from 'svelte';
import { getModalStore } from '@skeletonlabs/skeleton';

const modalStore = getModalStore();

export let message: string;
export let onCancel: () => void;
JamesPeck marked this conversation as resolved.
Show resolved Hide resolved
export let onConfirm: () => void;
export let cancelText: string = 'Cancel';
export let confirmText: string = 'Accept';

onMount(() => {
if ($modalStore[0]?.meta.onCancel) {
onCancel = $modalStore[0]?.meta.onCancel;
}
if ($modalStore[0]?.meta.onConfirm) {
onConfirm = $modalStore[0]?.meta.onConfirm;
}
if ($modalStore[0]?.meta.confirmText) {
confirmText = $modalStore[0]?.meta.confirmText;
}
if ($modalStore[0]?.meta.cancelText) {
cancelText = $modalStore[0]?.meta.cancelText;
}
if ($modalStore[0]?.meta.message) {
message = $modalStore[0]?.meta.message;
}
});
</script>

<div class="flex flex-col gap-4">
<p>{message}</p>
<div class="flex justify-end gap-4">
<button
class="btn variant-ghost-surface hover:variant-filled-surface mt-6"
on:click={() => onCancel()}>{cancelText}</button
>
<button
class="btn variant-filled hover:variant-filled-primary mt-6"
on:click={() => onConfirm()}>{confirmText}</button
>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -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';
</script>

<section id="terms-of-service">
Expand Down
2 changes: 2 additions & 0 deletions src/lib/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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 = {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface ExplorePageConfig {
totalPatientsText: string;
queryErrorText: string;
filterErrorText: string;
confirmDownloadTitle: string;
confirmDownloadMessage: string;
}

export interface LandingConfig {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/(picsure)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down