add table sorting to members, clients and tags table

This commit is contained in:
Gregor Vostrak
2026-02-18 17:41:36 +01:00
parent 88c0c334e9
commit cf98fabe0a
17 changed files with 829 additions and 46 deletions

View File

@@ -12,6 +12,8 @@ import PageTitle from '@/Components/Common/PageTitle.vue';
import { canCreateClients } from '@/utils/permissions';
import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue';
import TabBar from '@/Components/Common/TabBar/TabBar.vue';
import { useStorage } from '@vueuse/core';
import type { SortColumn, SortDirection } from '@/Components/Common/Client/ClientTable.vue';
const { clients } = useClientsQuery();
@@ -19,6 +21,26 @@ const activeTab = ref<'active' | 'archived'>('active');
const createClient = ref(false);
interface ClientTableState {
sortColumn: SortColumn;
sortDirection: SortDirection;
}
const tableState = useStorage<ClientTableState>(
'client-table-state',
{
sortColumn: 'name',
sortDirection: 'asc',
},
undefined,
{ mergeDefaults: true }
);
function handleSort(column: SortColumn, direction: SortDirection) {
tableState.value.sortColumn = column;
tableState.value.sortDirection = direction;
}
const shownClients = computed(() => {
return clients.value.filter((client) => {
if (activeTab.value === 'active') {
@@ -45,6 +67,10 @@ const shownClients = computed(() => {
>
<ClientCreateModal v-model:show="createClient"></ClientCreateModal>
</MainContainer>
<ClientTable :clients="shownClients"></ClientTable>
<ClientTable
:clients="shownClients"
:sort-column="tableState.sortColumn"
:sort-direction="tableState.sortDirection"
@sort="handleSort"></ClientTable>
</AppLayout>
</template>

View File

@@ -13,6 +13,8 @@ import type { Role } from '@/types/jetstream';
import PageTitle from '@/Components/Common/PageTitle.vue';
import InvitationTable from '@/Components/Common/Invitation/InvitationTable.vue';
import { canCreateInvitations } from '@/utils/permissions';
import { useStorage } from '@vueuse/core';
import type { SortColumn, SortDirection } from '@/Components/Common/Member/MemberTable.vue';
const inviteMember = ref(false);
@@ -21,6 +23,26 @@ defineProps<{
}>();
const activeTab = ref<'all' | 'invitations'>('all');
interface MemberTableState {
sortColumn: SortColumn;
sortDirection: SortDirection;
}
const tableState = useStorage<MemberTableState>(
'member-table-state',
{
sortColumn: 'name',
sortDirection: 'asc',
},
undefined,
{ mergeDefaults: true }
);
function handleSort(column: SortColumn, direction: SortDirection) {
tableState.value.sortColumn = column;
tableState.value.sortDirection = direction;
}
</script>
<template>
@@ -45,7 +67,11 @@ const activeTab = ref<'all' | 'invitations'>('all');
:available-roles="availableRoles"
@close="activeTab = 'invitations'"></MemberInviteModal>
</MainContainer>
<MemberTable v-if="activeTab === 'all'"></MemberTable>
<MemberTable
v-if="activeTab === 'all'"
:sort-column="tableState.sortColumn"
:sort-direction="tableState.sortDirection"
@sort="handleSort"></MemberTable>
<InvitationTable v-if="activeTab === 'invitations'"></InvitationTable>
</AppLayout>
</template>

View File

@@ -147,7 +147,9 @@ const showBillableRate = computed(() => {
data-testid="status-filter-badge"
:value="tableState.filters.status"
@remove="removeStatusFilter"
@update:value="tableState.filters.status = $event as 'active' | 'archived' | 'all'" />
@update:value="
tableState.filters.status = $event as 'active' | 'archived' | 'all'
" />
<ProjectClientFilterBadge
v-if="tableState.filters.clientIds.length > 0"

View File

@@ -9,9 +9,31 @@ import TagCreateModal from '@/packages/ui/src/Tag/TagCreateModal.vue';
import PageTitle from '@/Components/Common/PageTitle.vue';
import { canCreateTags } from '@/utils/permissions';
import { useTagsStore } from '@/utils/useTags';
import { useStorage } from '@vueuse/core';
import type { SortColumn, SortDirection } from '@/Components/Common/Tag/TagTable.vue';
const showCreateTagModal = ref(false);
interface TagTableState {
sortColumn: SortColumn;
sortDirection: SortDirection;
}
const tableState = useStorage<TagTableState>(
'tag-table-state',
{
sortColumn: 'name',
sortDirection: 'asc',
},
undefined,
{ mergeDefaults: true }
);
function handleSort(column: SortColumn, direction: SortDirection) {
tableState.value.sortColumn = column;
tableState.value.sortDirection = direction;
}
async function createTag(tag: string) {
return await useTagsStore().createTag(tag);
}
@@ -34,6 +56,10 @@ async function createTag(tag: string) {
v-model:show="showCreateTagModal"
:create-tag="createTag"></TagCreateModal>
</MainContainer>
<TagTable :create-tag="createTag"></TagTable>
<TagTable
:create-tag="createTag"
:sort-column="tableState.sortColumn"
:sort-direction="tableState.sortDirection"
@sort="handleSort"></TagTable>
</AppLayout>
</template>