feat: entry editor at /content/:key/new and /content/:key/:id

This commit is contained in:
Florian Sylvain committed 2026-10-21 00:12:34 +02:00
1 parent 91d916fb74
commit fba20f83c5
94 files changed
+7116 -423

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
import { computed, ref } from 'vue'
import type { BuiltinField, ContentEntry } from '@/lib/contentTypes'
import {
carriesDefault,
firstIssueKey,
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 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 }
issues.value = {}
rejected.value = false
}
function setValue(key: string, value: unknown) {
values.value = { ...values.value, [key]: value }
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,
issues,
rejected,
dirty,
firstIssue,
hasIssues,
reset,
setValue,
reject,
rejectField,
isDefault,
}
}
export type EntryForm = ReturnType<typeof useEntryForm>