Refactor stores
This commit is contained in:
parent
60d86c8b14
commit
b094f0bc31
|
@ -11,7 +11,7 @@
|
||||||
menu,
|
menu,
|
||||||
config,
|
config,
|
||||||
validation,
|
validation,
|
||||||
cellSelection,
|
selectedCells,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
export let highlighted
|
export let highlighted
|
||||||
|
@ -28,14 +28,12 @@
|
||||||
export let contentLines = 1
|
export let contentLines = 1
|
||||||
export let hidden = false
|
export let hidden = false
|
||||||
export let isSelectingCells = false
|
export let isSelectingCells = false
|
||||||
export let selectedCells = {}
|
export let cellSelected = false
|
||||||
|
|
||||||
const emptyError = writable(null)
|
const emptyError = writable(null)
|
||||||
|
|
||||||
let api
|
let api
|
||||||
|
|
||||||
$: cellSelected = selectedCells[cellId]
|
|
||||||
|
|
||||||
// Get the error for this cell if the cell is focused or selected
|
// Get the error for this cell if the cell is focused or selected
|
||||||
$: error = getErrorStore(rowFocused || cellSelected, cellId)
|
$: error = getErrorStore(rowFocused || cellSelected, cellId)
|
||||||
|
|
||||||
|
@ -89,16 +87,16 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// focusedCellId.set(cellId)
|
// focusedCellId.set(cellId)
|
||||||
cellSelection.actions.start(cellId)
|
selectedCells.actions.start(cellId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSelection = e => {
|
const updateSelection = e => {
|
||||||
focusedCellId.set(null)
|
focusedCellId.set(null)
|
||||||
cellSelection.actions.update(cellId)
|
selectedCells.actions.update(cellId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const stopSelection = e => {
|
const stopSelection = e => {
|
||||||
cellSelection.actions.stop()
|
selectedCells.actions.stop()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
{row}
|
{row}
|
||||||
{rowFocused}
|
{rowFocused}
|
||||||
{rowSelected}
|
{rowSelected}
|
||||||
|
cellSelected={$selectedCells[cellId]}
|
||||||
highlighted={rowHovered || rowFocused || reorderSource === column.name}
|
highlighted={rowHovered || rowFocused || reorderSource === column.name}
|
||||||
rowIdx={row.__idx}
|
rowIdx={row.__idx}
|
||||||
topRow={top}
|
topRow={top}
|
||||||
|
@ -57,7 +58,6 @@
|
||||||
contentLines={$contentLines}
|
contentLines={$contentLines}
|
||||||
hidden={!$columnRenderMap[column.name]}
|
hidden={!$columnRenderMap[column.name]}
|
||||||
isSelectingCells={$isSelectingCells}
|
isSelectingCells={$isSelectingCells}
|
||||||
selectedCells={$selectedCells}
|
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
const {
|
const {
|
||||||
rowHeight,
|
rowHeight,
|
||||||
scroll,
|
scroll,
|
||||||
focusedCellId,
|
ui,
|
||||||
renderedRows,
|
renderedRows,
|
||||||
maxScrollTop,
|
maxScrollTop,
|
||||||
maxScrollLeft,
|
maxScrollLeft,
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
on:wheel={attachHandlers ? handleWheel : null}
|
on:wheel={attachHandlers ? handleWheel : null}
|
||||||
on:touchstart={attachHandlers ? handleTouchStart : null}
|
on:touchstart={attachHandlers ? handleTouchStart : null}
|
||||||
on:touchmove={attachHandlers ? handleTouchMove : null}
|
on:touchmove={attachHandlers ? handleTouchMove : null}
|
||||||
on:click|self={() => ($focusedCellId = null)}
|
on:click|self={ui.actions.blur}
|
||||||
>
|
>
|
||||||
<div {style} class="inner" bind:this={ref}>
|
<div {style} class="inner" bind:this={ref}>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
{cellId}
|
{cellId}
|
||||||
{rowFocused}
|
{rowFocused}
|
||||||
{rowSelected}
|
{rowSelected}
|
||||||
|
cellSelected={$selectedCells[cellId]}
|
||||||
highlighted={rowHovered || rowFocused}
|
highlighted={rowHovered || rowFocused}
|
||||||
rowIdx={row.__idx}
|
rowIdx={row.__idx}
|
||||||
topRow={idx === 0}
|
topRow={idx === 0}
|
||||||
|
@ -100,7 +101,6 @@
|
||||||
column={$stickyColumn}
|
column={$stickyColumn}
|
||||||
contentLines={$contentLines}
|
contentLines={$contentLines}
|
||||||
isSelectingCells={$isSelectingCells}
|
isSelectingCells={$isSelectingCells}
|
||||||
selectedCells={$selectedCells}
|
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,7 +20,6 @@ import * as Table from "./datasources/table"
|
||||||
import * as ViewV2 from "./datasources/viewV2"
|
import * as ViewV2 from "./datasources/viewV2"
|
||||||
import * as NonPlus from "./datasources/nonPlus"
|
import * as NonPlus from "./datasources/nonPlus"
|
||||||
import * as Cache from "./cache"
|
import * as Cache from "./cache"
|
||||||
import * as Selection from "./selection"
|
|
||||||
|
|
||||||
const DependencyOrderedStores = [
|
const DependencyOrderedStores = [
|
||||||
Sort,
|
Sort,
|
||||||
|
@ -41,7 +40,6 @@ const DependencyOrderedStores = [
|
||||||
Users,
|
Users,
|
||||||
Menu,
|
Menu,
|
||||||
Pagination,
|
Pagination,
|
||||||
Selection,
|
|
||||||
Clipboard,
|
Clipboard,
|
||||||
Config,
|
Config,
|
||||||
Notifications,
|
Notifications,
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
import { derived, writable, get } from "svelte/store"
|
|
||||||
import { getCellID, parseCellID } from "../lib/utils"
|
|
||||||
|
|
||||||
export const createStores = () => {
|
|
||||||
const cellSelection = writable({
|
|
||||||
active: false,
|
|
||||||
sourceCellId: null,
|
|
||||||
targetCellId: null,
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
cellSelection,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const deriveStores = context => {
|
|
||||||
const {
|
|
||||||
cellSelection,
|
|
||||||
rowLookupMap,
|
|
||||||
columnLookupMap,
|
|
||||||
rows,
|
|
||||||
allVisibleColumns,
|
|
||||||
} = context
|
|
||||||
|
|
||||||
const isSelectingCells = derived(cellSelection, $cellSelection => {
|
|
||||||
return $cellSelection.active
|
|
||||||
})
|
|
||||||
|
|
||||||
const selectedCells = derived(
|
|
||||||
[cellSelection, rowLookupMap, columnLookupMap],
|
|
||||||
([$cellSelection, $rowLookupMap, $columnLookupMap]) => {
|
|
||||||
const { sourceCellId, targetCellId } = $cellSelection
|
|
||||||
if (!sourceCellId || !targetCellId || sourceCellId === targetCellId) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
const $rows = get(rows)
|
|
||||||
const $allVisibleColumns = get(allVisibleColumns)
|
|
||||||
|
|
||||||
// Get source and target row and column indices
|
|
||||||
const sourceInfo = parseCellID(sourceCellId)
|
|
||||||
const targetInfo = parseCellID(targetCellId)
|
|
||||||
|
|
||||||
// Row indices
|
|
||||||
const sourceRowIndex = $rowLookupMap[sourceInfo.id]
|
|
||||||
const targetRowIndex = $rowLookupMap[targetInfo.id]
|
|
||||||
const lowerRowIndex = Math.min(sourceRowIndex, targetRowIndex)
|
|
||||||
const upperRowIndex = Math.max(sourceRowIndex, targetRowIndex)
|
|
||||||
|
|
||||||
// Column indices
|
|
||||||
const sourceColIndex = $columnLookupMap[sourceInfo.field]
|
|
||||||
const targetColIndex = $columnLookupMap[targetInfo.field]
|
|
||||||
const lowerColIndex = Math.min(sourceColIndex, targetColIndex)
|
|
||||||
const upperColIndex = Math.max(sourceColIndex, targetColIndex)
|
|
||||||
|
|
||||||
// Build map of all cells inside these bounds
|
|
||||||
let map = {}
|
|
||||||
let rowId, colName, cellId
|
|
||||||
for (let rowIdx = lowerRowIndex; rowIdx <= upperRowIndex; rowIdx++) {
|
|
||||||
for (let colIdx = lowerColIndex; colIdx <= upperColIndex; colIdx++) {
|
|
||||||
rowId = $rows[rowIdx]._id
|
|
||||||
colName = $allVisibleColumns[colIdx].name
|
|
||||||
cellId = getCellID(rowId, colName)
|
|
||||||
map[cellId] = { rowIdx, colIdx }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const selectedCellCount = derived(selectedCells, $selectedCells => {
|
|
||||||
return Object.keys($selectedCells).length
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
isSelectingCells,
|
|
||||||
selectedCells,
|
|
||||||
selectedCellCount,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createActions = context => {
|
|
||||||
const { cellSelection } = context
|
|
||||||
|
|
||||||
const startCellSelection = sourceCellId => {
|
|
||||||
cellSelection.set({
|
|
||||||
active: true,
|
|
||||||
sourceCellId,
|
|
||||||
targetCellId: sourceCellId,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateCellSelection = targetCellId => {
|
|
||||||
cellSelection.update(state => ({
|
|
||||||
...state,
|
|
||||||
targetCellId,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const stopCellSelection = () => {
|
|
||||||
cellSelection.update(state => ({
|
|
||||||
...state,
|
|
||||||
active: false,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearCellSelection = () => {
|
|
||||||
cellSelection.set({
|
|
||||||
active: false,
|
|
||||||
sourceCellId: null,
|
|
||||||
targetCellId: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
cellSelection: {
|
|
||||||
...cellSelection,
|
|
||||||
actions: {
|
|
||||||
start: startCellSelection,
|
|
||||||
update: updateCellSelection,
|
|
||||||
stop: stopCellSelection,
|
|
||||||
clear: clearCellSelection,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialise = context => {
|
|
||||||
const { selectedCellCount, selectedRowCount, selectedRows } = context
|
|
||||||
|
|
||||||
selectedCellCount.subscribe($selectedCellCount => {
|
|
||||||
if ($selectedCellCount && get(selectedRowCount)) {
|
|
||||||
selectedRows.set({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
MediumRowHeight,
|
MediumRowHeight,
|
||||||
NewRowID,
|
NewRowID,
|
||||||
} from "../lib/constants"
|
} from "../lib/constants"
|
||||||
import { parseCellID } from "../lib/utils"
|
import { getCellID, parseCellID } from "../lib/utils"
|
||||||
|
|
||||||
export const createStores = context => {
|
export const createStores = context => {
|
||||||
const { props } = context
|
const { props } = context
|
||||||
|
@ -22,6 +22,11 @@ export const createStores = context => {
|
||||||
const keyboardBlocked = writable(false)
|
const keyboardBlocked = writable(false)
|
||||||
const isDragging = writable(false)
|
const isDragging = writable(false)
|
||||||
const buttonColumnWidth = writable(0)
|
const buttonColumnWidth = writable(0)
|
||||||
|
const cellSelection = writable({
|
||||||
|
active: false,
|
||||||
|
sourceCellId: null,
|
||||||
|
targetCellId: null,
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
focusedCellId,
|
focusedCellId,
|
||||||
|
@ -35,6 +40,7 @@ export const createStores = context => {
|
||||||
isDragging,
|
isDragging,
|
||||||
buttonColumnWidth,
|
buttonColumnWidth,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
|
cellSelection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +53,9 @@ export const deriveStores = context => {
|
||||||
stickyColumn,
|
stickyColumn,
|
||||||
width,
|
width,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
|
cellSelection,
|
||||||
|
columnLookupMap,
|
||||||
|
allVisibleColumns,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Derive the current focused row ID
|
// Derive the current focused row ID
|
||||||
|
@ -89,12 +98,67 @@ export const deriveStores = context => {
|
||||||
return Object.keys($selectedRows).length
|
return Object.keys($selectedRows).length
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Derive whether or not we're actively selecting cells
|
||||||
|
const isSelectingCells = derived(cellSelection, $cellSelection => {
|
||||||
|
return $cellSelection.active
|
||||||
|
})
|
||||||
|
|
||||||
|
// Derive the full extent of all selected cells
|
||||||
|
const selectedCells = derived(
|
||||||
|
[cellSelection, rowLookupMap, columnLookupMap],
|
||||||
|
([$cellSelection, $rowLookupMap, $columnLookupMap]) => {
|
||||||
|
const { sourceCellId, targetCellId } = $cellSelection
|
||||||
|
if (!sourceCellId || !targetCellId || sourceCellId === targetCellId) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
const $rows = get(rows)
|
||||||
|
const $allVisibleColumns = get(allVisibleColumns)
|
||||||
|
|
||||||
|
// Get source and target row and column indices
|
||||||
|
const sourceInfo = parseCellID(sourceCellId)
|
||||||
|
const targetInfo = parseCellID(targetCellId)
|
||||||
|
|
||||||
|
// Row indices
|
||||||
|
const sourceRowIndex = $rowLookupMap[sourceInfo.id]
|
||||||
|
const targetRowIndex = $rowLookupMap[targetInfo.id]
|
||||||
|
const lowerRowIndex = Math.min(sourceRowIndex, targetRowIndex)
|
||||||
|
const upperRowIndex = Math.max(sourceRowIndex, targetRowIndex)
|
||||||
|
|
||||||
|
// Column indices
|
||||||
|
const sourceColIndex = $columnLookupMap[sourceInfo.field]
|
||||||
|
const targetColIndex = $columnLookupMap[targetInfo.field]
|
||||||
|
const lowerColIndex = Math.min(sourceColIndex, targetColIndex)
|
||||||
|
const upperColIndex = Math.max(sourceColIndex, targetColIndex)
|
||||||
|
|
||||||
|
// Build map of all cells inside these bounds
|
||||||
|
let map = {}
|
||||||
|
let rowId, colName, cellId
|
||||||
|
for (let rowIdx = lowerRowIndex; rowIdx <= upperRowIndex; rowIdx++) {
|
||||||
|
for (let colIdx = lowerColIndex; colIdx <= upperColIndex; colIdx++) {
|
||||||
|
rowId = $rows[rowIdx]._id
|
||||||
|
colName = $allVisibleColumns[colIdx].name
|
||||||
|
cellId = getCellID(rowId, colName)
|
||||||
|
map[cellId] = { rowIdx, colIdx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Derive the count of the selected cells
|
||||||
|
const selectedCellCount = derived(selectedCells, $selectedCells => {
|
||||||
|
return Object.keys($selectedCells).length
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
focusedRowId,
|
focusedRowId,
|
||||||
focusedRow,
|
focusedRow,
|
||||||
contentLines,
|
contentLines,
|
||||||
compact,
|
compact,
|
||||||
selectedRowCount,
|
selectedRowCount,
|
||||||
|
isSelectingCells,
|
||||||
|
selectedCells,
|
||||||
|
selectedCellCount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +170,8 @@ export const createActions = context => {
|
||||||
rowLookupMap,
|
rowLookupMap,
|
||||||
rows,
|
rows,
|
||||||
selectedRowCount,
|
selectedRowCount,
|
||||||
|
cellSelection,
|
||||||
|
selectedCells,
|
||||||
} = context
|
} = context
|
||||||
// Keep the last selected index to use with bulk selection
|
// Keep the last selected index to use with bulk selection
|
||||||
let lastSelectedIndex = null
|
let lastSelectedIndex = null
|
||||||
|
@ -114,6 +180,7 @@ export const createActions = context => {
|
||||||
const blur = () => {
|
const blur = () => {
|
||||||
focusedCellId.set(null)
|
focusedCellId.set(null)
|
||||||
hoveredRowId.set(null)
|
hoveredRowId.set(null)
|
||||||
|
clearCellSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles whether a certain row ID is selected or not
|
// Toggles whether a certain row ID is selected or not
|
||||||
|
@ -159,6 +226,36 @@ export const createActions = context => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startCellSelection = sourceCellId => {
|
||||||
|
cellSelection.set({
|
||||||
|
active: true,
|
||||||
|
sourceCellId,
|
||||||
|
targetCellId: sourceCellId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCellSelection = targetCellId => {
|
||||||
|
cellSelection.update(state => ({
|
||||||
|
...state,
|
||||||
|
targetCellId,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopCellSelection = () => {
|
||||||
|
cellSelection.update(state => ({
|
||||||
|
...state,
|
||||||
|
active: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearCellSelection = () => {
|
||||||
|
cellSelection.set({
|
||||||
|
active: false,
|
||||||
|
sourceCellId: null,
|
||||||
|
targetCellId: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ui: {
|
ui: {
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -172,6 +269,15 @@ export const createActions = context => {
|
||||||
bulkSelectRows,
|
bulkSelectRows,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
selectedCells: {
|
||||||
|
...selectedCells,
|
||||||
|
actions: {
|
||||||
|
start: startCellSelection,
|
||||||
|
update: updateCellSelection,
|
||||||
|
stop: stopCellSelection,
|
||||||
|
clear: clearCellSelection,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +295,8 @@ export const initialise = context => {
|
||||||
fixedRowHeight,
|
fixedRowHeight,
|
||||||
selectedRowCount,
|
selectedRowCount,
|
||||||
menu,
|
menu,
|
||||||
cellSelection,
|
|
||||||
selectedCellCount,
|
selectedCellCount,
|
||||||
|
selectedCells,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Ensure we clear invalid rows from state if they disappear
|
// Ensure we clear invalid rows from state if they disappear
|
||||||
|
@ -254,7 +360,7 @@ export const initialise = context => {
|
||||||
|
|
||||||
// Clear cell selection when focusing a cell
|
// Clear cell selection when focusing a cell
|
||||||
if (id && get(selectedCellCount)) {
|
if (id && get(selectedCellCount)) {
|
||||||
cellSelection.actions.clear()
|
selectedCells.actions.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the menu if it was open
|
// Close the menu if it was open
|
||||||
|
@ -284,8 +390,15 @@ export const initialise = context => {
|
||||||
focusedCellId.set(null)
|
focusedCellId.set(null)
|
||||||
}
|
}
|
||||||
if (get(selectedCellCount)) {
|
if (get(selectedCellCount)) {
|
||||||
cellSelection.actions.clear()
|
selectedCells.actions.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Clear selected rows when selecting cells
|
||||||
|
selectedCellCount.subscribe($selectedCellCount => {
|
||||||
|
if ($selectedCellCount && get(selectedRowCount)) {
|
||||||
|
selectedRows.set({})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue