web/satellite: wire up vuetify access page to backend
Added logic to list, sort, search and paginate access grants table for Vuetify POC Change-Id: I215a9ad4f894b6ac985cb6a3059fdcf007e3d914
This commit is contained in:
parent
28711e30ad
commit
5db0fd8846
@ -244,7 +244,7 @@ async function onPageClick(index: number, limit: number): Promise<void> {
|
||||
try {
|
||||
await agStore.getAccessGrants(index, projectsStore.state.selectedProject.id, limit);
|
||||
} catch (error) {
|
||||
await notify.error(`Unable to fetch Access Grants. ${error.message}`, AnalyticsErrorEventSource.ACCESS_GRANTS_PAGE);
|
||||
notify.error(`Unable to fetch Access Grants. ${error.message}`, AnalyticsErrorEventSource.ACCESS_GRANTS_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ onMounted(async () => {
|
||||
await agStore.getAccessGrants(FIRST_PAGE, projectsStore.state.selectedProject.id);
|
||||
areGrantsFetching.value = false;
|
||||
} catch (error) {
|
||||
await notify.error(`Unable to fetch Access Grants. ${error.message}`, AnalyticsErrorEventSource.ACCESS_GRANTS_PAGE);
|
||||
notify.error(`Unable to fetch Access Grants. ${error.message}`, AnalyticsErrorEventSource.ACCESS_GRANTS_PAGE);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -65,6 +65,8 @@ export interface AccessGrantsApi {
|
||||
export enum AccessGrantsOrderBy {
|
||||
NAME = 1,
|
||||
CREATED_AT,
|
||||
name = 1,
|
||||
createdAt = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,8 @@
|
||||
export enum SortDirection {
|
||||
ASCENDING = 1,
|
||||
DESCENDING,
|
||||
asc = 1,
|
||||
desc = 2,
|
||||
}
|
||||
|
||||
export enum OnboardingOS {
|
||||
@ -40,3 +42,16 @@ export enum PricingPlanType {
|
||||
export type UUID = string
|
||||
export type MemorySize = string
|
||||
export type Time = string
|
||||
|
||||
export function tableSizeOptions(itemCount: number): {title: string, value: number}[] {
|
||||
const opts = [
|
||||
{ title: '10', value: 10 },
|
||||
{ title: '25', value: 25 },
|
||||
{ title: '50', value: 50 },
|
||||
{ title: '100', value: 100 },
|
||||
];
|
||||
if (itemCount < 1000) {
|
||||
return [{ title: 'All', value: itemCount }, ...opts];
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
@ -11,85 +11,134 @@
|
||||
hide-details
|
||||
/>
|
||||
|
||||
<v-data-table
|
||||
<v-data-table-server
|
||||
v-model="selected"
|
||||
:sort-by="sortBy"
|
||||
:headers="headers"
|
||||
:items="accesses"
|
||||
:search="search"
|
||||
:items="page.accessGrants"
|
||||
:loading="areGrantsFetching"
|
||||
:items-length="page.totalCount"
|
||||
:items-per-page-options="tableSizeOptions(page.totalCount)"
|
||||
item-value="name"
|
||||
select-strategy="all"
|
||||
class="elevation-1"
|
||||
show-select
|
||||
hover
|
||||
@update:itemsPerPage="onUpdateLimit"
|
||||
@update:page="onUpdatePage"
|
||||
@update:sortBy="onUpdateSortBy"
|
||||
>
|
||||
<template #item.name="{ item }">
|
||||
<span class="font-weight-bold">
|
||||
{{ item.raw.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template #item.status="{ item }">
|
||||
<v-chip :color="item.raw.status == 'Active' ? 'success' : 'warning'" variant="tonal" size="small" rounded="xl" class="font-weight-bold">
|
||||
{{ item.raw.status }}
|
||||
</v-chip>
|
||||
<template #item.createdAt="{ item }">
|
||||
<span>
|
||||
{{ item.raw.createdAt.toLocaleString() }}
|
||||
</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-data-table-server>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { VCard, VTextField, VChip } from 'vuetify/components';
|
||||
import { VDataTable } from 'vuetify/labs/components';
|
||||
import { ref, watch, onMounted, computed } from 'vue';
|
||||
import { VCard, VTextField } from 'vuetify/components';
|
||||
import { VDataTableServer } from 'vuetify/labs/components';
|
||||
|
||||
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
||||
import { AccessGrantCursor, AccessGrantsOrderBy, AccessGrantsPage } from '@/types/accessGrants';
|
||||
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
|
||||
import { useNotify } from '@/utils/hooks';
|
||||
import { useProjectsStore } from '@/store/modules/projectsStore';
|
||||
import { DEFAULT_PAGE_LIMIT } from '@/types/pagination';
|
||||
import { SortDirection, tableSizeOptions } from '@/types/common';
|
||||
|
||||
const agStore = useAccessGrantsStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
const notify = useNotify();
|
||||
|
||||
const FIRST_PAGE = 1;
|
||||
const areGrantsFetching = ref<boolean>(true);
|
||||
const search = ref<string>('');
|
||||
const searchTimer = ref<NodeJS.Timeout>();
|
||||
const selected = ref([]);
|
||||
|
||||
const sortBy = [{ key: 'date', order: 'asc' }];
|
||||
const headers = [
|
||||
{
|
||||
title: 'Name',
|
||||
align: 'start',
|
||||
key: 'name',
|
||||
},
|
||||
{ title: 'Type', key: 'type' },
|
||||
{ title: 'Status', key: 'status' },
|
||||
{ title: 'Permissions', key: 'permissions' },
|
||||
{ title: 'Date Created', key: 'date' },
|
||||
];
|
||||
const accesses = [
|
||||
{
|
||||
name: 'Backup',
|
||||
date: '02 Mar 2023',
|
||||
type: 'Access Grant',
|
||||
permissions: 'All',
|
||||
status: 'Active',
|
||||
},
|
||||
{
|
||||
name: 'S3 Test',
|
||||
date: '03 Mar 2023',
|
||||
type: 'S3 Credentials',
|
||||
permissions: 'Read, Write',
|
||||
status: 'Expired',
|
||||
},
|
||||
{
|
||||
name: 'CLI Demo',
|
||||
date: '04 Mar 2023',
|
||||
type: 'CLI Access',
|
||||
permissions: 'Read, Write, List',
|
||||
status: 'Active',
|
||||
},
|
||||
{
|
||||
name: 'Sharing',
|
||||
date: '08 Mar 2023',
|
||||
type: 'Access Grant',
|
||||
permissions: 'Read, Delete',
|
||||
status: 'Active',
|
||||
},
|
||||
{
|
||||
name: 'Sync Int',
|
||||
date: '12 Mar 2023',
|
||||
type: 'S3 Credentials',
|
||||
permissions: 'All',
|
||||
status: 'Expired',
|
||||
},
|
||||
{ title: 'Date Created', key: 'createdAt' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns access grants cursor from store.
|
||||
*/
|
||||
const cursor = computed((): AccessGrantCursor => {
|
||||
return agStore.state.cursor;
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns access grants page from store.
|
||||
*/
|
||||
const page = computed((): AccessGrantsPage => {
|
||||
return agStore.state.page;
|
||||
});
|
||||
|
||||
/**
|
||||
* Fetches Access records depending on page and limit.
|
||||
*/
|
||||
async function fetch(page = FIRST_PAGE, limit = DEFAULT_PAGE_LIMIT): Promise<void> {
|
||||
try {
|
||||
await agStore.getAccessGrants(page, projectsStore.state.selectedProject.id, limit);
|
||||
if (areGrantsFetching.value) areGrantsFetching.value = false;
|
||||
} catch (error) {
|
||||
notify.error(`Unable to fetch Access Grants. ${error.message}`, AnalyticsErrorEventSource.ACCESS_GRANTS_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles update table rows limit event.
|
||||
*/
|
||||
function onUpdateLimit(limit: number): void {
|
||||
fetch(page.value.currentPage, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles update table page event.
|
||||
*/
|
||||
function onUpdatePage(page: number): void {
|
||||
fetch(page, cursor.value.limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles update table sorting event.
|
||||
*/
|
||||
function onUpdateSortBy(sortBy: {key: keyof AccessGrantsOrderBy, order: keyof SortDirection}[]): void {
|
||||
if (!sortBy.length) return;
|
||||
|
||||
const sorting = sortBy[0];
|
||||
|
||||
agStore.setSortingBy(AccessGrantsOrderBy[sorting.key]);
|
||||
agStore.setSortingDirection(SortDirection[sorting.order]);
|
||||
|
||||
fetch(FIRST_PAGE, cursor.value.limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles update table search.
|
||||
*/
|
||||
watch(() => search.value, () => {
|
||||
clearTimeout(searchTimer.value);
|
||||
|
||||
searchTimer.value = setTimeout(() => {
|
||||
agStore.setSearchQuery(search.value);
|
||||
fetch();
|
||||
}, 500); // 500ms delay for every new call.
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user