Files
RenewCMS/web/src/composables/useEntryForm.ts
T

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>