Add bulk deletion to multi row context menu
This commit is contained in:
parent
2dbf9a5118
commit
f86c80af32
|
@ -2,7 +2,8 @@
|
|||
import { Modal, ModalContent } from "@budibase/bbui"
|
||||
import { getContext, onMount } from "svelte"
|
||||
|
||||
const { selectedRows, rows, subscribe, notifications } = getContext("grid")
|
||||
const { selectedRows, rows, subscribe, notifications, menu } =
|
||||
getContext("grid")
|
||||
|
||||
let modal
|
||||
|
||||
|
@ -16,6 +17,9 @@
|
|||
const count = rowsToDelete.length
|
||||
await rows.actions.deleteRows(rowsToDelete)
|
||||
$notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
|
||||
|
||||
// Ensure menu is closed, as we may have triggered this from there
|
||||
menu.actions.close()
|
||||
}
|
||||
|
||||
onMount(() => subscribe("request-bulk-delete", () => modal?.show()))
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
focusedRowId,
|
||||
notifications,
|
||||
hasBudibaseIdentifiers,
|
||||
selectedRowCount,
|
||||
} = getContext("grid")
|
||||
|
||||
let anchor
|
||||
|
@ -37,6 +38,10 @@
|
|||
$notifications.success("Deleted 1 row")
|
||||
}
|
||||
|
||||
const bulkDelete = () => {
|
||||
dispatch("request-bulk-delete")
|
||||
}
|
||||
|
||||
const duplicate = async () => {
|
||||
menu.actions.close()
|
||||
const newRow = await rows.actions.duplicateRow($focusedRow)
|
||||
|
@ -58,59 +63,80 @@
|
|||
{#key style}
|
||||
<GridPopover {anchor} on:close={menu.actions.close} maxHeight={null}>
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
on:click={clipboard.actions.copy}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Paste"
|
||||
disabled={$copiedCell == null || $focusedCellAPI?.isReadonly()}
|
||||
on:click={clipboard.actions.paste}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Paste
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Maximize"
|
||||
disabled={isNewRow || !$config.canEditRows || !$config.canExpandRows}
|
||||
on:click={() => dispatch("edit-row", $focusedRow)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Edit row in modal
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
disabled={isNewRow || !$focusedRow?._id || !$hasBudibaseIdentifiers}
|
||||
on:click={() => copyToClipboard($focusedRow?._id)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy row _id
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
disabled={isNewRow || !$focusedRow?._rev || !$hasBudibaseIdentifiers}
|
||||
on:click={() => copyToClipboard($focusedRow?._rev)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy row _rev
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Duplicate"
|
||||
disabled={isNewRow || !$config.canAddRows}
|
||||
on:click={duplicate}
|
||||
>
|
||||
Duplicate row
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Delete"
|
||||
disabled={isNewRow || !$config.canDeleteRows}
|
||||
on:click={deleteRow}
|
||||
>
|
||||
Delete row
|
||||
</MenuItem>
|
||||
{#if $menu.multiRowMode}
|
||||
<MenuItem
|
||||
icon="Duplicate"
|
||||
disabled={isNewRow || !$config.canAddRows}
|
||||
on:click={duplicate}
|
||||
>
|
||||
Duplicate {$selectedRowCount} rows
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Delete"
|
||||
disabled={!$config.canDeleteRows}
|
||||
on:click={bulkDelete}
|
||||
>
|
||||
Delete {$selectedRowCount} rows
|
||||
</MenuItem>
|
||||
{:else}
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
on:click={clipboard.actions.copy}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Paste"
|
||||
disabled={$copiedCell == null || $focusedCellAPI?.isReadonly()}
|
||||
on:click={clipboard.actions.paste}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Paste
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Maximize"
|
||||
disabled={isNewRow ||
|
||||
!$config.canEditRows ||
|
||||
!$config.canExpandRows}
|
||||
on:click={() => dispatch("edit-row", $focusedRow)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Edit row in modal
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
disabled={isNewRow || !$focusedRow?._id || !$hasBudibaseIdentifiers}
|
||||
on:click={() => copyToClipboard($focusedRow?._id)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy row _id
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Copy"
|
||||
disabled={isNewRow ||
|
||||
!$focusedRow?._rev ||
|
||||
!$hasBudibaseIdentifiers}
|
||||
on:click={() => copyToClipboard($focusedRow?._rev)}
|
||||
on:click={menu.actions.close}
|
||||
>
|
||||
Copy row _rev
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Duplicate"
|
||||
disabled={isNewRow || !$config.canAddRows}
|
||||
on:click={duplicate}
|
||||
>
|
||||
Duplicate row
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="Delete"
|
||||
disabled={isNewRow || !$config.canDeleteRows}
|
||||
on:click={deleteRow}
|
||||
>
|
||||
Delete row
|
||||
</MenuItem>
|
||||
{/if}
|
||||
</Menu>
|
||||
</GridPopover>
|
||||
{/key}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { writable } from "svelte/store"
|
||||
import { writable, get } from "svelte/store"
|
||||
import { parseCellID } from "../lib/utils"
|
||||
|
||||
export const createStores = () => {
|
||||
const menu = writable({
|
||||
|
@ -13,7 +14,8 @@ export const createStores = () => {
|
|||
}
|
||||
|
||||
export const createActions = context => {
|
||||
const { menu, focusedCellId, gridID } = context
|
||||
const { menu, focusedCellId, gridID, selectedRows, selectedRowCount } =
|
||||
context
|
||||
|
||||
const open = (cellId, e) => {
|
||||
e.preventDefault()
|
||||
|
@ -29,11 +31,26 @@ export const createActions = context => {
|
|||
// Compute bounds of cell relative to outer data node
|
||||
const targetBounds = e.target.getBoundingClientRect()
|
||||
const dataBounds = dataNode.getBoundingClientRect()
|
||||
focusedCellId.set(cellId)
|
||||
|
||||
// Check if there are multiple rows selected, and this is one of them
|
||||
let multiRowMode = false
|
||||
if (get(selectedRowCount) > 1) {
|
||||
const rowId = parseCellID(cellId).id
|
||||
if (get(selectedRows)[rowId]) {
|
||||
multiRowMode = true
|
||||
}
|
||||
}
|
||||
|
||||
// Only focus this cell if not in multi row mode
|
||||
if (!multiRowMode) {
|
||||
focusedCellId.set(cellId)
|
||||
}
|
||||
|
||||
menu.set({
|
||||
left: targetBounds.left - dataBounds.left + e.offsetX,
|
||||
top: targetBounds.top - dataBounds.top + e.offsetY,
|
||||
visible: true,
|
||||
multiRowMode,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ export const deriveStores = context => {
|
|||
})
|
||||
|
||||
// Derive we have any selected rows or not
|
||||
const hasSelectedRows = derived(selectedRows, $selectedRows => {
|
||||
const selectedRowCount = derived(selectedRows, $selectedRows => {
|
||||
return Object.keys($selectedRows).length
|
||||
})
|
||||
|
||||
|
@ -94,7 +94,7 @@ export const deriveStores = context => {
|
|||
focusedRow,
|
||||
contentLines,
|
||||
compact,
|
||||
hasSelectedRows,
|
||||
selectedRowCount,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ export const createActions = context => {
|
|||
selectedRows,
|
||||
rowLookupMap,
|
||||
rows,
|
||||
hasSelectedRows,
|
||||
selectedRowCount,
|
||||
} = context
|
||||
// Keep the last selected index to use with bulk selection
|
||||
let lastSelectedIndex = null
|
||||
|
@ -133,7 +133,7 @@ export const createActions = context => {
|
|||
}
|
||||
|
||||
const bulkSelectRows = id => {
|
||||
if (!get(hasSelectedRows)) {
|
||||
if (!get(selectedRowCount)) {
|
||||
toggleSelectedRow(id)
|
||||
return
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ export const initialise = context => {
|
|||
definition,
|
||||
rowHeight,
|
||||
fixedRowHeight,
|
||||
hasSelectedRows,
|
||||
selectedRowCount,
|
||||
} = context
|
||||
|
||||
// Ensure we clear invalid rows from state if they disappear
|
||||
|
@ -245,7 +245,7 @@ export const initialise = context => {
|
|||
}
|
||||
|
||||
// Clear row selection when focusing a cell
|
||||
if (id && get(hasSelectedRows)) {
|
||||
if (id && get(selectedRowCount)) {
|
||||
selectedRows.set({})
|
||||
}
|
||||
})
|
||||
|
@ -267,8 +267,8 @@ export const initialise = context => {
|
|||
})
|
||||
|
||||
// Clear focused cell when selecting rows
|
||||
hasSelectedRows.subscribe(selected => {
|
||||
if (get(focusedCellId) && selected) {
|
||||
selectedRowCount.subscribe(count => {
|
||||
if (get(focusedCellId) && count) {
|
||||
focusedCellId.set(null)
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue