Skip to content

Commit

Permalink
Add dialog to manage uploads for embargoed dandisets
Browse files Browse the repository at this point in the history
  • Loading branch information
jjnesbitt committed Nov 21, 2024
1 parent 4afd687 commit e2f5237
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 14 deletions.
8 changes: 8 additions & 0 deletions web/src/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
AssetPath,
Zarr,
DandisetSearchResult,
IncompleteUpload,
} from '@/types';
import type {
Dandiset as DandisetMetadata,
Expand Down Expand Up @@ -106,6 +107,13 @@ const dandiRest = {
throw e;
}
},
async uploads(identifier: string): Promise<IncompleteUpload[]> {
const res = await client.get(`dandisets/${identifier}/uploads/`);
return res.data;
},
async clearUploads(identifier: string) {
await client.delete(`dandisets/${identifier}/uploads/`);
},
async assets(
identifier: string,
version: string,
Expand Down
8 changes: 8 additions & 0 deletions web/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ export interface AssetPath {
aggregate_size: number;
asset: AssetFile | null;
}

export interface IncompleteUpload {
created: string;
blob: string;
upload_id: string;
etag: string;
size: number;
}
119 changes: 105 additions & 14 deletions web/src/views/DandisetLandingView/DandisetUnembargo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,65 @@
outlined
class="mt-4 px-3"
>
<v-dialog v-model="showUploadManagementDialog" max-width="60vw">
<v-card class="pb-3">
<v-card-title class="text-h5 font-weight-light">
This dandiset has active uploads
</v-card-title>
<v-divider class="my-3" />
<v-card-text>
This dandiset has <strong>{{ incompleteUploads.length }}</strong> active uploads. Unembargo may not proceed until these are addressed. You may delete these uploads using the "Clear Uploads" button below.
</v-card-text>

<v-data-table
height="40vh"
:items-per-page="-1"
:items="incompleteUploads"
:headers="uploadHeaders"
hide-default-footer
>
<template #item.created="{ item }">
{{ formatDate(item.created, 'LLL') }}
</template>
<template #item.size="{ item }">
{{ filesize(item.size, { round: 1, base: 10, standard: 'iec' }) }}
</template>
</v-data-table>

<v-card-actions>
<v-spacer />
<v-btn
depressed
@click="showUploadManagementDialog = false"
>
Close
</v-btn>

<v-menu offset-y bottom>
<template #activator="{ on, attrs }">
<v-btn
class="ml-2"
depressed
v-on="on"
v-bind="attrs"
primary
>
Clear Uploads
</v-btn>
</template>

<v-card width="15vw">
<v-card-text>
Delete all uploads? Once deleted, any partially uploaded data will be lost.
</v-card-text>
<v-card-actions>
<v-btn @click="clearUploads" color="error" depressed>Delete</v-btn>
</v-card-actions>
</v-card>
</v-menu>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog
v-if="showWarningDialog"
v-model="showWarningDialog"
Expand Down Expand Up @@ -63,10 +122,7 @@
class="mb-4"
no-gutters
>
<v-tooltip
left
:disabled="!unembargoDisabled"
>
<v-tooltip left :disabled="!unembargo_in_progress">
<template #activator="{ on }">
<div
class="px-1 pt-3"
Expand All @@ -75,19 +131,19 @@
>
<v-btn
block
color="info"
:color="unembargoDisabled ? 'grey lighten-2': 'info'"
depressed
:disabled="unembargoDisabled"
@click="unembargo()"
:disabled="unembargo_in_progress"
@click="unembargoDisabled ? showUploadManagementDialog = true : unembargo()"
>
{{ unembargo_in_progress ? 'Unembargoing' : 'Unembargo' }}
<v-spacer />
<v-icon>mdi-lock-open</v-icon>
<v-icon v-if="unembargoDisabled">mdi-alert</v-icon>
<v-icon v-else>mdi-lock-open</v-icon>
</v-btn>
</div>
</template>
<span v-if="unembargo_in_progress">This dandiset is being unembargoed, please wait.</span>
<span v-else-if="currentDandiset.active_uploads">This dandiset has active uploads. Please complete or clear these uploads before proceeding.</span>
<span>This dandiset is being unembargoed, please wait.</span>
</v-tooltip>
</v-row>
<v-row>
Expand Down Expand Up @@ -119,19 +175,54 @@ import { computed, ref } from 'vue';
import moment from 'moment';
import { dandiRest } from '@/rest';
import { useDandisetStore } from '@/stores/dandiset';
import type { IncompleteUpload } from '@/types';
import filesize from 'filesize';
function formatDate(date: string): string {
return moment(date).format('ll');
function formatDate(date: string, format: string = 'll'): string {
return moment(date).format(format);
}
const store = useDandisetStore();
const uploadHeaders = [
{
text: 'Started at',
value: 'created',
},
{
text: 'Size',
value: 'size',
},
{
text: 'E-Tag',
value: 'etag',
},
];
const store = useDandisetStore();
const currentDandiset = computed(() => store.dandiset);
const unembargo_in_progress = computed(() => currentDandiset.value?.dandiset.embargo_status === 'UNEMBARGOING');
const unembargoDisabled = computed(() => !!(unembargo_in_progress.value || currentDandiset.value === null || currentDandiset.value.active_uploads));
const showWarningDialog = ref(false);
const confirmationPhrase = ref('');
// Upload management
const showUploadManagementDialog = ref(false);
const incompleteUploads = ref<IncompleteUpload[]>([]);
const unembargoDisabled = computed(() => !!(unembargo_in_progress.value || currentDandiset.value === null || currentDandiset.value.active_uploads));
if (unembargoDisabled.value) {
fetchIncompleteUploads();
}
async function fetchIncompleteUploads() {
incompleteUploads.value = await dandiRest.uploads(currentDandiset.value!.dandiset.identifier);
}
async function clearUploads() {
const identifier = currentDandiset.value!.dandiset.identifier;
await dandiRest.clearUploads(identifier);
showUploadManagementDialog.value = false;
store.fetchDandiset({ identifier, version: 'draft' });
}
async function unembargo() {
if (currentDandiset.value) {
// Display the warning dialog before releasing
Expand Down

0 comments on commit e2f5237

Please sign in to comment.