refactor table sorting to composables and shared SortableTableHeaderCell

This commit is contained in:
Gregor Vostrak
2026-08-26 14:46:00 +02:00
parent d29f5706ce
commit 0e9f652d84
24 changed files with 596 additions and 611 deletions

View File

@@ -18,6 +18,7 @@ import { getCurrentOrganizationId, getCurrentRole } from '@/utils/useUser';
import { useOrganizationQuery } from '@/utils/useOrganizationQuery';
import { isAllowedToPerformPremiumAction } from '@/utils/billing';
import { useStorage } from '@vueuse/core';
import { useTableSortState } from '@/utils/useTableSortState';
import ProjectsFilterDropdown from '@/Components/Common/Project/ProjectsFilterDropdown.vue';
import ProjectStatusFilterBadge from '@/Components/Common/Project/ProjectStatusFilterBadge.vue';
import ProjectVisibilityFilterBadge from '@/Components/Common/Project/ProjectVisibilityFilterBadge.vue';
@@ -41,7 +42,7 @@ interface ProjectTableState {
};
}
const tableState = useStorage<ProjectTableState>(
const { tableState, handleSort } = useTableSortState<SortColumn, ProjectTableState>(
'project-table-state',
{
sortColumn: 'name',
@@ -52,21 +53,15 @@ const tableState = useStorage<ProjectTableState>(
visibility: 'all',
},
},
undefined,
{
mergeDefaults: (storage, defaults) => ({
...defaults,
...storage,
filters: { ...defaults.filters, ...storage.filters },
}),
}
// The filters are merged key by key so a stored value missing a newer filter still
// picks up its default instead of the whole object falling back.
(storage, defaults) => ({
...defaults,
...storage,
filters: { ...defaults.filters, ...storage.filters },
})
);
function handleSort(column: SortColumn, direction: SortDirection) {
tableState.value.sortColumn = column;
tableState.value.sortDirection = direction;
}
// Filter projects based on current filters
const filteredProjects = computed(() => {
return projects.value.filter((project) => {