89 lines
2.1 KiB
TypeScript
89 lines
2.1 KiB
TypeScript
import { computed, ref } from 'vue'
|
|
import type { BuiltinField, ContentEntry } from '@/lib/contentTypes'
|
|
import type { MediaMap, MediaSummary } from '@/lib/mediaField'
|
|
import {
|
|
carriesDefault,
|
|
firstIssueKey,
|
|
initialImages,
|
|
initialValues,
|
|
valuesDiffer,
|
|
type EntryIssues,
|
|
type EntryValues,
|
|
type FieldIssue,
|
|
} from '@/lib/entryForm'
|
|
|
|
export function useEntryForm(fields: () => BuiltinField[], creating: () => boolean) {
|
|
const values = ref<EntryValues>({})
|
|
const saved = ref<EntryValues>({})
|
|
const images = ref<MediaMap>({})
|
|
const issues = ref<EntryIssues>({})
|
|
const rejected = ref(false)
|
|
|
|
const dirty = computed(() => valuesDiffer(fields(), values.value, saved.value))
|
|
const firstIssue = computed(() => firstIssueKey(fields(), issues.value))
|
|
const hasIssues = computed(() => Object.keys(issues.value).length > 0)
|
|
|
|
function reset(entry: ContentEntry | null) {
|
|
const next = initialValues(fields(), entry)
|
|
values.value = { ...next }
|
|
saved.value = { ...next }
|
|
images.value = initialImages(fields(), entry)
|
|
issues.value = {}
|
|
rejected.value = false
|
|
}
|
|
|
|
function setImage(key: string, image: MediaSummary | null | undefined) {
|
|
if (image === undefined) {
|
|
return
|
|
}
|
|
const next = { ...images.value }
|
|
if (image === null) {
|
|
delete next[key]
|
|
} else {
|
|
next[key] = image
|
|
}
|
|
images.value = next
|
|
}
|
|
|
|
function setValue(key: string, value: unknown, image?: MediaSummary | null) {
|
|
values.value = { ...values.value, [key]: value }
|
|
setImage(key, image)
|
|
rejected.value = false
|
|
if (issues.value[key]) {
|
|
const rest = { ...issues.value }
|
|
delete rest[key]
|
|
issues.value = rest
|
|
}
|
|
}
|
|
|
|
function reject(next: EntryIssues) {
|
|
issues.value = next
|
|
rejected.value = true
|
|
}
|
|
|
|
function rejectField(key: string, issue: FieldIssue) {
|
|
reject({ [key]: issue })
|
|
}
|
|
|
|
function isDefault(field: BuiltinField) {
|
|
return creating() && carriesDefault(field, values.value[field.key])
|
|
}
|
|
|
|
return {
|
|
values,
|
|
images,
|
|
issues,
|
|
rejected,
|
|
dirty,
|
|
firstIssue,
|
|
hasIssues,
|
|
reset,
|
|
setValue,
|
|
reject,
|
|
rejectField,
|
|
isDefault,
|
|
}
|
|
}
|
|
|
|
export type EntryForm = ReturnType<typeof useEntryForm>
|