Refactor stores and make state more modular
This commit is contained in:
parent
b82e7582db
commit
37393c4e2a
|
@ -20,10 +20,6 @@
|
|||
// Deletion callback when confirmed
|
||||
const performDeletion = async () => {
|
||||
await rows.actions.deleteRows(rowsToDelete)
|
||||
|
||||
// Refresh state
|
||||
$selectedCellId = null
|
||||
$selectedRows = {}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
import { createRowsStore } from "./stores/rows"
|
||||
import { createColumnsStores } from "./stores/columns"
|
||||
import { createScrollStores } from "./stores/scroll"
|
||||
import { createBoundsStores } from "./stores/bounds"
|
||||
import { createInterfaceStores } from "./stores/interface"
|
||||
import DeleteButton from "./DeleteButton.svelte"
|
||||
import SheetBody from "./SheetBody.svelte"
|
||||
import SheetRow from "./SheetRow.svelte"
|
||||
|
@ -38,42 +40,23 @@
|
|||
allowAddColumns,
|
||||
allowSelectRows,
|
||||
})
|
||||
const selectedCellId = writable()
|
||||
const selectedRows = writable({})
|
||||
const hoveredRowId = writable()
|
||||
const scroll = writable({
|
||||
left: 0,
|
||||
top: 0,
|
||||
})
|
||||
const bounds = writable({
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
})
|
||||
|
||||
// Build up spreadsheet context and additional stores
|
||||
// Build up spreadsheet context
|
||||
// Stores are listed in order of dependency on each other
|
||||
let context = {
|
||||
API: API || createAPIClient(),
|
||||
rand,
|
||||
selectedCellId,
|
||||
selectedRows,
|
||||
cellHeight,
|
||||
bounds,
|
||||
scroll,
|
||||
hoveredRowId,
|
||||
config,
|
||||
dispatch,
|
||||
}
|
||||
const { rows, schema } = createRowsStore(context)
|
||||
context = { ...context, rows, schema }
|
||||
const { columns, stickyColumn } = createColumnsStores(context)
|
||||
context = { ...context, columns, stickyColumn }
|
||||
context = { ...context, ...createRowsStore(context) }
|
||||
context = { ...context, ...createColumnsStores(context) }
|
||||
context = { ...context, ...createBoundsStores(context) }
|
||||
context = { ...context, ...createScrollStores(context) }
|
||||
const { visibleRows, visibleColumns } = createViewportStores(context)
|
||||
context = { ...context, visibleRows, visibleColumns }
|
||||
const { reorder } = createReorderStores(context)
|
||||
context = { ...context, reorder }
|
||||
context = { ...context, ...createViewportStores(context) }
|
||||
context = { ...context, ...createReorderStores(context) }
|
||||
context = { ...context, ...createInterfaceStores(context) }
|
||||
|
||||
// Keep config store up to date
|
||||
$: config.set({
|
||||
|
@ -94,14 +77,7 @@
|
|||
<StickyColumn />
|
||||
<div class="sheet-main">
|
||||
<HeaderRow />
|
||||
<SheetBody>
|
||||
{#each $visibleRows as row}
|
||||
<SheetRow {row} />
|
||||
{/each}
|
||||
{#if allowAddRows}
|
||||
<NewRow />
|
||||
{/if}
|
||||
</SheetBody>
|
||||
<SheetBody />
|
||||
</div>
|
||||
<DeleteButton />
|
||||
<ResizeOverlay />
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
<script>
|
||||
import { getContext, onMount } from "svelte"
|
||||
import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
|
||||
import NewRow from "./NewRow.svelte"
|
||||
import SheetRow from "./SheetRow.svelte"
|
||||
|
||||
const { selectedCellId, bounds } = getContext("spreadsheet")
|
||||
const { selectedCellId, bounds, visibleRows, config } =
|
||||
getContext("spreadsheet")
|
||||
|
||||
let ref
|
||||
|
||||
|
@ -24,7 +27,12 @@
|
|||
on:click|self={() => ($selectedCellId = null)}
|
||||
>
|
||||
<SheetScrollWrapper>
|
||||
<slot />
|
||||
{#each $visibleRows as row}
|
||||
<SheetRow {row} />
|
||||
{/each}
|
||||
{#if $config.allowAddRows}
|
||||
<NewRow />
|
||||
{/if}
|
||||
</SheetScrollWrapper>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -37,10 +37,16 @@
|
|||
}
|
||||
|
||||
const selectRow = id => {
|
||||
selectedRows.update(state => ({
|
||||
...state,
|
||||
[id]: !state[id],
|
||||
}))
|
||||
selectedRows.update(state => {
|
||||
let newState = {
|
||||
...state,
|
||||
[id]: !state[id],
|
||||
}
|
||||
if (!newState[id]) {
|
||||
delete newState[id]
|
||||
}
|
||||
return newState
|
||||
})
|
||||
}
|
||||
|
||||
const addRow = async field => {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import { writable } from "svelte/store"
|
||||
|
||||
export const createBoundsStores = () => {
|
||||
const bounds = writable({
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
})
|
||||
return { bounds }
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { writable, get } from "svelte/store"
|
||||
|
||||
export const createInterfaceStores = context => {
|
||||
const { rows } = context
|
||||
const selectedCellId = writable(null)
|
||||
const selectedRows = writable({})
|
||||
const hoveredRowId = writable(null)
|
||||
|
||||
// Ensure we clear invalid rows from state if they disappear
|
||||
rows.subscribe($rows => {
|
||||
const $selectedCellId = get(selectedCellId)
|
||||
const $selectedRows = get(selectedRows)
|
||||
const $hoveredRowId = get(hoveredRowId)
|
||||
|
||||
// Check selected cell
|
||||
const selectedRowId = $selectedCellId?.split("-")[0]
|
||||
if (selectedRowId && !$rows.find(row => row._id === selectedRowId)) {
|
||||
selectedCellId.set(null)
|
||||
}
|
||||
|
||||
// Check hovered row
|
||||
if ($hoveredRowId && !$rows.find(row => row._id === $hoveredRowId)) {
|
||||
hoveredRowId.set(null)
|
||||
}
|
||||
|
||||
// Check selected rows
|
||||
let newSelectedRows = { ...$selectedRows }
|
||||
let selectedRowsNeedsUpdate = false
|
||||
const selectedIds = Object.keys($selectedRows)
|
||||
for (let i = 0; i < selectedIds.length; i++) {
|
||||
if (!$rows.find(row => row._id === selectedIds[i])) {
|
||||
delete newSelectedRows[selectedIds[i]]
|
||||
selectedRowsNeedsUpdate = true
|
||||
}
|
||||
}
|
||||
if (selectedRowsNeedsUpdate) {
|
||||
selectedRows.set(newSelectedRows)
|
||||
}
|
||||
})
|
||||
|
||||
return { selectedCellId, selectedRows, hoveredRowId }
|
||||
}
|
|
@ -4,7 +4,7 @@ import { fetchData } from "../../../fetch/fetchData"
|
|||
import { notifications } from "@budibase/bbui"
|
||||
|
||||
export const createRowsStore = context => {
|
||||
const { config, API, scroll } = context
|
||||
const { config, API } = context
|
||||
const tableId = derived(config, $config => $config.tableId)
|
||||
const filter = derived(config, $config => $config.filter)
|
||||
|
||||
|
@ -64,9 +64,6 @@ export const createRowsStore = context => {
|
|||
newSchema[primaryDisplay].primaryDisplay = true
|
||||
}
|
||||
schema.set(newSchema)
|
||||
|
||||
// Reset scroll state for fresh dataset
|
||||
scroll.set({ left: 0, top: 0 })
|
||||
}
|
||||
|
||||
// Process new rows
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { derived, get } from "svelte/store"
|
||||
import { derived, get, writable } from "svelte/store"
|
||||
|
||||
export const createScrollStores = context => {
|
||||
const { scroll, rows, columns, stickyColumn, bounds, cellHeight } = context
|
||||
const { rows, columns, stickyColumn, bounds, cellHeight } = context
|
||||
const padding = 180
|
||||
const scroll = writable({
|
||||
left: 0,
|
||||
top: 0,
|
||||
})
|
||||
|
||||
// Memoize store primitives
|
||||
const scrollTop = derived(scroll, $scroll => $scroll.top)
|
||||
|
@ -77,6 +81,7 @@ export const createScrollStores = context => {
|
|||
})
|
||||
|
||||
return {
|
||||
scroll,
|
||||
contentHeight,
|
||||
contentWidth,
|
||||
maxScrollTop,
|
||||
|
|
Loading…
Reference in New Issue