Improve bulk notifications and progress updates

This commit is contained in:
Andrew Kingston 2024-06-24 08:05:59 +01:00
parent 7a3eabc529
commit e2df7ae6db
No known key found for this signature in database
3 changed files with 40 additions and 35 deletions

View File

@ -13,6 +13,7 @@
selectedCellCount, selectedCellCount,
selectedRowCount, selectedRowCount,
selectedCells, selectedCells,
rowLookupMap,
} = getContext("grid") } = getContext("grid")
const duration = 260 const duration = 260
@ -20,17 +21,24 @@
let cellsModal let cellsModal
let processing = false let processing = false
let progressPercentage = 0 let progressPercentage = 0
let promptQuantity = 0
$: rowsToDelete = Object.entries($selectedRows) $: rowsToDelete = Object.keys($selectedRows)
.map(entry => $rows.find(x => x._id === entry[0])) .map(rowId => $rows[$rowLookupMap[rowId]])
.filter(x => x != null) .filter(x => x != null)
const handleBulkDeleteRequest = () => { const handleBulkDeleteRequest = () => {
progressPercentage = 0 progressPercentage = 0
menu.actions.close() menu.actions.close()
if ($selectedRowCount) { if ($selectedRowCount) {
rowsModal?.show() if ($selectedRowCount === 1) {
bulkDeleteRows()
} else {
promptQuantity = $selectedRowCount
rowsModal?.show()
}
} else if ($selectedCellCount) { } else if ($selectedCellCount) {
promptQuantity = $selectedCellCount
cellsModal?.show() cellsModal?.show()
} }
} }
@ -38,9 +46,11 @@
const bulkDeleteRows = async () => { const bulkDeleteRows = async () => {
processing = true processing = true
const count = rowsToDelete.length const count = rowsToDelete.length
await rows.actions.deleteRows(rowsToDelete, progress => { await rows.actions.deleteRows(rowsToDelete)
progressPercentage = progress * 100 // This is a real bulk delete endpoint so we don't need progress.
}) // We just animate it uo to 100 when we're done for consistency with other
// prompts.
progressPercentage = 100
await sleep(duration) await sleep(duration)
$notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`) $notifications.success(`Deleted ${count} row${count === 1 ? "" : "s"}`)
processing = false processing = false
@ -76,8 +86,7 @@
onConfirm={bulkDeleteRows} onConfirm={bulkDeleteRows}
size="M" size="M"
> >
Are you sure you want to delete {$selectedRowCount} Are you sure you want to delete {promptQuantity} rows?
row{$selectedRowCount === 1 ? "" : "s"}?
{#if processing} {#if processing}
<ProgressBar <ProgressBar
size="L" size="L"
@ -97,8 +106,7 @@
onConfirm={bulkDeleteCells} onConfirm={bulkDeleteCells}
size="M" size="M"
> >
Are you sure you want to delete {$selectedCellCount} Are you sure you want to delete {promptQuantity} cells?
cell{$selectedCellCount === 1 ? "" : "s"}?
{#if processing} {#if processing}
<ProgressBar <ProgressBar
size="L" size="L"

View File

@ -17,6 +17,7 @@
let modal let modal
let progressPercentage = 0 let progressPercentage = 0
let processing = false let processing = false
let promptQuantity = 0
// Deletion callback when confirmed // Deletion callback when confirmed
const performDuplication = async () => { const performDuplication = async () => {
@ -48,7 +49,12 @@
processing = false processing = false
} }
onMount(() => subscribe("request-bulk-duplicate", () => modal?.show())) const handleBulkDuplicateRequest = () => {
promptQuantity = $selectedRowCount
modal?.show()
}
onMount(() => subscribe("request-bulk-duplicate", handleBulkDuplicateRequest))
</script> </script>
<Modal bind:this={modal}> <Modal bind:this={modal}>
@ -59,8 +65,7 @@
onConfirm={performDuplication} onConfirm={performDuplication}
size="M" size="M"
> >
Are you sure you want to duplicate {$selectedRowCount} Are you sure you want to duplicate {promptQuantity} rows?
row{$selectedRowCount === 1 ? "" : "s"}?
{#if processing} {#if processing}
<ProgressBar <ProgressBar
size="L" size="L"

View File

@ -324,6 +324,7 @@ export const createActions = context => {
// Find index of last row // Find index of last row
const $rowLookupMap = get(rowLookupMap) const $rowLookupMap = get(rowLookupMap)
const index = Math.max(...rowsToDupe.map(row => $rowLookupMap[row._id])) const index = Math.max(...rowsToDupe.map(row => $rowLookupMap[row._id]))
const count = rowsToDupe.length
// Clone and clean rows // Clone and clean rows
const clones = rowsToDupe.map(row => { const clones = rowsToDupe.map(row => {
@ -336,7 +337,7 @@ export const createActions = context => {
// Create rows // Create rows
let saved = [] let saved = []
let failed = 0 let failed = 0
for (let i = 0; i < clones.length; i++) { for (let i = 0; i < count; i++) {
try { try {
saved.push(await datasource.actions.addRow(clones[i])) saved.push(await datasource.actions.addRow(clones[i]))
rowCacheMap[saved._id] = true rowCacheMap[saved._id] = true
@ -345,7 +346,7 @@ export const createActions = context => {
failed++ failed++
console.error("Duplicating row failed", error) console.error("Duplicating row failed", error)
} }
progressCallback?.((i + 1) / clones.length) progressCallback?.((i + 1) / count)
} }
// Add to state // Add to state
@ -356,15 +357,10 @@ export const createActions = context => {
} }
// Notify user // Notify user
if (saved.length) {
get(notifications).success(
`Duplicated ${saved.length} row${saved.length === 1 ? "" : "s"}`
)
}
if (failed) { if (failed) {
get(notifications).error( get(notifications).error(`Failed to duplicate ${failed} of ${count} rows`)
`Failed to duplicate ${failed} row${failed === 1 ? "" : "s"}` } else if (saved.length) {
) get(notifications).success(`Duplicated ${saved.length} rows`)
} }
return saved return saved
} }
@ -527,17 +523,18 @@ export const createActions = context => {
const bulkUpdate = async (changeMap, progressCallback) => { const bulkUpdate = async (changeMap, progressCallback) => {
const rowIds = Object.keys(changeMap || {}) const rowIds = Object.keys(changeMap || {})
if (!rowIds.length) { const count = rowIds.length
if (!count) {
return return
} }
// Update rows // Update rows
let updated = [] let updated = []
let failed = 0 let failed = 0
for (let i = 0; i < rowIds.length; i++) { for (let i = 0; i < count; i++) {
const rowId = rowIds[i] const rowId = rowIds[i]
if (!Object.keys(changeMap[rowId] || {}).length) { if (!Object.keys(changeMap[rowId] || {}).length) {
progressCallback?.((i + 1) / rowIds.length) progressCallback?.((i + 1) / count)
continue continue
} }
try { try {
@ -557,7 +554,7 @@ export const createActions = context => {
failed++ failed++
console.error("Failed to update row", error) console.error("Failed to update row", error)
} }
progressCallback?.((i + 1) / rowIds.length) progressCallback?.((i + 1) / count)
} }
// Update state // Update state
@ -573,15 +570,10 @@ export const createActions = context => {
} }
// Notify user // Notify user
if (updated.length) {
get(notifications).success(
`Updated ${updated.length} row${updated.length === 1 ? "" : "s"}`
)
}
if (failed) { if (failed) {
get(notifications).error( get(notifications).error(`Failed to update ${failed} of ${count} rows`)
`Failed to update ${failed} row${failed === 1 ? "" : "s"}` } else if (updated.length) {
) get(notifications).success(`Updated ${updated.length} rows`)
} }
} }