|
| 1 | +<template> |
| 2 | + <div class="groups-table"> |
| 3 | + <UiTitle> |
| 4 | + {{ t('groups') }} |
| 5 | + </UiTitle> |
| 6 | + <VtsQueryBuilder v-model="filter" :schema /> |
| 7 | + <div class="container"> |
| 8 | + <VtsTable :state :pagination-bindings> |
| 9 | + <thead> |
| 10 | + <tr> |
| 11 | + <HeadCells /> |
| 12 | + </tr> |
| 13 | + </thead> |
| 14 | + <tbody> |
| 15 | + <VtsRow v-for="group of paginatedGroups" :key="group.id"> |
| 16 | + <BodyCells :item="group" /> |
| 17 | + </VtsRow> |
| 18 | + </tbody> |
| 19 | + </VtsTable> |
| 20 | + </div> |
| 21 | + </div> |
| 22 | +</template> |
| 23 | + |
| 24 | +<script setup lang="ts"> |
| 25 | +import type { FrontXoGroup } from '@/modules/group/remote-resources/use-xo-group-collection.ts' |
| 26 | +import VtsQueryBuilder from '@core/components/query-builder/VtsQueryBuilder.vue' |
| 27 | +import VtsRow from '@core/components/table/VtsRow.vue' |
| 28 | +import VtsTable from '@core/components/table/VtsTable.vue' |
| 29 | +import UiTitle from '@core/components/ui/title/UiTitle.vue' |
| 30 | +import { usePagination } from '@core/composables/pagination.composable.ts' |
| 31 | +import { useTableState } from '@core/composables/table-state.composable.ts' |
| 32 | +import { useQueryBuilderSchema } from '@core/packages/query-builder/schema/use-query-builder-schema.ts' |
| 33 | +import { useQueryBuilderFilter } from '@core/packages/query-builder/use-query-builder-filter.ts' |
| 34 | +import { useGroupColumns } from '@core/tables/column-sets/group-columns.ts' |
| 35 | +import { useNumberSchema } from '@core/utils/query-builder/use-number-schema.ts' |
| 36 | +import { useStringSchema } from '@core/utils/query-builder/use-string-schema.ts' |
| 37 | +import { computed } from 'vue' |
| 38 | +import { useI18n } from 'vue-i18n' |
| 39 | +
|
| 40 | +type FilterableGroup = FrontXoGroup & { provider: string; usersCount: number; rolesCount: number } |
| 41 | +
|
| 42 | +const { |
| 43 | + groups: rawGroups, |
| 44 | + busy, |
| 45 | + error, |
| 46 | +} = defineProps<{ |
| 47 | + groups: FrontXoGroup[] |
| 48 | + busy?: boolean |
| 49 | + error?: boolean |
| 50 | +}>() |
| 51 | +
|
| 52 | +const { t } = useI18n() |
| 53 | +
|
| 54 | +const filterableGroups = computed<FilterableGroup[]>(() => |
| 55 | + rawGroups.map(group => ({ |
| 56 | + ...group, |
| 57 | + provider: group.provider ?? '', |
| 58 | + usersCount: group.users.length, |
| 59 | + rolesCount: group.aclRoleIds.length, |
| 60 | + })) |
| 61 | +) |
| 62 | +
|
| 63 | +const { items: filteredGroups, filter } = useQueryBuilderFilter('groups', () => filterableGroups.value) |
| 64 | +
|
| 65 | +const schema = useQueryBuilderSchema<FilterableGroup>({ |
| 66 | + '': useStringSchema(t('any-property')), |
| 67 | + name: useStringSchema(t('name')), |
| 68 | + provider: useStringSchema(t('provider')), |
| 69 | + usersCount: useNumberSchema(t('users')), |
| 70 | + rolesCount: useNumberSchema(t('roles')), |
| 71 | +}) |
| 72 | +
|
| 73 | +const state = useTableState({ |
| 74 | + busy: () => busy, |
| 75 | + error: () => error, |
| 76 | + empty: () => |
| 77 | + rawGroups.length === 0 ? t('no-group-detected') : filteredGroups.value.length === 0 ? { type: 'no-result' } : false, |
| 78 | +}) |
| 79 | +
|
| 80 | +const { pageRecords: paginatedGroups, paginationBindings } = usePagination('groups', filteredGroups) |
| 81 | +
|
| 82 | +const { HeadCells, BodyCells } = useGroupColumns({ |
| 83 | + body: (group: FilterableGroup) => ({ |
| 84 | + name: r => r(group.name), |
| 85 | + provider: r => r(group.provider), |
| 86 | + users: r => r(group.usersCount), |
| 87 | + roles: r => r(group.rolesCount), |
| 88 | + }), |
| 89 | +}) |
| 90 | +</script> |
| 91 | + |
| 92 | +<style scoped lang="postcss"> |
| 93 | +.groups-table, |
| 94 | +.container { |
| 95 | + display: flex; |
| 96 | + flex-direction: column; |
| 97 | + gap: 2.4rem; |
| 98 | +} |
| 99 | +
|
| 100 | +.container { |
| 101 | + gap: 0.8rem; |
| 102 | +} |
| 103 | +</style> |
0 commit comments