Files
admin-web/src/core/unsaved-work/useUnsavedWorkRegistration.ts
T

54 lines
1.5 KiB
TypeScript
Raw Normal View History

2026-08-05 15:54:59 +08:00
import { computed, getCurrentInstance, onActivated, onScopeDispose, ref, watch, type ComputedRef, type Ref } from 'vue'
2026-08-03 18:49:18 +08:00
import { useUnsavedWorkStore } from '@/core/unsaved-work/unsavedWork'
2026-07-30 17:59:43 +08:00
interface UnsavedWorkRegistrationOptions<T extends object> {
key: string
label: ComputedRef<string>
isOpen: Ref<boolean>
model: T
requiredPermission: ComputedRef<string | null>
}
export function useUnsavedWorkRegistration<T extends object>(
options: UnsavedWorkRegistrationOptions<T>,
) {
const store = useUnsavedWorkStore()
2026-08-05 15:54:59 +08:00
const routeName = getCurrentInstance()?.proxy?.$route?.name
const workspaceTabId = routeName === undefined || routeName === null ? null : String(routeName)
const owner = Symbol(options.key)
2026-07-30 17:59:43 +08:00
const snapshot = computed(() => JSON.stringify(options.model))
const baseline = ref(snapshot.value)
2026-08-05 15:54:59 +08:00
store.claim(options.key, owner)
2026-07-30 17:59:43 +08:00
function sync() {
if (!options.isOpen.value) {
2026-08-05 15:54:59 +08:00
store.remove(options.key, owner)
2026-07-30 17:59:43 +08:00
return
}
store.upsert({
key: options.key,
label: options.label.value,
dirty: snapshot.value !== baseline.value,
requiredPermission: options.requiredPermission.value,
2026-08-05 15:54:59 +08:00
workspaceTabId,
}, owner)
2026-07-30 17:59:43 +08:00
}
function captureBaseline() {
baseline.value = snapshot.value
sync()
}
watch(
[options.isOpen, snapshot, options.label, options.requiredPermission],
sync,
{ flush: 'sync' },
)
sync()
2026-08-05 15:54:59 +08:00
onActivated(sync)
onScopeDispose(() => store.release(options.key, owner))
2026-07-30 17:59:43 +08:00
return { captureBaseline }
}