import { computed, ref, watch, type ComputedRef, type Ref } from 'vue' export interface VisibilityColumn { key: string title?: string visible?: boolean showInModal?: boolean } export interface TempVisibilityColumn { key: string title?: string visible: boolean showInModal: boolean } export interface UseTableColumnVisibilityOptions { columns: Ref | ComputedRef minVisible?: number save?: (columns: TempVisibilityColumn[]) => void } export function useTableColumnVisibility( opts: UseTableColumnVisibilityOptions, ) { const minVisible = opts.minVisible ?? 1 const showMenu = ref(false) const tempColumns = ref([]) const visibleColumnsCount = computed(() => tempColumns.value.filter((c) => c.visible).length) const areAllColumnsSelected = computed({ get() { const toggleable = tempColumns.value.filter((c) => c.key !== 'id' && c.showInModal) return toggleable.length > 0 && toggleable.every((c) => c.visible) }, set(value: boolean) { tempColumns.value.forEach((c) => { if (c.key !== 'id' && c.showInModal) { c.visible = value } }) const idColumn = tempColumns.value.find((c) => c.key === 'id') if (idColumn) idColumn.visible = true }, }) const isCheckboxDisabled = (columnKey: string): boolean => { const col = tempColumns.value.find((c) => c.key === columnKey) return visibleColumnsCount.value === minVisible && !!col?.visible } const openMenu = () => { tempColumns.value = opts.columns.value.map((column) => ({ key: column.key, title: column.title, visible: column.visible ?? true, showInModal: column.showInModal ?? true, })) showMenu.value = true } const applyColumnVisibility = () => { tempColumns.value.forEach((tempColumn) => { const column = opts.columns.value.find((c) => c.key === tempColumn.key) if (column) column.visible = tempColumn.visible }) opts.save?.(tempColumns.value) showMenu.value = false } // Safety net: never allow all columns to be unchecked — force 'id' visible. watch( () => tempColumns.value.map((column) => column.visible), () => { const visibleColumns = tempColumns.value.filter((column) => column.visible) if (visibleColumns.length === 0) { const idColumn = tempColumns.value.find((column) => column.key === 'id') if (idColumn) idColumn.visible = true } }, ) return { showMenu, tempColumns, openMenu, applyColumnVisibility, areAllColumnsSelected, isCheckboxDisabled, } }