85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import type { Ref } from 'vue'
|
|
import type { WorkflowConfig } from '~/types/workflow'
|
|
|
|
interface WorkflowStore {
|
|
current: any
|
|
isLoading: boolean
|
|
clearCurrent: () => void
|
|
[key: string]: any
|
|
}
|
|
|
|
export const useWorkflowSteps = (config: WorkflowConfig, store: WorkflowStore) => {
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const stepLabels = config.steps.map(s => s.label)
|
|
|
|
const currentStep = computed(() => store.current?.currentStep ?? 0)
|
|
const entity = computed(() => store.current)
|
|
|
|
const loadMethod = `load${config.entityName.charAt(0).toUpperCase() + config.entityName.slice(1)}`
|
|
const updateMethod = `update${config.entityName.charAt(0).toUpperCase() + config.entityName.slice(1)}`
|
|
|
|
const resolveId = (param: unknown) => {
|
|
const idStr = Array.isArray(param) ? param[0] : param
|
|
if (!idStr) return null
|
|
const id = Number(idStr)
|
|
return Number.isFinite(id) ? id : null
|
|
}
|
|
|
|
const init = () => {
|
|
watch(
|
|
() => route.params.id,
|
|
async (param) => {
|
|
const id = resolveId(param)
|
|
if (id === null) {
|
|
store.clearCurrent()
|
|
return
|
|
}
|
|
await store[loadMethod](id)
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
}
|
|
|
|
const saveAndHold = async () => {
|
|
if (!store.current) {
|
|
await router.push('/')
|
|
return
|
|
}
|
|
const datePayload: Record<string, any> = {}
|
|
const rawDate = store.current[config.dateField]
|
|
datePayload[config.dateField] = rawDate ? rawDate.slice(0, 10) : rawDate
|
|
await store[updateMethod](store.current.id, {
|
|
currentStep: store.current.currentStep,
|
|
licensePlate: store.current.licensePlate,
|
|
...datePayload
|
|
})
|
|
await router.push('/')
|
|
}
|
|
|
|
const handleStepSelect = async (step: number) => {
|
|
if (!store.current) return
|
|
if (step === store.current.currentStep) return
|
|
await store[updateMethod](store.current.id, { currentStep: step })
|
|
await store[loadMethod](store.current.id)
|
|
}
|
|
|
|
const advanceStep = async () => {
|
|
if (!store.current) return
|
|
const nextStep = store.current.currentStep + 1
|
|
await store[updateMethod](store.current.id, { currentStep: nextStep })
|
|
await store[loadMethod](store.current.id)
|
|
}
|
|
|
|
return {
|
|
stepLabels,
|
|
currentStep,
|
|
entity,
|
|
init,
|
|
saveAndHold,
|
|
handleStepSelect,
|
|
advanceStep
|
|
}
|
|
}
|