Initial typing

This commit is contained in:
Adria Navarro 2024-12-27 09:23:53 +01:00
parent d96b8c77fa
commit b67966a9fb
3 changed files with 49 additions and 19 deletions

View File

@ -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] = {}
} }

View File

@ -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 => {

View File

@ -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>