web/satellite/vuetify-poc: implement Delete Access dialog

This change implements the Delete Access dialog for deleting access
grants. It is triggered by clicking Delete in the actions menu of
access grant table rows.

Resolves #6300

Change-Id: I288f9a88c62e57390f039e41ca6770d2942a9058
This commit is contained in:
Jeremy Wharton 2023-09-20 00:52:11 -05:00 committed by Storj Robot
parent 22261146be
commit 471111122b
2 changed files with 166 additions and 1 deletions

View File

@ -42,13 +42,43 @@
{{ item.raw.createdAt.toLocaleString() }}
</span>
</template>
<template #item.actions="{ item }">
<v-btn
variant="outlined"
color="default"
size="small"
class="mr-1 text-caption"
density="comfortable"
icon
>
<v-icon icon="mdi-dots-horizontal" />
<v-menu activator="parent">
<v-list class="pa-2">
<v-list-item density="comfortable" link rounded="lg" @click="() => onDeleteClick(item.raw.name)">
<template #prepend>
<icon-trash bold />
</template>
<v-list-item-title class="pl-2 text-body-2 font-weight-medium">
Delete
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</template>
</v-data-table-server>
</v-card>
<delete-access-dialog
v-model="isDeleteAccessDialogShown"
:access-name="accessNameToDelete"
@deleted="() => onUpdatePage(FIRST_PAGE)"
/>
</template>
<script setup lang="ts">
import { ref, watch, onMounted, computed } from 'vue';
import { VCard, VTextField } from 'vuetify/components';
import { VBtn, VIcon, VMenu, VList, VListItem, VListItemTitle, VCard, VTextField } from 'vuetify/components';
import { VDataTableServer } from 'vuetify/labs/components';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
@ -59,6 +89,9 @@ import { useProjectsStore } from '@/store/modules/projectsStore';
import { DEFAULT_PAGE_LIMIT } from '@/types/pagination';
import { SortDirection, tableSizeOptions } from '@/types/common';
import DeleteAccessDialog from '@poc/components/dialogs/DeleteAccessDialog.vue';
import IconTrash from '@poc/components/icons/IconTrash.vue';
const agStore = useAccessGrantsStore();
const projectsStore = useProjectsStore();
const notify = useNotify();
@ -68,6 +101,8 @@ const areGrantsFetching = ref<boolean>(true);
const search = ref<string>('');
const searchTimer = ref<NodeJS.Timeout>();
const selected = ref([]);
const isDeleteAccessDialogShown = ref<boolean>(false);
const accessNameToDelete = ref<string>('');
const headers = [
{
@ -76,6 +111,7 @@ const headers = [
key: 'name',
},
{ title: 'Date Created', key: 'createdAt' },
{ title: '', key: 'actions', sortable: false, width: 0 },
];
/**
@ -132,6 +168,14 @@ function onUpdateSortBy(sortBy: {key: keyof AccessGrantsOrderBy, order: keyof So
fetch(FIRST_PAGE, cursor.value.limit);
}
/**
* Displays the Delete Access dialog.
*/
function onDeleteClick(accessName: string): void {
accessNameToDelete.value = accessName;
isDeleteAccessDialogShown.value = true;
}
/**
* Handles update table search.
*/

View File

@ -0,0 +1,121 @@
// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<v-dialog
v-model="model"
width="400px"
transition="fade-transition"
:persistent="isLoading"
>
<v-card rounded="xlg">
<v-card-item class="pl-7 py-4 pos-relative">
<template #prepend>
<v-sheet
class="bg-on-surface-variant d-flex justify-center align-center"
width="40"
height="40"
rounded="lg"
>
<icon-trash />
</v-sheet>
</template>
<v-card-title class="font-weight-bold">
Delete Access
</v-card-title>
<template #append>
<v-btn
icon="$close"
variant="text"
size="small"
color="default"
:disabled="isLoading"
@click="model = false"
/>
</template>
</v-card-item>
<v-divider />
<div class="pa-7">
The following access will be deleted. Linksharing URLs using this access will no longer work.
<br><br>
<span class="font-weight-bold">{{ accessName }}</span>
</div>
<v-divider />
<v-card-actions class="pa-7">
<v-row>
<v-col>
<v-btn variant="outlined" color="default" block :disabled="isLoading" @click="model = false">
Cancel
</v-btn>
</v-col>
<v-col>
<v-btn color="error" variant="flat" block :loading="isLoading" @click="onDeleteClick">
Delete
</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import {
VDialog,
VCard,
VCardItem,
VSheet,
VCardTitle,
VDivider,
VCardActions,
VRow,
VCol,
VBtn,
} from 'vuetify/components';
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { useLoading } from '@/composables/useLoading';
import { useNotify } from '@/utils/hooks';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import IconTrash from '@poc/components/icons/IconTrash.vue';
const agStore = useAccessGrantsStore();
const projectsStore = useProjectsStore();
const notify = useNotify();
const { isLoading, withLoading } = useLoading();
const props = defineProps<{
modelValue: boolean;
accessName: string;
}>();
const emit = defineEmits<{
'update:modelValue': [value: boolean],
'deleted': [];
}>();
const model = computed<boolean>({
get: () => props.modelValue,
set: value => emit('update:modelValue', value),
});
async function onDeleteClick(): Promise<void> {
await withLoading(async () => {
try {
await agStore.deleteAccessGrantByNameAndProjectID(props.accessName, projectsStore.state.selectedProject.id);
emit('deleted');
model.value = false;
} catch (error) {
error.message = `Error deleting access grant. ${error.message}`;
notify.notifyError(error, AnalyticsErrorEventSource.CONFIRM_DELETE_AG_MODAL);
}
});
}
</script>