Files
Starlight_Lancher/packages/ui/src/layouts/shared/content-tab/composables/bulk-operations.ts

104 lines
2.3 KiB
TypeScript

import { onBeforeUnmount, ref, watch } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
export type BulkOperationType = 'enable' | 'disable' | 'delete' | 'update'
export function useBulkOperation() {
const isBulkOperating = ref(false)
const bulkProgress = ref(0)
const bulkTotal = ref(0)
const bulkOperation = ref<BulkOperationType | null>(null)
const bulkWaiting = ref(false)
function resetState() {
isBulkOperating.value = false
bulkOperation.value = null
bulkProgress.value = 0
bulkTotal.value = 0
bulkWaiting.value = false
}
async function runBulk<T>(
operation: BulkOperationType,
items: T[],
fn: (item: T) => Promise<void>,
options?: { delayMs?: number; onComplete?: () => void },
) {
const delayMs = options?.delayMs ?? 250
isBulkOperating.value = true
bulkOperation.value = operation
bulkTotal.value = items.length
bulkProgress.value = 0
try {
for (const item of items) {
await fn(item)
bulkProgress.value++
if (delayMs > 0 && bulkProgress.value < items.length) {
await new Promise((resolve) => setTimeout(resolve, delayMs))
}
}
} finally {
options?.onComplete?.()
resetState()
}
}
async function runBulkWithWaiting(
operation: BulkOperationType,
total: number,
fn: () => Promise<void>,
onComplete?: () => void,
) {
isBulkOperating.value = true
bulkOperation.value = operation
bulkTotal.value = total
bulkProgress.value = 0
bulkWaiting.value = true
try {
await fn()
} finally {
onComplete?.()
resetState()
}
}
function handleBeforeUnload(e: BeforeUnloadEvent) {
if (isBulkOperating.value) {
e.preventDefault()
return ''
}
}
if (typeof window !== 'undefined') {
watch(isBulkOperating, (operating) => {
if (operating) {
window.addEventListener('beforeunload', handleBeforeUnload)
} else {
window.removeEventListener('beforeunload', handleBeforeUnload)
}
})
onBeforeUnmount(() => {
window.removeEventListener('beforeunload', handleBeforeUnload)
})
onBeforeRouteLeave(() => {
if (isBulkOperating.value) {
return window.confirm('A bulk operation is in progress. Are you sure you want to leave?')
}
return true
})
}
return {
isBulkOperating,
bulkProgress,
bulkTotal,
bulkOperation,
bulkWaiting,
runBulk,
runBulkWithWaiting,
}
}