1
0
Fork 0
mirror of synced 2024-07-07 15:25:52 +12:00

Add persitence to column size and order in sheets

This commit is contained in:
Andrew Kingston 2023-04-12 14:56:22 +01:00
parent 49611298b4
commit 724bff60f2
4 changed files with 79 additions and 18 deletions

View file

@ -12,10 +12,11 @@ export const createStores = () => {
columns,
$columns => {
let offset = 0
return $columns.map(column => {
return $columns.map((column, idx) => {
const enriched = {
...column,
left: offset,
order: idx,
}
if (column.visible) {
offset += column.width
@ -85,15 +86,27 @@ export const deriveStores = context => {
}
return {
name: field,
width: existing?.width || DefaultColumnWidth,
width: existing?.width || schema[field].width || DefaultColumnWidth,
schema: schema[field],
visible: existing?.visible ?? true,
order: schema[field].order,
}
})
.sort((a, b) => {
// Sort columns to put auto columns last
let autoColA = a.schema?.autocolumn
let autoColB = b.schema?.autocolumn
// Sort by order first
const orderA = a.order
const orderB = b.order
if (orderA != null && orderB != null) {
return orderA < orderB ? -1 : 1
} else if (orderA != null) {
return -1
} else if (orderB != null) {
return 1
}
// Then sort by auto columns
const autoColA = a.schema?.autocolumn
const autoColB = b.schema?.autocolumn
if (autoColA === autoColB) {
return 0
}
@ -115,7 +128,8 @@ export const deriveStores = context => {
}
stickyColumn.set({
name: primaryDisplay,
width: existing?.width || DefaultColumnWidth,
width:
existing?.width || schema[primaryDisplay].width || DefaultColumnWidth,
left: gutterWidth,
schema: schema[primaryDisplay],
idx: "sticky",

View file

@ -1,4 +1,5 @@
import { get, writable, derived } from "svelte/store"
import { cloneDeep } from "lodash/fp"
const reorderInitialState = {
sourceColumn: null,
@ -23,7 +24,8 @@ export const createStores = () => {
}
export const deriveStores = context => {
const { reorder, columns, scroll, bounds, stickyColumn, ui } = context
const { reorder, columns, scroll, bounds, stickyColumn, ui, table, API } =
context
// Callback when dragging on a colum header and starting reordering
const startReordering = (column, e) => {
@ -88,10 +90,10 @@ export const deriveStores = context => {
}
// Callback when stopping reordering columns
const stopReordering = () => {
const stopReordering = async () => {
// Swap position of columns
let { sourceColumn, targetColumn } = get(reorder)
const $columns = get(columns)
let $columns = get(columns)
let sourceIdx = $columns.findIndex(x => x.name === sourceColumn)
let targetIdx = $columns.findIndex(x => x.name === targetColumn)
targetIdx++
@ -110,9 +112,12 @@ export const deriveStores = context => {
// Remove event handlers
document.removeEventListener("mousemove", onReorderMouseMove)
document.removeEventListener("mouseup", stopReordering)
// Persist changes
await saveOrderChanges()
}
const moveColumnLeft = column => {
const moveColumnLeft = async column => {
const $columns = get(columns)
const sourceIdx = $columns.findIndex(x => x.name === column)
if (sourceIdx === 0) {
@ -124,9 +129,12 @@ export const deriveStores = context => {
state[sourceIdx - 1] = tmp
return state.slice()
})
// Persist changes
await saveOrderChanges()
}
const moveColumnRight = column => {
const moveColumnRight = async column => {
const $columns = get(columns)
const sourceIdx = $columns.findIndex(x => x.name === column)
if (sourceIdx === $columns.length - 1) {
@ -138,6 +146,20 @@ export const deriveStores = context => {
state[sourceIdx + 1] = tmp
return state.slice()
})
// Persist changes
await saveOrderChanges()
}
// Saves order changes as part of table metadata
const saveOrderChanges = async () => {
const $table = cloneDeep(get(table))
const $columns = get(columns)
$columns.forEach(column => {
$table.schema[column.name].order = column.order
})
const newTable = await API.saveTable($table)
table.set(newTable)
}
return {

View file

@ -1,5 +1,6 @@
import { writable, get, derived } from "svelte/store"
import { DefaultColumnWidth } from "./columns"
import { cloneDeep } from "lodash/fp"
export const MinColumnWidth = 100
@ -22,7 +23,7 @@ export const createStores = () => {
}
export const deriveStores = context => {
const { resize, columns, stickyColumn, ui } = context
const { resize, columns, stickyColumn, ui, table, API, rows } = context
// Starts resizing a certain column
const startResizing = (column, e) => {
@ -83,14 +84,21 @@ export const deriveStores = context => {
}
// Stop resizing any columns
const stopResizing = () => {
const stopResizing = async () => {
// Reset state
const $resize = get(resize)
resize.set(initialState)
document.removeEventListener("mousemove", onResizeMouseMove)
document.removeEventListener("mouseup", stopResizing)
// Persist width if it changed
if ($resize.width !== $resize.initialWidth) {
await saveNewColumnWidth($resize.column, $resize.width)
}
}
// Resets a column size back to default
const resetSize = column => {
const resetSize = async column => {
let columnIdx = get(columns).findIndex(col => col.name === column.name)
if (columnIdx === -1) {
stickyColumn.update(state => ({
@ -103,6 +111,23 @@ export const deriveStores = context => {
return [...state]
})
}
await saveNewColumnWidth(column.name, DefaultColumnWidth)
}
// Saves a new column width as part of table metadata
const saveNewColumnWidth = async (columnName, width) => {
const $table = get(table)
const newDefinition = await API.saveTable({
...$table,
schema: {
...$table.schema,
[columnName]: {
...$table.schema[columnName],
width,
},
},
})
table.set(newDefinition)
}
return {

View file

@ -115,6 +115,8 @@ export const deriveStores = context => {
// Reset scroll state when data changes
if (!get(instanceLoaded)) {
table.set($fetch.definition)
// Reset both top and left for a new table ID
instanceLoaded.set(true)
scroll.set({ top: 0, left: 0 })
@ -123,9 +125,6 @@ export const deriveStores = context => {
scroll.update(state => ({ ...state, top: 0 }))
}
// Update table definition
table.set($fetch.definition)
// Process new rows
handleNewRows($fetch.rows, resetRows)
@ -385,7 +384,8 @@ export const deriveStores = context => {
// Refreshes the schema of the data fetch subscription
const refreshTableDefinition = async () => {
return await get(fetch)?.refreshDefinition()
const definition = await API.fetchTableDefinition(get(tableId))
table.set(definition)
}
// Checks if we have a row with a certain ID