@kaifronsdal/transcript-viewer
Version:
A web-based viewer for AI conversation transcripts with rollback support
147 lines (129 loc) • 4.29 kB
text/typescript
import type {
SortingState,
VisibilityState,
ExpandedState,
ColumnSizingState,
OnChangeFn,
TableOptions
} from '@tanstack/svelte-table';
import type { Writable } from 'svelte/store';
import {
loadColumnVisibility,
saveColumnVisibility,
loadColumnSizing,
saveColumnSizing
} from '$lib/client/utils/table-persistence';
import { getDefaultColumnVisibility } from '$lib/client/utils/table-columns';
export function useTableState(
scoreTypes: string[],
expandedFolders: Set<string>,
onToggleFolder: (path: string) => void,
options: Writable<TableOptions<any>>
) {
// Initialize state
let sorting = $state<SortingState>([]);
let columnVisibility = $state<VisibilityState>({});
let columnSizing = $state<ColumnSizingState>({});
// Expanded state is managed by watching external expandedFolders
let expanded = $state<ExpandedState>({});
// Effect to update expanded state when external expandedFolders changes
$effect(() => {
const expandedState: ExpandedState = {};
expandedFolders.forEach(path => {
expandedState[path] = true;
});
console.log('📂 [DEBUG] Converting external expandedFolders to table state:', {
external: [...expandedFolders],
tableState: expandedState
});
expanded = expandedState;
// Don't call updateOptions here - it will be called by other effects
});
// Prevent infinite sync loops
let isSyncing = false;
// Load persisted state
function initializeState() {
// Load column visibility from localStorage or use defaults
const savedVisibility = loadColumnVisibility();
columnVisibility = Object.keys(savedVisibility).length > 0
? savedVisibility
: getDefaultColumnVisibility(scoreTypes);
// Load column sizing
columnSizing = loadColumnSizing();
// Expanded state is handled by derived state - no initialization needed
console.log('✅ [DEBUG] Table state initialized');
}
// State setters
const setSorting: OnChangeFn<SortingState> = (updater) => {
if (updater instanceof Function) {
sorting = updater(sorting);
} else {
sorting = updater;
}
updateOptions();
};
const setColumnVisibility: OnChangeFn<VisibilityState> = (updater) => {
if (updater instanceof Function) {
columnVisibility = updater(columnVisibility);
} else {
columnVisibility = updater;
}
updateOptions();
saveColumnVisibility(columnVisibility);
};
// No setExpanded needed - expanded state is derived and read-only from table perspective
const setColumnSizing: OnChangeFn<ColumnSizingState> = (updater) => {
if (updater instanceof Function) {
columnSizing = updater(columnSizing);
} else {
columnSizing = updater;
}
console.log('🔧 [DEBUG] Column sizing updated:', $state.snapshot(columnSizing));
updateOptions();
saveColumnSizing(columnSizing);
};
function updateOptions() {
const currentExpanded = expanded; // Capture current expanded state
console.log('🔧 [DEBUG] updateOptions called with expanded state:', currentExpanded);
options.update(old => ({
...old,
state: {
...old.state,
sorting,
columnVisibility,
expanded: currentExpanded, // Use captured expanded state
columnSizing,
},
onSortingChange: setSorting,
onColumnVisibilityChange: setColumnVisibility,
// No onExpandedChange - we don't want table to manage expanded state
onColumnSizingChange: setColumnSizing,
}));
}
// Expose a function to trigger updates when needed
function forceUpdate() {
updateOptions();
}
// Manual column visibility toggle
function toggleColumnVisibility(columnId: string, visible: boolean) {
setColumnVisibility(prev => ({
...prev,
[columnId]: visible
}));
}
return {
// State
get sorting() { return sorting; },
get columnVisibility() { return columnVisibility; },
get expanded() { return expanded; },
get columnSizing() { return columnSizing; },
// Setters (no setExpanded - it's derived)
setSorting,
setColumnVisibility,
setColumnSizing,
// Utilities
initializeState,
toggleColumnVisibility,
forceUpdate,
};
}