fix datatable header reorder issue

This commit is contained in:
pa
2026-03-07 00:23:02 +09:00
parent 9feef5d119
commit c42b126131
8 changed files with 264 additions and 45 deletions

View File

@@ -332,4 +332,88 @@ describe('useVrcxVueTable persistence', () => {
);
expect(stored?.pageSize).toBeUndefined();
});
it('resetAll clears both columnSizing and columnOrder', async () => {
const { columnSizing, columnOrder, resetAll } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-reset-all',
enableColumnResizing: true,
enableColumnReorder: true
});
columnSizing.value = { name: 200 };
columnOrder.value = ['date', 'name'];
await new Promise((r) => setTimeout(r, 300));
resetAll();
expect(columnSizing.value).toEqual({});
expect(columnOrder.value).toEqual([]);
const stored = JSON.parse(
localStorage.getItem('vrcx:table:test-reset-all')
);
expect(stored?.columnSizing).toBeUndefined();
expect(stored?.columnOrder).toBeUndefined();
});
it('persists columnOrderLocked to localStorage', async () => {
const { columnOrderLocked } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-lock-order'
});
expect(columnOrderLocked.value).toBe(false);
columnOrderLocked.value = true;
// Watcher is async, wait for it to fire
await new Promise((r) => setTimeout(r, 50));
const stored = JSON.parse(
localStorage.getItem('vrcx:table:test-lock-order')
);
expect(stored?.columnOrderLocked).toBe(true);
});
it('restores columnOrderLocked from localStorage on init', () => {
localStorage.setItem(
'vrcx:table:test-restore-lock',
JSON.stringify({ columnOrderLocked: true })
);
const { columnOrderLocked } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-restore-lock'
});
expect(columnOrderLocked.value).toBe(true);
});
it('attaches controls to table.options.meta when persistKey is set', () => {
const { table } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-meta'
});
const meta = table.options.meta;
expect(meta.resetAll).toBeTypeOf('function');
expect(meta.columnOrderLocked).toBeDefined();
expect(meta.columnOrderLocked.value).toBe(false);
});
it('does not attach controls to meta without persistKey', () => {
const { table } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date')
});
const meta = table.options.meta;
expect(meta.resetAll).toBeUndefined();
expect(meta.columnOrderLocked).toBeUndefined();
});
});

View File

@@ -273,6 +273,21 @@ export function useVrcxVueTable(options) {
localStorage.setItem(storageKey, JSON.stringify(next));
}
/**
* @param keys
*/
function removePersisted(keys) {
if (!storageKey) {
return;
}
const cur = safeJsonParse(localStorage.getItem(storageKey)) ?? {};
for (const key of keys) {
delete cur[key];
}
cur.updatedAt = Date.now();
localStorage.setItem(storageKey, JSON.stringify(cur));
}
const persisted = readPersisted();
let resolvedSorting = initialSorting ?? [];
@@ -309,6 +324,9 @@ export function useVrcxVueTable(options) {
};
}
// Column order lock — persisted per-table
const columnOrderLocked = ref(persisted?.columnOrderLocked === true);
const state = {};
const handlers = {};
const rowModels = {};
@@ -417,6 +435,11 @@ export function useVrcxVueTable(options) {
state,
meta: {
resetAll: storageKey ? resetAll : undefined,
columnOrderLocked: storageKey ? columnOrderLocked : undefined
},
...tableOptions
});
@@ -505,6 +528,20 @@ export function useVrcxVueTable(options) {
);
}
if (storageKey) {
watch(columnOrderLocked, (val) => {
writePersisted({ columnOrderLocked: val });
});
}
/**
*/
function resetAll() {
columnSizing.value = {};
columnOrder.value = [];
removePersisted(['columnSizing', 'columnOrder']);
}
return {
table,
sorting,
@@ -513,6 +550,8 @@ export function useVrcxVueTable(options) {
columnPinning,
columnSizing,
columnOrder,
columnVisibility
columnVisibility,
columnOrderLocked,
resetAll
};
}