Skip to content

Commit

Permalink
[ALS-6928] Add details drawer to dashboard (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesPeck authored Nov 20, 2024
1 parent d47997c commit 27cedd0
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 16 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ VITE_USE_QUERY_TEMPLATE=true
VITE_API=true
VITE_DISCOVER=true
VITE_DASHBOARD=true
VITE_DASHBOARD_DRAWER=true
VITE_ENABLE_SAMPLE_ID_CHECKBOX=true

# VITE_AUTH_PROVIDER_MODULE is the prefix for any authorization providers you want to use.
Expand Down
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ VITE_DISCOVER=true
VITE_DASHBOARD=true
VITE_ENABLE_SNP_QUERY=true
VITE_ENABLE_GENE_QUERY=true
VITE_DASHBOARD_DRAWER=true
VITE_ENABLE_SAMPLE_ID_CHECKBOX=true

# VITE_AUTH_PROVIDER_MODULE is the prefix for any authorization providers you want to use.
Expand Down
76 changes: 76 additions & 0 deletions src/lib/components/datatable/DashboardDrawer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script lang="ts">
import { getDrawerStore } from '@skeletonlabs/skeleton';
import { getDatasetDetails } from '$lib/services/dictionary';
import type { DashboardRow } from '$lib/stores/Dashboard';
import { ProgressRadial } from '@skeletonlabs/skeleton';
import ErrorAlert from '$lib/components/ErrorAlert.svelte';
const drawerStore = getDrawerStore();
const datasetId = (($drawerStore.meta.row as DashboardRow)?.dataset_id as string) || '';
const title = (($drawerStore.meta.row as DashboardRow)?.name as string) || '';
const link = (($drawerStore.meta.row as DashboardRow)?.additional_info_link as string) || '';
async function getDataset() {
const details = await getDatasetDetails(datasetId);
if (!details || Object.keys(details).length === 0) throw new Error('No details found');
if (details.datasetId) {
delete details.datasetId;
}
if (details.studyFullname) {
delete details.studyFullname;
}
return details;
}
</script>

{#if title}
<h2 data-testid="drawer-title" class="text-2xl font-bold ml-4">{title}</h2>
{/if}
<hr class="m-4 border-t-2 border-gray-200" />
{#await getDataset()}
<div class="flex justify-center items-center h-full">
<ProgressRadial />
</div>
{:then details}
<ul data-testid="drawer-details" class="m-4 p-4">
{#each Object.entries(details) as [key, value]}
{#if value}
<li class="m-2">
<strong class="capitalize"
>{key
.replace(/([A-Z])/g, ' $1')
.toLowerCase()
.trim()}</strong
>:
{#if Array.isArray(value)}
<ul class="list-disc">
{#each value as item}
{#if item}
<li class="ml-8">{item}</li>
{/if}
{/each}
</ul>
{:else}
{value}
{/if}
</li>
{/if}
{/each}
</ul>
{#if link}
<div class="flex justify-center items-center mb-4">
<a
href={link || '#'}
on:click|stopPropagation
class="btn variant-ghost-primary hover:variant-filled-primary"
target="_blank">More Info</a
>
</div>
{/if}
{:catch}
<div class="flex justify-center items-center">
<ErrorAlert title="An Error Occured">
<p>We're having trouble fetching the dataset details right now. Please try again later.</p>
</ErrorAlert>
</div>
{/await}
10 changes: 8 additions & 2 deletions src/lib/components/datatable/DashboardLink.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
{#if consentGranted}
<i class="fa-regular fa-circle-check text-3xl text-success-500"></i>
{:else}
<a href={link} class="btn variant-ghost-primary hover:variant-filled-primary" target="_blank"
>More Info</a
<a
href={link || '#'}
title={link ? 'More Info' : 'Link not available'}
on:click|stopPropagation={(e) => !link && e.preventDefault()}
class="btn variant-ghost-primary hover:variant-filled-primary{!link
? ' opacity-50 cursor-not-allowed'
: ''}"
target="_blank">More Info</a
>
{/if}
12 changes: 10 additions & 2 deletions src/lib/components/datatable/RemoteTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
export let columns: Column[] = [];
export let cellOverides: Indexable = {};
export let rowClickHandler: (row: Indexable) => void = () => {};
export let isClickable: boolean = false;
let rows = handler.getRows();
onMount(() => {
Expand Down Expand Up @@ -100,7 +100,15 @@
</tr>
{:else if $rows.length > 0}
{#each $rows as row, i}
<ExpandableRow {tableName} {cellOverides} {columns} index={i} {row} {rowClickHandler} />
<ExpandableRow
{tableName}
{cellOverides}
{columns}
index={i}
{row}
{rowClickHandler}
{isClickable}
/>
{/each}
{:else}
<tr><td colspan={columns.length}>No entries found.</td></tr>
Expand Down
10 changes: 7 additions & 3 deletions src/lib/components/datatable/Row.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@
export let index: number = -2;
export let row: Indexable = {};
export let tableName: string = '';
export let isClickable: boolean = false;
export let rowClickHandler: (row: Indexable) => void = () => {};
function onClick(row: Indexable) {
setActiveRow({ row: row.conceptPath, table: tableName });
setActiveRow({ row: row.conceptPath || row.dataset_id, table: tableName });
rowClickHandler(row);
}
$: active = $activeTable === tableName && $activeRow === row?.conceptPath;
$: active =
$activeTable === tableName &&
($activeRow === row?.conceptPath || $activeRow === row.dataset_id);
</script>

<tr
id="row-{index.toString()}"
on:click|stopPropagation={() => onClick(row)}
class="cursor-pointer"
class={isClickable ? 'cursor-pointer' : ''}
tabindex={isClickable ? 0 : -1}
>
{#each columns as column, colIndex}
<td id="row-{index.toString()}-col-{colIndex.toString()}">
Expand Down
12 changes: 10 additions & 2 deletions src/lib/components/datatable/Table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
export let stickyHeader = false;
export let showPagination = true;
export let rowClickHandler: (row: Indexable) => void = () => {};
export let isClickable: boolean = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export let data: any = []; //TODO: Fix this type
Expand Down Expand Up @@ -83,7 +83,15 @@
<tbody>
{#if $rows.length > 0}
{#each $rows as row, i}
<ExpandableRow {tableName} {cellOverides} {columns} index={i} {row} {rowClickHandler} />
<ExpandableRow
{tableName}
{cellOverides}
{columns}
index={i}
{row}
{rowClickHandler}
{isClickable}
/>
{/each}
{:else}
<tr><td colspan={columns.length}>No entries found.</td></tr>
Expand Down
1 change: 1 addition & 0 deletions src/lib/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export const features: Indexable = {
distributionExplorer: import.meta.env?.VITE_DIST_EXPLORER === 'true',
},
dashboard: import.meta.env?.VITE_DASHBOARD === 'true',
dashboardDrawer: import.meta.env?.VITE_DASHBOARD_DRAWER === 'true',
confirmDownload: import.meta.env?.VITE_CONFIRM_DOWNLOAD === 'true',
};

Expand Down
5 changes: 5 additions & 0 deletions src/lib/services/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { user } from '$lib/stores/User';
const dictionaryUrl = 'picsure/proxy/dictionary-api/';
const searchUrl = 'picsure/proxy/dictionary-api/concepts';
const conceptDetailUrl = 'picsure/proxy/dictionary-api/concepts/detail/';
const datasetDetailUrl = 'picsure/proxy/dictionary-api/dashboard-drawer/';

export type FacetSkeleton = {
[facetCategory: string]: string[];
Expand Down Expand Up @@ -146,3 +147,7 @@ export async function getStudiesCount(isOpenAccess = false) {
const facetsForUser = facetCat.facets.filter((facet) => facet.count > 0);
return facetsForUser.length;
}

export async function getDatasetDetails(datasetId: string) {
return api.get(`${datasetDetailUrl}${datasetId}`);
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
cellOverides={roleTable.overrides}
defaultRowsPerPage={10}
rowClickHandler={roleRowCLick}
isClickable={true}
/>
</div>
<div id="authorization-privilege-table" class="mb-10">
Expand All @@ -106,6 +107,7 @@
cellOverides={privilegesTable.overrides}
defaultRowsPerPage={10}
rowClickHandler={privilegeRowClick}
isClickable={true}
/>
</div>
{:catch}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
defaultRowsPerPage={10}
title={connection.label}
{rowClickHandler}
isClickable={true}
/>
</div>
{/each}
Expand Down
15 changes: 14 additions & 1 deletion src/routes/(picsure)/(public)/dashboard/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { ProgressBar } from '@skeletonlabs/skeleton';
import { branding } from '$lib/configuration';
import { branding, features } from '$lib/configuration';
import Content from '$lib/components/Content.svelte';
import Datatable from '$lib/components/datatable/Table.svelte';
import DashboardLink from '$lib/components/datatable/DashboardLink.svelte';
Expand All @@ -14,6 +14,10 @@
import type { Column } from '$lib/models/Tables';
import type { DashboardRow } from '$lib/stores/Dashboard';
import { getDrawerStore } from '@skeletonlabs/skeleton';
const drawerStore = getDrawerStore();
const tableName = 'ExplorerTable';
let unsubColumns: Unsubscriber;
Expand All @@ -40,6 +44,13 @@
unsubColumns && unsubColumns();
unsubRows && unsubRows();
});
function rowClickHandler(row: DashboardRow) {
drawerStore.open({
id: 'dashboard-drawer',
meta: { row },
});
}
</script>

<svelte:head>
Expand All @@ -59,6 +70,8 @@
search={false}
showPagination={false}
stickyHeader={true}
rowClickHandler={features.dashboardDrawer ? rowClickHandler : undefined}
isClickable={features.dashboardDrawer}
/>
{/await}
</section>
Expand Down
18 changes: 16 additions & 2 deletions src/routes/(picsure)/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<script lang="ts">
import { AppShell, Modal, Toast, storePopup, type ModalComponent } from '@skeletonlabs/skeleton';
import {
AppShell,
Modal,
Toast,
Drawer,
storePopup,
type ModalComponent,
} from '@skeletonlabs/skeleton';
import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
import Navigation from '$lib/components/Navigation.svelte';
import { onMount } from 'svelte';
Expand All @@ -8,12 +15,14 @@
import ExportStepper from '$lib/components/explorer/export/ExportStepper.svelte';
import Footer from '$lib/components/Footer.svelte';
import ModalWrapper from '$lib/components/modals/ModalWrapper.svelte';
import { getModalStore } from '@skeletonlabs/skeleton';
import { getModalStore, getDrawerStore } from '@skeletonlabs/skeleton';
import { beforeNavigate } from '$app/navigation';
import { hasInvalidFilter, hasGenomicFilter, hasUnallowedFilter } from '$lib/stores/Filter.ts';
import DashboardDrawer from '$lib/components/datatable/DashboardDrawer.svelte';
import FilterWarning from '$lib/components/modals/FilterWarning.svelte';
const modalStore = getModalStore();
const drawerStore = getDrawerStore();
// Highlight.js
import hljs from 'highlight.js/lib/core';
Expand Down Expand Up @@ -68,6 +77,11 @@

<Toast position="t" />
<Modal {...modalProps} />
<Drawer position="right" width="w-1/2" rounded="rounded-none">
{#if $drawerStore.id === 'dashboard-drawer'}
<DashboardDrawer />
{/if}
</Drawer>
<AppShell>
<svelte:fragment slot="header">
<Navigation />
Expand Down
20 changes: 18 additions & 2 deletions tests/mock-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ export const mockDashboard: DashboardResp = {
{ label: 'Link', dataElement: 'additional_info_link' },
],
rows: [
{ name: 'A', additional_info_link: 'foo.invalid' },
{ name: 'B', additional_info_link: 'bar.invalid' },
{
name: 'A',
description: 'This is a description 1',
additional_info_link: 'foo.invalid',
dataset_id: '1',
},
{
name: 'B',
description: 'This is a description 2',
additional_info_link: 'bar.invalid',
dataset_id: '2',
},
{
name: 'C',
description: 'This is a description 3',
additional_info_link: null,
dataset_id: '3',
},
],
};

Expand Down
Loading

0 comments on commit 27cedd0

Please sign in to comment.