Files
alphane.ca/web/src/components/users/UsersDataTableServer.vue
T
2026-06-19 23:55:39 -07:00

108 lines
2.3 KiB
Vue

<template>
<v-data-table-server
v-model:items-per-page="perPage"
:page="page"
:headers="headers"
:items="users"
:items-length="totalCount"
:loading="isLoading"
@click:row="rowClicked"
@update:page="updatePage"
>
<template #item.roles="{ item }"> {{ item.roles?.join(", ") }} affaafafa </template>
<template #item.updatedAt="{ value }">{{ formatDate(value) }}</template>
<template #item.createdAt="{ value }">{{ formatDate(value) }}</template>
<template
v-for="(_, name) in $slots"
:key="name"
#[name]="slotProps"
>
<slot
:name="name"
v-bind="slotProps"
></slot>
</template>
</v-data-table-server>
</template>
<script lang="ts">
export const DEFAULT_HEADERS = [
{
title: "Name",
key: "displayName",
},
{
title: "Email",
key: "email",
},
{
title: "Roles",
key: "roles",
},
]
</script>
<script setup lang="ts">
import { computed } from "vue"
import { formatDate } from "@/utils/formatters"
import useUsers, {
User,
UserFiltersOptions,
UserQueryOptions,
UserWhereOptions,
} from "@/use/use-users"
import useRouteQueryPagination from "@/use/utils/use-route-query-pagination"
const props = withDefaults(
defineProps<{
headers?: { title: string; key: string }[]
filters?: UserFiltersOptions
where?: UserWhereOptions
waiting?: boolean
routeQuerySuffix?: string
}>(),
{
headers: () => DEFAULT_HEADERS,
filters: () => ({}),
where: () => ({}),
waiting: false,
routeQuerySuffix: "Users",
}
)
const { page, perPage } = useRouteQueryPagination({ routeQuerySuffix: "Users", perPage: 100 })
const userQueryOptions = computed<UserQueryOptions>(() => {
return {
where: props.where,
filters: props.filters,
perPage: perPage.value,
page: page.value,
}
})
const { users, totalCount, isLoading, refresh } = useUsers(userQueryOptions, {
skipWatchIf: () => props.waiting,
})
type UserTableRow = {
item: User
}
const emit = defineEmits<{ clicked: [userId: User] }>()
function rowClicked(_event: unknown, row: UserTableRow) {
emit("clicked", row.item)
}
function updatePage(newPage: number) {
if (isLoading.value || props.waiting) return
page.value = newPage
}
defineExpose({ refresh })
</script>