Remove copy/paste rows, remove move to start/end, improve copy/paste for cell values

This commit is contained in:
Andrew Kingston 2023-04-14 15:11:52 +01:00
parent ddc11ab88c
commit b1d227b65f
9 changed files with 93 additions and 54 deletions

View File

@ -16,7 +16,7 @@
export let column export let column
export let row export let row
export let cellId export let cellId
export let updateRow = rows.actions.updateRow export let updateValue = rows.actions.updateValue
export let invertX = false export let invertX = false
export let invertY = false export let invertY = false
@ -53,7 +53,7 @@
getValue: () => row[column.name], getValue: () => row[column.name],
setValue: value => { setValue: value => {
validation.actions.setError(cellId, null) validation.actions.setError(cellId, null)
updateRow(row._id, column.name, value) updateValue(row._id, column.name, value)
}, },
} }
</script> </script>

View File

@ -177,26 +177,12 @@
> >
Sort Z-A Sort Z-A
</MenuItem> </MenuItem>
<MenuItem
disabled={!canMoveLeft}
icon="ChevronDoubleLeft"
on:click={moveStart}
>
Move to start
</MenuItem>
<MenuItem disabled={!canMoveLeft} icon="ChevronLeft" on:click={moveLeft}> <MenuItem disabled={!canMoveLeft} icon="ChevronLeft" on:click={moveLeft}>
Move left Move left
</MenuItem> </MenuItem>
<MenuItem disabled={!canMoveRight} icon="ChevronRight" on:click={moveRight}> <MenuItem disabled={!canMoveRight} icon="ChevronRight" on:click={moveRight}>
Move right Move right
</MenuItem> </MenuItem>
<MenuItem
disabled={!canMoveRight}
icon="ChevronDoubleRight"
on:click={moveEnd}
>
Move to end
</MenuItem>
</Menu> </Menu>
</Popover> </Popover>

View File

@ -62,7 +62,7 @@
} }
} }
const updateRow = (rowId, columnName, val) => { const updateValue = (rowId, columnName, val) => {
touched = true touched = true
newRow[columnName] = val newRow[columnName] = val
} }
@ -112,7 +112,7 @@
focused={$focusedCellId === cellId} focused={$focusedCellId === cellId}
{rowFocused} {rowFocused}
width={$stickyColumn.width} width={$stickyColumn.width}
{updateRow} {updateValue}
rowIdx={0} rowIdx={0}
/> />
{/if} {/if}
@ -131,7 +131,7 @@
focused={$focusedCellId === cellId} focused={$focusedCellId === cellId}
{rowFocused} {rowFocused}
width={column.width} width={column.width}
{updateRow} {updateValue}
rowIdx={0} rowIdx={0}
/> />
{/key} {/key}

View File

@ -9,15 +9,15 @@
focusedRow, focusedRow,
stickyColumn, stickyColumn,
focusedCellAPI, focusedCellAPI,
clipboard,
} = getContext("sheet") } = getContext("sheet")
let copiedValue
// Global key listener which intercepts all key events // Global key listener which intercepts all key events
const handleKeyDown = e => { const handleKeyDown = e => {
// If nothing selected avoid processing further key presses // If nothing selected avoid processing further key presses
if (!$focusedCellId) { if (!$focusedCellId) {
if (e.key === "Tab") { if (e.key === "Tab") {
e.preventDefault()
focusFirstCell() focusFirstCell()
} }
return return
@ -46,10 +46,10 @@
if (e.metaKey || e.ctrlKey) { if (e.metaKey || e.ctrlKey) {
switch (e.key) { switch (e.key) {
case "c": case "c":
copy() clipboard.actions.copy()
break break
case "v": case "v":
paste() clipboard.actions.paste()
break break
} }
} else { } else {
@ -144,18 +144,6 @@
$focusedCellAPI?.focus?.() $focusedCellAPI?.focus?.()
} }
// Copies the value from the current cell
const copy = () => {
copiedValue = $focusedCellAPI?.getValue()
}
// Pastes the copied value
const paste = () => {
if (copiedValue != null) {
$focusedCellAPI?.setValue(copiedValue)
}
}
// Utils to identify a key code // Utils to identify a key code
const keyCodeIsNumber = keyCode => keyCode >= 48 && keyCode <= 57 const keyCodeIsNumber = keyCode => keyCode >= 48 && keyCode <= 57
const keyCodeIsLetter = keyCode => keyCode >= 65 && keyCode <= 90 const keyCodeIsLetter = keyCode => keyCode >= 65 && keyCode <= 90

View File

@ -10,6 +10,8 @@
focusedCellId, focusedCellId,
stickyColumn, stickyColumn,
config, config,
copiedCell,
clipboard,
} = getContext("sheet") } = getContext("sheet")
$: style = makeStyle($menu) $: style = makeStyle($menu)
@ -37,16 +39,35 @@
{#if $menu.visible} {#if $menu.visible}
<div class="menu" {style} use:clickOutside={() => menu.actions.close()}> <div class="menu" {style} use:clickOutside={() => menu.actions.close()}>
<Menu> <Menu>
<MenuItem
icon="Copy"
on:click={clipboard.actions.copyCell}
on:click={menu.actions.close}
>
Copy
</MenuItem>
<MenuItem
icon="Paste"
disabled={$copiedCell == null}
on:click={clipboard.actions.pasteCell}
on:click={menu.actions.close}
>
Paste
</MenuItem>
<MenuItem <MenuItem
icon="Delete" icon="Delete"
disabled={!$config.allowDeleteRows} disabled={!$config.allowDeleteRows}
on:click={deleteRow}>Delete row</MenuItem on:click={deleteRow}
> >
Delete row
</MenuItem>
<MenuItem <MenuItem
icon="Duplicate" icon="Duplicate"
disabled={!$config.allowAddRows} disabled={!$config.allowAddRows}
on:click={duplicate}>Duplicate row</MenuItem on:click={duplicate}
> >
Duplicate row
</MenuItem>
</Menu> </Menu>
</div> </div>
{/if} {/if}

View File

@ -0,0 +1,37 @@
import { writable, get } from "svelte/store"
export const createStores = () => {
const copiedCell = writable(null)
const copiedRow = writable(null)
return {
copiedCell,
copiedRow,
}
}
export const deriveStores = context => {
const { copiedCell, copiedRow, focusedCellAPI } = context
const copy = () => {
copiedCell.set(get(focusedCellAPI)?.getValue())
copiedRow.set(null)
}
const paste = () => {
const $copiedCell = get(copiedCell)
const $focusedCellAPI = get(focusedCellAPI)
if ($copiedCell != null && $focusedCellAPI) {
$focusedCellAPI.setValue($copiedCell)
}
}
return {
clipboard: {
actions: {
copy,
paste,
},
},
}
}

View File

@ -10,6 +10,7 @@ import * as UI from "./ui"
import * as Users from "./users" import * as Users from "./users"
import * as Validation from "./validation" import * as Validation from "./validation"
import * as Viewport from "./viewport" import * as Viewport from "./viewport"
import * as Clipboard from "./clipboard"
const DependencyOrderedStores = [ const DependencyOrderedStores = [
Bounds, Bounds,
@ -24,6 +25,7 @@ const DependencyOrderedStores = [
Users, Users,
Menu, Menu,
Pagination, Pagination,
Clipboard,
] ]
export const attachStores = context => { export const attachStores = context => {

View File

@ -122,17 +122,6 @@ export const deriveStores = context => {
}) })
} }
const moveColumnToStart = async column => {
moveColumn(column, null)
await columns.actions.saveChanges()
}
const moveColumnToEnd = async column => {
const $visibleColumns = get(visibleColumns)
moveColumn(column, $visibleColumns[$visibleColumns.length - 1]?.name)
await columns.actions.saveChanges()
}
// Moves a column one place left (as appears visually) // Moves a column one place left (as appears visually)
const moveColumnLeft = async column => { const moveColumnLeft = async column => {
const $visibleColumns = get(visibleColumns) const $visibleColumns = get(visibleColumns)
@ -160,8 +149,6 @@ export const deriveStores = context => {
stopReordering, stopReordering,
moveColumnLeft, moveColumnLeft,
moveColumnRight, moveColumnRight,
moveColumnToStart,
moveColumnToEnd,
}, },
}, },
} }

View File

@ -283,13 +283,25 @@ export const deriveStores = context => {
get(fetch)?.getInitialData() get(fetch)?.getInitialData()
} }
// Updates a value of a row // Patches a row with some changes
const updateRow = async (rowId, column, value) => { const updateRow = async (rowId, changes) => {
const $rows = get(rows) const $rows = get(rows)
const $rowLookupMap = get(rowLookupMap) const $rowLookupMap = get(rowLookupMap)
const index = $rowLookupMap[rowId] const index = $rowLookupMap[rowId]
const row = $rows[index] const row = $rows[index]
if (index == null || row?.[column] === value) { if (index == null || !Object.keys(changes || {}).length) {
return
}
// Abandon if no changes
let same = true
for (let column of Object.keys(changes)) {
if (row[column] !== changes[column]) {
same = false
break
}
}
if (same) {
return return
} }
@ -298,7 +310,7 @@ export const deriveStores = context => {
...state, ...state,
[rowId]: { [rowId]: {
...state[rowId], ...state[rowId],
[column]: value, ...changes,
}, },
})) }))
@ -332,6 +344,11 @@ export const deriveStores = context => {
})) }))
} }
// Updates a value of a row
const updateValue = async (rowId, column, value) => {
return await updateRow(rowId, { [column]: value })
}
// Deletes an array of rows // Deletes an array of rows
const deleteRows = async rowsToDelete => { const deleteRows = async rowsToDelete => {
if (!rowsToDelete?.length) { if (!rowsToDelete?.length) {
@ -418,6 +435,7 @@ export const deriveStores = context => {
addRow, addRow,
duplicateRow, duplicateRow,
getRow, getRow,
updateValue,
updateRow, updateRow,
deleteRows, deleteRows,
hasRow, hasRow,