Skip to content

Commit

Permalink
Refactor datatable with Pagination Searchobject API service call
Browse files Browse the repository at this point in the history
made adjustment to pagination and load data
  • Loading branch information
jatindersingh93 committed Jan 26, 2024
1 parent b7b227d commit d0c0eb4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 63 deletions.
67 changes: 53 additions & 14 deletions frontend/src/components/object/ObjectTable.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { storeToRefs } from 'pinia';
import { onUnmounted, ref, watch } from 'vue';
import { onUnmounted, onMounted, ref, watch } from 'vue';
import { Spinner } from '@/components/layout';
import {
Expand All @@ -17,6 +17,7 @@ import { useAuthStore, useAppStore, useObjectStore, usePermissionStore } from '@
import { Permissions } from '@/utils/constants';
import { ButtonMode } from '@/utils/enums';
import { formatDateLong } from '@/utils/formatters';
import { objectService } from '@/services';
import type { Ref } from 'vue';
import type { COMSObject } from '@/types';
Expand All @@ -25,6 +26,10 @@ type COMSObjectDataSource = {
lastUpdatedDate?: string;
} & COMSObject;
type DataTableObjectSource = {
[key: string]: any;
};
// Props
type Props = {
bucketId?: string;
Expand Down Expand Up @@ -52,6 +57,12 @@ const permissionsObjectId = ref('');
const permissionsObjectName: Ref<string | undefined> = ref('');
const tableData: Ref<Array<COMSObjectDataSource>> = ref([]);
const loading = ref(false);
const lazyParams: Ref<DataTableObjectSource> = ref({});
const totalRecords = ref(0);
const first = ref(0);
const selectedObjects: any = ref();
// Actions
const toast = useToast();
Expand Down Expand Up @@ -85,18 +96,46 @@ async function showPermissions(objectId: string) {
watch(getObjects, async () => {
clearSelected();
});
// Filter object cache to this specific bucket
const objs: Array<COMSObjectDataSource> = getObjects.value.filter(
(x: COMSObject) => x.bucketId === props.bucketId
) as COMSObjectDataSource[];
onMounted(() => {
loading.value = true;
tableData.value = objs.map((x: COMSObjectDataSource) => {
x.lastUpdatedDate = x.updatedAt ?? x.createdAt;
return x;
});
lazyParams.value = {
first: 0,
rows: 10,
sortField: null,
sortOrder: null,
filters: filters.value
};
loadLazyData(lazyParams);
});
const loadLazyData = (event: any) => {
lazyParams.value = { ...lazyParams.value, first: event?.first || first.value };
objectService
.searchObjects({
bucketId: props.bucketId ? [props.bucketId] : undefined,
deleteMarker: false,
latest: true,
permissions: true,
page: lazyParams.value.page ? lazyParams.value.page + 1 : 1,
limit: lazyParams.value.rows
})
.then((r: any) => {
loading.value = true;
tableData.value = r.data.map((x: COMSObjectDataSource) => {
x.lastUpdatedDate = x.updatedAt ?? x.createdAt;
return x;
});
totalRecords.value = +r?.headers['x-total-rows'];
loading.value = false;
});
};
const onPage = (event: any) => {
lazyParams.value = event;
loadLazyData(event);
};
// Clear selections when navigating away
onUnmounted(() => {
objectStore.setSelectedObjects([]);
Expand All @@ -114,17 +153,17 @@ const filters = ref({
<template>
<div class="object-table">
<DataTable
v-model:selection="objectStore.selectedObjects"
v-model:selection="selectedObjects"
v-model:filters="filters"
:loading="useAppStore().getIsLoading"
lazy
:loading="loading"
:value="tableData"
:total-records="totalRecords"
data-key="id"
class="p-datatable-sm"
responsive-layout="scroll"
:paginator="true"
:rows="10"
paginator-template="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink "
current-page-report-template="{first}-{last} of {totalRecords}"
:rows-per-page-options="[10, 20, 50]"
sort-field="lastUpdatedDate"
:sort-order="-1"
Expand All @@ -140,7 +179,7 @@ const filters = ref({
}
}
"
@page="clearSelected"
@page="onPage($event)"
@update:sort-order="clearSelected"
@update:sort-field="clearSelected"
@update:rows="clearSelected"
Expand Down
50 changes: 1 addition & 49 deletions frontend/src/services/objectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,55 +220,7 @@ export default {
* @returns {Promise} An axios response
*/
async searchObjects(params: SearchObjectsOptions = {}, headers: any = {}) {
// remove objectId array if its first element is undefined
if (params.objectId && params.objectId[0] === undefined) delete params.objectId;

if (params.objectId) {
/**
* split calls to COMS if query params (eg objectId's)
* will cause url length to excede 2000 characters
* see: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
*
* TODO: consider creating a utils function
* eg: `divideParam(params, attr)`
* ...
* return Promise.all(divideParam(params, objectId)
* .map(zparam => comsAxios().get(PATH, {params: zparam, headers: headers});
*/
let urlLimit = 2000;

const baseUrl = new URL(`${new ConfigService().getConfig().coms.apiPath}${PATH}`).toString();
urlLimit -= baseUrl.length; // subtract baseUrl length
if (params.deleteMarker) urlLimit -= 19; // subtract `deleteMarker=false`
if (params.latest) urlLimit -= 13; // subtract `latest=false`
if (params.bucketId) urlLimit -= 48; // subtract a single bucketId `bucketId[]=<uuid>`
// if tagset parameters passed
if (params.tagset) {
type TagsetObjectEntries = {
[K in keyof Tag]: [K, Tag[K]];
}[keyof Tag][];
for (const [key, value] of Object.entries(params.tagset) as TagsetObjectEntries) {
urlLimit -= 10 + key.length + value.length;
}
}

// number of allowed objectId's in each group - 48 chars for each objectId (&objectId[]=<uuid>)
const space = urlLimit;
const groupSize = Math.floor(space / 48);

// loop through each group and push COMS result to `groups` array
const iterations = Math.ceil(params.objectId.length / groupSize);
const groups = [];
for (let i = 0; i < iterations; i++) {
const ids = params.objectId.slice(i * groupSize, i * groupSize + groupSize);
groups.push(await comsAxios().get(PATH, { params: { ...params, objectId: ids }, headers: headers }));
}
return Promise.resolve({ data: groups.flatMap((result) => result.data) });
}
// else just call COMS once
else {
return comsAxios().get(PATH, { params: params, headers: headers });
}
return comsAxios().get(PATH, { params: params, headers: headers });
},

/**
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/types/options/SearchObjectsOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ export type SearchObjectsOptions = {
active?: boolean;
deleteMarker?: boolean;
latest?: boolean;
permissions?: boolean;
page?: number;
limit?: number;
sort?: string;
order?: string;
};

0 comments on commit d0c0eb4

Please sign in to comment.