custom col width persistent

This commit is contained in:
pa
2026-01-11 20:23:01 +09:00
committed by Natsumi
parent 8460c51706
commit 5fa2d4d465
7 changed files with 87 additions and 1 deletions

View File

@@ -7,7 +7,42 @@ import {
isFunction,
useVueTable
} from '@tanstack/vue-table';
import { ref, unref } from 'vue';
import { ref, unref, watch } from 'vue';
function safeJsonParse(str) {
if (!str) {
return null;
}
try {
return JSON.parse(str);
} catch {
return null;
}
}
function debounce(fn, wait) {
let t = 0;
return (...args) => {
if (t) {
clearTimeout(t);
}
t = setTimeout(() => fn(...args), wait);
};
}
function filterSizingByColumns(sizing, columns) {
if (!sizing || typeof sizing !== 'object') {
return {};
}
const ids = new Set((columns ?? []).map((c) => c?.id).filter(Boolean));
const out = {};
for (const [key, value] of Object.entries(sizing)) {
if (ids.has(key)) {
out[key] = value;
}
}
return out;
}
function getColumnId(col) {
return col?.id ?? col?.accessorKey ?? null;
@@ -98,6 +133,10 @@ export function useVrcxVueTable(options) {
fillRemainingSpace = true,
spacerColumnId = '__spacer',
persistKey,
persistColumnSizing = true,
persistDebounceMs = 200,
tableOptions = {}
} = options ?? {};
@@ -112,6 +151,29 @@ export function useVrcxVueTable(options) {
const columnPinning = ref(initialColumnPinning ?? { left: [], right: [] });
const columnSizing = ref(initialColumnSizing ?? {});
const storageKey = persistKey ? `vrcx:table:${persistKey}` : null;
function readPersisted() {
if (!storageKey) {
return null;
}
return safeJsonParse(localStorage.getItem(storageKey));
}
function writePersisted(patch) {
if (!storageKey) {
return;
}
const cur = safeJsonParse(localStorage.getItem(storageKey)) ?? {};
const next = { ...cur, ...patch, updatedAt: Date.now() };
localStorage.setItem(storageKey, JSON.stringify(next));
}
const persisted = readPersisted();
if (persisted && persistColumnSizing && persisted.columnSizing) {
columnSizing.value = persisted.columnSizing;
}
const state = {};
const handlers = {};
const rowModels = {};
@@ -199,6 +261,24 @@ export function useVrcxVueTable(options) {
...tableOptions
});
const persistWrite = debounce(
(payload) => writePersisted(payload),
persistDebounceMs
);
if (storageKey && persistColumnSizing) {
watch(
columnSizing,
(val) => {
const cols = table.getAllLeafColumns?.() ?? [];
persistWrite({
columnSizing: filterSizingByColumns(val, cols)
});
},
{ deep: true }
);
}
return {
table,
sorting,

View File

@@ -76,6 +76,7 @@
);
const { table, pagination } = useVrcxVueTable({
persistKey: 'feed',
data: feedDisplayData,
columns: baseColumns,
getRowId: (row) => `${row.type}:${row.rowId}:${row.created_at ?? ''}`,

View File

@@ -157,6 +157,7 @@
);
const { table, pagination } = useVrcxVueTable({
persistKey: 'friendLog',
data: friendLogDisplayData,
columns,
getRowId: (row) => `${row.type}:${row.rowId ?? row.userId ?? row.created_at ?? ''}`,

View File

@@ -156,6 +156,7 @@
);
const { table, pagination } = useVrcxVueTable({
persistKey: 'gameLog',
data: gameLogDisplayData,
columns,
getRowId: (row) => `${row.type}:${row.rowId ?? row.displayName + row.location + row.time}`,

View File

@@ -145,6 +145,7 @@
);
const { table, pagination } = useVrcxVueTable({
persistKey: 'moderation',
data: moderationDisplayData,
columns,
getRowId: (row) => row.id ?? `${row.type}:${row.sourceUserId}:${row.targetUserId}:${row.created ?? ''}`,

View File

@@ -213,6 +213,7 @@
);
const { table, pagination } = useVrcxVueTable({
persistKey: 'notifications',
data: notificationDisplayData,
columns,
getRowId: (row) => row.id ?? `${row.type}:${row.senderUserId ?? ''}:${row.created_at ?? ''}`,

View File

@@ -278,6 +278,7 @@
const playerListDisplayData = computed(() => currentInstanceUsersData.value ?? []);
const { table: playerListTable } = useVrcxVueTable({
persistKey: 'playerList',
data: playerListDisplayData,
columns: playerListColumns.value,
getRowId: (row) => `${row?.ref?.id ?? ''}:${row?.displayName ?? ''}:${row?.photonId ?? ''}`,