Improve bulk notifications and progress updates
This commit is contained in:
parent
7a3eabc529
commit
e2df7ae6db
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue