Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 12 additions & 33 deletions ui/src/components/Connector/ConnectorList.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
<template>
<DataTable
:headers="headers"
:items="keyList"
:itemsPerPage="itemsPerPage"
:nextPage="next"
:previousPage="prev"
:loading="loading"
:actualPage="page"
:totalCount="numberKeys"
:comboboxOptions="[10, 20, 50, 100]"
@changeItemsPerPage="changeItemsPerPage"
@clickNextPage="next"
@clickPreviousPage="prev"
v-model:page="page"
v-model:itemsPerPage="itemsPerPage"
:headers
:items="connectors"
:totalCount="connectorsCount"
:loading
:itemsPerPageOptions="[10, 20, 50, 100]"
data-test="connector-list"
>
<template v-slot:rows>
<tr v-for="(item, i) in keyList" :key="i">
<tr v-for="(item, i) in connectors" :key="i">
<td class="text-center">
<div data-test="status-connector" :class="(item.status.state === 'connected' ? 'enabled' : 'disabled') + ' text-center'" />
</td>
Expand Down Expand Up @@ -172,11 +167,11 @@ const page = ref(1);

const store = useStore();

const numberKeys = computed<number>(
const connectorsCount = computed<number>(
() => store.getters["connectors/getNumberConnectors"],
);

const keyList = computed(() => store.getters["connectors/list"]);
const connectors = computed(() => store.getters["connectors/list"]);

const hasAuthorizationEdit = () => {
const role = store.getters["auth/role"];
Expand Down Expand Up @@ -230,24 +225,8 @@ const refresh = async () => {
await getConnectors(itemsPerPage.value, page.value);
};

const next = async () => {
await getConnectors(itemsPerPage.value, ++page.value);
};

const prev = async () => {
try {
if (page.value > 1) await getConnectors(itemsPerPage.value, --page.value);
} catch (error) {
snackbar.showError("An error occurred while loading connectors");
}
};

const changeItemsPerPage = async (newItemsPerPage: number) => {
itemsPerPage.value = newItemsPerPage;
};

watch(itemsPerPage, async (newItemsPerPage) => {
await getConnectors(newItemsPerPage, page.value);
watch([page, itemsPerPage], async () => {
await getConnectors(itemsPerPage.value, page.value);
});

const redirectToDetails = (uid: string) => {
Expand Down
122 changes: 37 additions & 85 deletions ui/src/components/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,130 +3,82 @@
<v-table class="bg-background border rounded">
<thead class="bg-v-theme-background">
<tr>
<th v-for="(head, i) in headers" :key="i" :class="head.align ? `text-${head.align}` : 'text-center'">
<th v-for="(header, i) in headers" :key="i" class="text-center">
<span
v-if="head.sortable"
@click="$emit('clickSortableIcon', head.value)"
@keypress.enter="$emit('clickSortableIcon', head.value)"
v-if="header.sortable"
@click="$emit('update:sort', header.value)"
@keypress.enter="$emit('update:sort', header.value)"
tabindex="0"
class="hover"
class="cursor-pointer text-decoration-underline"
>
{{ head.text }}
<v-tooltip activator="parent" anchor="top">Sort by {{ head.text }}</v-tooltip>
{{ header.text }}
<v-tooltip activator="parent" anchor="top">Sort by {{ header.text }}</v-tooltip>
</span>
<span v-else> {{ head.text }}</span>
<span v-else> {{ header.text }}</span>
</th>
</tr>
</thead>
<tbody v-if="items.length">
<slot name="rows" />
</tbody>
<div v-else class="pa-4 text-subtitle-2">
<p>No data available</p>
</div>
<tbody v-else class="pa-4 text-subtitle-2">
<tr>
<td :colspan="headers.length" class="pa-4 text-subtitle-2 text-center">
No data available
</td>
</tr>
</tbody>
</v-table>

<v-progress-linear v-if="loading" indeterminate alt="Data table loading" />
<div class="d-flex w-100 justify-end align-center" v-if="!itemSelectorDisable == true">
<div class="d-flex w-100 justify-end align-center" v-if="itemsPerPageOptions?.length">
<span class="text-subtitle-2 mr-4">Items per page:</span>
<div>
<v-combobox
:items="comboboxOptions"
v-model="itemsPerPageRef"
:items="itemsPerPageOptions"
v-model="itemsPerPage"
@update:model-value="goToFirstPage"
outlined
:update:modelValue="$emit('changeItemsPerPage', itemsPerPageRef)"
variant="underlined"
hide-details
class="mb-4"
/>
</div>
<div class="d-flex align-center">
<v-btn icon="mdi-chevron-left" variant="plain" @click="$emit('clickPreviousPage')" :disabled="pageQuantity <= 1" />
<span class="text-subtitle-2">{{ actualPage }} of {{ pageQuantity }}</span>
<v-btn icon="mdi-chevron-left" variant="plain" @click="page--" :disabled="page <= 1" />
<span class="text-subtitle-2">{{ page }} of {{ pageQuantity }}</span>
<v-btn
icon="mdi-chevron-right"
variant="plain"
@click="$emit('clickNextPage')"
:disabled="pageQuantity <= 1 || actualPage == pageQuantity" />
@click="page++"
:disabled="pageQuantity <= 1 || page === pageQuantity" />
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, PropType, toRefs, ref } from "vue";
import { computed } from "vue";

type HeaderItem = {
type Header = {
text: string;
value: string;
sortable?: boolean;
align?: "center" | "left" | "right";
};

type UserTable = {
name: string;
email: string;
username: string;
namespaces: string;
};
const props = defineProps<{
headers: Header[];
items: object[];
totalCount: number;
loading: boolean;
itemsPerPageOptions?: number[];
}>();

const props = defineProps({
headers: {
type: Array as PropType<HeaderItem[]>,
default: () => [],
required: true,
},
items: {
type: Array,
default: () => [] as PropType<UserTable[]>,
required: false,
},
itemsPerPage: {
type: Number,
required: true,
},
itemSelectorDisable: {
type: Boolean,
required: false,
},
comboboxOptions: {
type: Array as PropType<number[]>,
required: false,
default: () => [10, 20, 50, 100],
},
loading: {
type: Boolean,
default: false,
required: false,
},
actualPage: {
type: Number,
default: 1,
},
totalCount: {
type: Number,
required: true,
},
nextPage: {
type: Function as PropType<() => void>,
default: Function as PropType<() => {}>,
},
previousPage: {
type: Function as PropType<() => void>,
default: Function as PropType<() => {}>,
},
});
defineEmits(["update:sort"]);

defineEmits(["changeItemsPerPage", "clickNextPage", "clickPreviousPage", "clickSortableIcon"]);
const page = defineModel<number>("page", { required: true, type: Number });
const itemsPerPage = defineModel("itemsPerPage", { required: true, type: Number });
const pageQuantity = computed(() => Math.ceil(props.totalCount / itemsPerPage.value) || 1);

const { itemsPerPage, totalCount } = toRefs(props);
const itemsPerPageRef = ref(itemsPerPage.value);
const pageQuantity = computed(() => Math.ceil(totalCount.value / itemsPerPageRef.value));
const goToFirstPage = () => { page.value = 1; };
</script>

<style scoped>
.hover:hover {
cursor: pointer;
text-decoration: underline;
}
</style>
28 changes: 5 additions & 23 deletions ui/src/components/Devices/DeviceListChooser.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
<template>
<v-card class="bg-v-theme-surface" data-test="devices-list-chooser">
<DataTable
:headers="headers"
v-model:page="page"
v-model:itemsPerPage="itemsPerPage"
:headers
:items="devices"
:itemsPerPage="itemsPerPage"
:nextPage="next"
:previousPage="prev"
:loading="loading"
:totalCount="numberDevices"
:actualPage="page"
:enable-items-per-page="false"
:comboboxOptions="[5]"
@clickNextPage="next"
@clickPreviousPage="prev"
:loading
data-test="devices-dataTable"
>
<template v-slot:rows>
Expand Down Expand Up @@ -151,19 +145,7 @@ const getDevices = async (perPageValue: number, pageValue: number) => {
}
};

const next = async () => {
await getDevices(itemsPerPage.value, ++page.value);
};

const prev = async () => {
try {
if (page.value > 1) await getDevices(itemsPerPage.value, --page.value);
} catch (error) {
snackbar.showError("An error occurred while fetching devices.");
}
};

watch(itemsPerPage, async () => {
watch([page, itemsPerPage], async () => {
await getDevices(itemsPerPage.value, page.value);
});

Expand Down
39 changes: 8 additions & 31 deletions ui/src/components/PublicKeys/PublicKeysList.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
<template>
<div>
<DataTable
v-bind="$attrs"
:headers="headers"
v-model:page="page"
v-model:itemsPerPage="itemsPerPage"
:headers
:items="publicKeys"
:itemsPerPage="itemsPerPage"
:nextPage="next"
:previousPage="prev"
:loading="loading"
:totalCount="getNumberPublicKeys"
:actualPage="page"
:comboboxOptions="[10, 20, 50, 100]"
@changeItemsPerPage="changeItemsPerPage"
@clickNextPage="next"
@clickPreviousPage="prev"
:totalCount="publicKeysCount"
:loading
:itemsPerPageOptions="[10, 20, 50, 100]"
data-test="publicKeys-list"
>
<template v-slot:rows>
Expand Down Expand Up @@ -170,7 +164,7 @@ const loading = ref(false);
const itemsPerPage = ref(10);
const page = ref(1);
const publicKeys = computed(() => store.getters["publicKeys/list"]);
const getNumberPublicKeys = computed(
const publicKeysCount = computed(
() => store.getters["publicKeys/getNumberPublicKeys"],
);

Expand Down Expand Up @@ -215,24 +209,7 @@ const getPublicKeysList = async (
}
};

const next = async () => {
await getPublicKeysList(itemsPerPage.value, ++page.value);
};

const prev = async () => {
try {
if (page.value > 1) await getPublicKeysList(itemsPerPage.value, --page.value);
} catch (error: unknown) {
snackbar.showError("Failed to load public keys.");
handleError(error);
}
};

const changeItemsPerPage = async (newItemsPerPage: number) => {
itemsPerPage.value = newItemsPerPage;
};

watch(itemsPerPage, async () => {
watch([page, itemsPerPage], async () => {
await getPublicKeysList(itemsPerPage.value, page.value);
});

Expand Down
Loading