Initial typing
This commit is contained in:
parent
d96b8c77fa
commit
b67966a9fb
|
@ -1,9 +1,30 @@
|
||||||
import { derived, writable, get } from "svelte/store"
|
import { derived, writable, get, Writable, Readable } from "svelte/store"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { parseCellID, getCellID } from "../lib/utils"
|
import { parseCellID, getCellID } from "../lib/utils"
|
||||||
import { NewRowID } from "../lib/constants"
|
import { NewRowID } from "../lib/constants"
|
||||||
|
import { Store as StoreContext } from "."
|
||||||
|
|
||||||
export const createStores = () => {
|
interface ClipboardStore {
|
||||||
|
clipboard: Writable<{ value: any; multiCellCopy: boolean }>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClipboardDerivedStore {
|
||||||
|
copyAllowed: Readable<boolean>
|
||||||
|
pasteAllowed: Readable<boolean>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClipboardActions {
|
||||||
|
clipboard: ClipboardStore["clipboard"] & {
|
||||||
|
actions: {
|
||||||
|
copy: any
|
||||||
|
paste: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Store = ClipboardStore & ClipboardDerivedStore & ClipboardActions
|
||||||
|
|
||||||
|
export const createStores = (): ClipboardStore => {
|
||||||
const clipboard = writable({
|
const clipboard = writable({
|
||||||
value: null,
|
value: null,
|
||||||
multiCellCopy: false,
|
multiCellCopy: false,
|
||||||
|
@ -13,7 +34,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const deriveStores = (context: StoreContext): ClipboardDerivedStore => {
|
||||||
const { clipboard, focusedCellAPI, selectedCellCount, config, focusedRowId } =
|
const { clipboard, focusedCellAPI, selectedCellCount, config, focusedRowId } =
|
||||||
context
|
context
|
||||||
|
|
||||||
|
@ -60,7 +81,7 @@ export const deriveStores = context => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createActions = context => {
|
export const createActions = (context: StoreContext): ClipboardActions => {
|
||||||
const {
|
const {
|
||||||
clipboard,
|
clipboard,
|
||||||
focusedCellAPI,
|
focusedCellAPI,
|
||||||
|
@ -92,11 +113,11 @@ export const createActions = context => {
|
||||||
const $rowChangeCache = get(rowChangeCache)
|
const $rowChangeCache = get(rowChangeCache)
|
||||||
|
|
||||||
// Extract value of each selected cell, accounting for the change cache
|
// Extract value of each selected cell, accounting for the change cache
|
||||||
let value = []
|
const value = []
|
||||||
for (let row of $selectedCells) {
|
for (const row of $selectedCells) {
|
||||||
const rowValues = []
|
const rowValues = []
|
||||||
for (let cellId of row) {
|
for (const cellId of row) {
|
||||||
const { rowId, field } = parseCellID(cellId)
|
const { rowId = "", field = "" } = parseCellID(cellId)
|
||||||
const row = {
|
const row = {
|
||||||
...$rowLookupMap[rowId],
|
...$rowLookupMap[rowId],
|
||||||
...$rowChangeCache[rowId],
|
...$rowChangeCache[rowId],
|
||||||
|
@ -113,7 +134,7 @@ export const createActions = context => {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Single value to copy
|
// Single value to copy
|
||||||
const value = $focusedCellAPI.getValue()
|
const value = $focusedCellAPI?.getValue()
|
||||||
clipboard.set({
|
clipboard.set({
|
||||||
value,
|
value,
|
||||||
multiCellCopy,
|
multiCellCopy,
|
||||||
|
@ -130,7 +151,7 @@ export const createActions = context => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pastes the previously copied value(s) into the selected cell(s)
|
// Pastes the previously copied value(s) into the selected cell(s)
|
||||||
const paste = async progressCallback => {
|
const paste = async (progressCallback: () => void) => {
|
||||||
if (!get(pasteAllowed)) {
|
if (!get(pasteAllowed)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -166,8 +187,8 @@ export const createActions = context => {
|
||||||
const { rowId, field } = parseCellID($focusedCellId)
|
const { rowId, field } = parseCellID($focusedCellId)
|
||||||
const $rowLookupMap = get(rowLookupMap)
|
const $rowLookupMap = get(rowLookupMap)
|
||||||
const $columnLookupMap = get(columnLookupMap)
|
const $columnLookupMap = get(columnLookupMap)
|
||||||
const rowIdx = $rowLookupMap[rowId].__idx
|
const rowIdx = $rowLookupMap[rowId!].__idx
|
||||||
const colIdx = $columnLookupMap[field].__idx
|
const colIdx = $columnLookupMap[field!].__idx || 0
|
||||||
|
|
||||||
// Get limits of how many rows and columns we're able to paste into
|
// Get limits of how many rows and columns we're able to paste into
|
||||||
const $rows = get(rows)
|
const $rows = get(rows)
|
||||||
|
@ -187,7 +208,7 @@ export const createActions = context => {
|
||||||
// Paste into target cell range
|
// Paste into target cell range
|
||||||
if (targetCellId === $focusedCellId) {
|
if (targetCellId === $focusedCellId) {
|
||||||
// Single cell edge case
|
// Single cell edge case
|
||||||
get(focusedCellAPI).setValue(value[0][0])
|
get(focusedCellAPI)?.setValue(value[0][0])
|
||||||
} else {
|
} else {
|
||||||
// Select the new cells to paste into, then paste
|
// Select the new cells to paste into, then paste
|
||||||
selectedCells.actions.selectRange($focusedCellId, targetCellId)
|
selectedCells.actions.selectRange($focusedCellId, targetCellId)
|
||||||
|
@ -201,13 +222,16 @@ export const createActions = context => {
|
||||||
await pasteIntoSelectedCells(newValue, progressCallback)
|
await pasteIntoSelectedCells(newValue, progressCallback)
|
||||||
} else {
|
} else {
|
||||||
// Single to single - just update the cell's value
|
// Single to single - just update the cell's value
|
||||||
get(focusedCellAPI).setValue(value)
|
get(focusedCellAPI)?.setValue(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paste the specified value into the currently selected cells
|
// Paste the specified value into the currently selected cells
|
||||||
const pasteIntoSelectedCells = async (value, progressCallback) => {
|
const pasteIntoSelectedCells = async (
|
||||||
|
value: string[][],
|
||||||
|
progressCallback: () => any
|
||||||
|
) => {
|
||||||
const $selectedCells = get(selectedCells)
|
const $selectedCells = get(selectedCells)
|
||||||
|
|
||||||
// Find the extent at which we can paste
|
// Find the extent at which we can paste
|
||||||
|
@ -215,11 +239,13 @@ export const createActions = context => {
|
||||||
const colExtent = Math.min(value[0].length, $selectedCells[0].length)
|
const colExtent = Math.min(value[0].length, $selectedCells[0].length)
|
||||||
|
|
||||||
// Build change map
|
// Build change map
|
||||||
let changeMap = {}
|
let changeMap: Record<string, Record<string, string>> = {}
|
||||||
for (let rowIdx = 0; rowIdx < rowExtent; rowIdx++) {
|
for (let rowIdx = 0; rowIdx < rowExtent; rowIdx++) {
|
||||||
for (let colIdx = 0; colIdx < colExtent; colIdx++) {
|
for (let colIdx = 0; colIdx < colExtent; colIdx++) {
|
||||||
const cellId = $selectedCells[rowIdx][colIdx]
|
const cellId = $selectedCells[rowIdx][colIdx]
|
||||||
const { rowId, field } = parseCellID(cellId)
|
let { rowId, field } = parseCellID(cellId)
|
||||||
|
rowId = rowId!
|
||||||
|
field = field!
|
||||||
if (!changeMap[rowId]) {
|
if (!changeMap[rowId]) {
|
||||||
changeMap[rowId] = {}
|
changeMap[rowId] = {}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Writable } from "svelte/store"
|
import { Readable, Writable } from "svelte/store"
|
||||||
import type { APIClient } from "../../../api/types"
|
import type { APIClient } from "../../../api/types"
|
||||||
|
|
||||||
import * as Bounds from "./bounds"
|
import * as Bounds from "./bounds"
|
||||||
|
@ -65,7 +65,8 @@ export type Store = BaseStore &
|
||||||
Users.Store &
|
Users.Store &
|
||||||
Menu.Store &
|
Menu.Store &
|
||||||
Filter.Store &
|
Filter.Store &
|
||||||
UI.Store & {
|
UI.Store &
|
||||||
|
Clipboard.Store & {
|
||||||
// TODO while typing the rest of stores
|
// TODO while typing the rest of stores
|
||||||
fetch: Writable<any>
|
fetch: Writable<any>
|
||||||
sort: Writable<any>
|
sort: Writable<any>
|
||||||
|
@ -83,6 +84,7 @@ export type Store = BaseStore &
|
||||||
rowLookupMap: Writable<any>
|
rowLookupMap: Writable<any>
|
||||||
width: Writable<number>
|
width: Writable<number>
|
||||||
fixedRowHeight: Writable<number>
|
fixedRowHeight: Writable<number>
|
||||||
|
rowChangeCache: Readable<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attachStores = (context: Store): Store => {
|
export const attachStores = (context: Store): Store => {
|
||||||
|
|
|
@ -13,6 +13,8 @@ export interface UIStore {
|
||||||
focusedCellId: Writable<string | null>
|
focusedCellId: Writable<string | null>
|
||||||
focusedCellAPI: Writable<{
|
focusedCellAPI: Writable<{
|
||||||
isReadonly: () => boolean
|
isReadonly: () => boolean
|
||||||
|
getValue: () => string
|
||||||
|
setValue: (val: string) => void
|
||||||
} | null>
|
} | null>
|
||||||
selectedRows: Writable<Record<string, boolean>>
|
selectedRows: Writable<Record<string, boolean>>
|
||||||
hoveredRowId: Writable<string | null>
|
hoveredRowId: Writable<string | null>
|
||||||
|
|
Loading…
Reference in New Issue