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

View File

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

View File

@ -1,5 +1,6 @@
import { writable, get, derived } from "svelte/store" import { writable, get, derived } from "svelte/store"
import { DefaultColumnWidth } from "./columns" import { DefaultColumnWidth } from "./columns"
import { cloneDeep } from "lodash/fp"
export const MinColumnWidth = 100 export const MinColumnWidth = 100
@ -22,7 +23,7 @@ export const createStores = () => {
} }
export const deriveStores = context => { export const deriveStores = context => {
const { resize, columns, stickyColumn, ui } = context const { resize, columns, stickyColumn, ui, table, API, rows } = context
// Starts resizing a certain column // Starts resizing a certain column
const startResizing = (column, e) => { const startResizing = (column, e) => {
@ -83,14 +84,21 @@ export const deriveStores = context => {
} }
// Stop resizing any columns // Stop resizing any columns
const stopResizing = () => { const stopResizing = async () => {
// Reset state
const $resize = get(resize)
resize.set(initialState) resize.set(initialState)
document.removeEventListener("mousemove", onResizeMouseMove) document.removeEventListener("mousemove", onResizeMouseMove)
document.removeEventListener("mouseup", stopResizing) 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 // Resets a column size back to default
const resetSize = column => { const resetSize = async column => {
let columnIdx = get(columns).findIndex(col => col.name === column.name) let columnIdx = get(columns).findIndex(col => col.name === column.name)
if (columnIdx === -1) { if (columnIdx === -1) {
stickyColumn.update(state => ({ stickyColumn.update(state => ({
@ -103,6 +111,23 @@ export const deriveStores = context => {
return [...state] 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 { return {

View File

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