Add space keybind for selecting rows and allow bulk deleting of rows via keypress when rows are selected
This commit is contained in:
parent
ace9bca81d
commit
0493fb5c03
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { Modal, ModalContent, Button, notifications } from "@budibase/bbui"
|
import { Modal, ModalContent, Button, notifications } from "@budibase/bbui"
|
||||||
import { getContext } from "svelte"
|
import { getContext, onMount } from "svelte"
|
||||||
|
|
||||||
const { selectedRows, rows, config } = getContext("grid")
|
const { selectedRows, rows, config, subscribe } = getContext("grid")
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
await rows.actions.deleteRows(rowsToDelete)
|
await rows.actions.deleteRows(rowsToDelete)
|
||||||
notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
|
notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => subscribe("request-bulk-delete", () => modal?.show()))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if selectedRowCount}
|
{#if selectedRowCount}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import DataCell from "../cells/DataCell.svelte"
|
import DataCell from "../cells/DataCell.svelte"
|
||||||
import { fade } from "svelte/transition"
|
import { fade } from "svelte/transition"
|
||||||
import { GutterWidth } from "../lib/constants"
|
import { GutterWidth } from "../lib/constants"
|
||||||
|
import { NewRowID } from "../lib/constants"
|
||||||
|
|
||||||
const {
|
const {
|
||||||
hoveredRowId,
|
hoveredRowId,
|
||||||
|
@ -21,10 +22,8 @@
|
||||||
renderedColumns,
|
renderedColumns,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
const rowId = "new"
|
|
||||||
let isAdding = false
|
let isAdding = false
|
||||||
let newRow = {}
|
let newRow = {}
|
||||||
let touched = false
|
|
||||||
|
|
||||||
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
||||||
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
||||||
|
@ -66,19 +65,18 @@
|
||||||
document.addEventListener("keydown", handleKeyPress)
|
document.addEventListener("keydown", handleKeyPress)
|
||||||
newRow = {}
|
newRow = {}
|
||||||
isAdding = true
|
isAdding = true
|
||||||
$hoveredRowId = rowId
|
$hoveredRowId = NewRowID
|
||||||
if (firstColumn) {
|
if (firstColumn) {
|
||||||
$focusedCellId = `${rowId}-${firstColumn.name}`
|
$focusedCellId = `${NewRowID}-${firstColumn.name}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValue = (rowId, columnName, val) => {
|
const updateValue = (rowId, columnName, val) => {
|
||||||
touched = true
|
|
||||||
newRow[columnName] = val
|
newRow[columnName] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
const addViaModal = () => {
|
const addViaModal = () => {
|
||||||
isAdding = false
|
clear()
|
||||||
dispatch("add-row")
|
dispatch("add-row")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,3 +9,4 @@ export const SmallRowHeight = 36
|
||||||
export const MediumRowHeight = 64
|
export const MediumRowHeight = 64
|
||||||
export const LargeRowHeight = 92
|
export const LargeRowHeight = 92
|
||||||
export const DefaultRowHeight = SmallRowHeight
|
export const DefaultRowHeight = SmallRowHeight
|
||||||
|
export const NewRowID = "new"
|
||||||
|
|
|
@ -21,7 +21,10 @@ export const createEventManagers = () => {
|
||||||
|
|
||||||
// Return unsubscribe function
|
// Return unsubscribe function
|
||||||
return () => {
|
return () => {
|
||||||
|
console.log("unsub", event)
|
||||||
|
console.log(subscribers[event].length)
|
||||||
subscribers[event] = subscribers[event].filter(cb => cb !== callback)
|
subscribers[event] = subscribers[event].filter(cb => cb !== callback)
|
||||||
|
console.log(subscribers[event].length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext, onMount } from "svelte"
|
import { getContext, onMount } from "svelte"
|
||||||
import { debounce } from "../../../utils/utils"
|
import { debounce } from "../../../utils/utils"
|
||||||
|
import { NewRowID } from "../lib/constants"
|
||||||
|
|
||||||
const {
|
const {
|
||||||
enrichedRows,
|
enrichedRows,
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
focusedCellAPI,
|
focusedCellAPI,
|
||||||
clipboard,
|
clipboard,
|
||||||
dispatch,
|
dispatch,
|
||||||
|
selectedRows,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
// Global key listener which intercepts all key events
|
// Global key listener which intercepts all key events
|
||||||
|
@ -34,9 +36,11 @@
|
||||||
// which depend on being able to read cell state on an escape keypress
|
// which depend on being able to read cell state on an escape keypress
|
||||||
// get a chance to observe the true state before we blur
|
// get a chance to observe the true state before we blur
|
||||||
setTimeout(api?.blur, 10)
|
setTimeout(api?.blur, 10)
|
||||||
|
return
|
||||||
} else if (e.key === "Tab") {
|
} else if (e.key === "Tab") {
|
||||||
api?.blur?.()
|
api?.blur?.()
|
||||||
changeFocusedColumn(1)
|
changeFocusedColumn(1)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the key event to the selected cell and let it decide whether to
|
// Pass the key event to the selected cell and let it decide whether to
|
||||||
|
@ -84,11 +88,19 @@
|
||||||
break
|
break
|
||||||
case "Delete":
|
case "Delete":
|
||||||
case "Backspace":
|
case "Backspace":
|
||||||
deleteSelectedCell()
|
if (Object.keys($selectedRows).length) {
|
||||||
|
dispatch("request-bulk-delete")
|
||||||
|
} else {
|
||||||
|
deleteSelectedCell()
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case "Enter":
|
case "Enter":
|
||||||
focusCell()
|
focusCell()
|
||||||
break
|
break
|
||||||
|
case " ":
|
||||||
|
case "Space":
|
||||||
|
toggleSelectRow()
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
startEnteringValue(e.key, e.which)
|
startEnteringValue(e.key, e.which)
|
||||||
}
|
}
|
||||||
|
@ -182,6 +194,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleSelectRow = () => {
|
||||||
|
const id = $focusedRow?._id
|
||||||
|
if (!id || id === NewRowID) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedRows.update(state => {
|
||||||
|
state[id] = !state[id]
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
document.addEventListener("keydown", handleKeyDown)
|
document.addEventListener("keydown", handleKeyDown)
|
||||||
return () => {
|
return () => {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { writable, derived, get } from "svelte/store"
|
import { writable, derived, get } from "svelte/store"
|
||||||
import { fetchData } from "../../../fetch/fetchData"
|
import { fetchData } from "../../../fetch/fetchData"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
|
import { NewRowID } from "../lib/constants"
|
||||||
|
|
||||||
const initialSortState = {
|
const initialSortState = {
|
||||||
column: null,
|
column: null,
|
||||||
|
@ -230,7 +231,7 @@ export const deriveStores = context => {
|
||||||
if (bubble) {
|
if (bubble) {
|
||||||
throw error
|
throw error
|
||||||
} else {
|
} else {
|
||||||
handleValidationError("new", error)
|
handleValidationError(NewRowID, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
DefaultRowHeight,
|
DefaultRowHeight,
|
||||||
LargeRowHeight,
|
LargeRowHeight,
|
||||||
MediumRowHeight,
|
MediumRowHeight,
|
||||||
|
NewRowID,
|
||||||
} from "../lib/constants"
|
} from "../lib/constants"
|
||||||
|
|
||||||
export const createStores = () => {
|
export const createStores = () => {
|
||||||
|
@ -50,9 +51,9 @@ export const deriveStores = context => {
|
||||||
([$focusedCellId, $rowLookupMap, $enrichedRows]) => {
|
([$focusedCellId, $rowLookupMap, $enrichedRows]) => {
|
||||||
const rowId = $focusedCellId?.split("-")[0]
|
const rowId = $focusedCellId?.split("-")[0]
|
||||||
|
|
||||||
// Edge case for new rows (top and bottom row ID components have unique IDs)
|
// Edge case for new rows
|
||||||
if (rowId?.startsWith("new")) {
|
if (rowId === NewRowID) {
|
||||||
return { _id: rowId }
|
return { _id: NewRowID }
|
||||||
}
|
}
|
||||||
|
|
||||||
// All normal rows
|
// All normal rows
|
||||||
|
@ -145,18 +146,18 @@ export const initialise = context => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Reset selected rows when selected cell changes
|
// Reset selected rows when selected cell changes
|
||||||
focusedCellId.subscribe(id => {
|
// focusedCellId.subscribe(id => {
|
||||||
if (id) {
|
// if (id) {
|
||||||
selectedRows.set({})
|
// selectedRows.set({})
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
// Unset selected cell when rows are selected
|
// Unset selected cell when rows are selected
|
||||||
selectedRows.subscribe(rows => {
|
// selectedRows.subscribe(rows => {
|
||||||
if (Object.keys(rows || {}).length) {
|
// if (Object.keys(rows || {}).length) {
|
||||||
focusedCellId.set(null)
|
// focusedCellId.set(null)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
// Remove hovered row when a cell is selected
|
// Remove hovered row when a cell is selected
|
||||||
focusedCellId.subscribe(cell => {
|
focusedCellId.subscribe(cell => {
|
||||||
|
|
Loading…
Reference in New Issue