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

+17 -21
View File
@@ -1,8 +1,12 @@
import { formatNumber, t } from '@/i18n'
import type { BuiltinField } from '@/lib/contentTypes'
import { formatAbsoluteDate, formatAbsoluteDateFromIso } from '@/lib/relativeDate'
import { fieldTypeSpec, type FieldCellKind } from '@/lib/fieldTypes'
import { formatDayValue } from '@/lib/entryValue'
import { formatAbsoluteDateFromIso } from '@/lib/relativeDate'
export type CellKind = 'empty' | 'text' | 'richtext' | 'number' | 'boolean' | 'date' | 'choice'
export { formatDayValue }
export type CellKind = 'empty' | FieldCellKind
export interface CellView {
kind: CellKind
@@ -13,10 +17,10 @@ export interface CellView {
export const EMPTY_TEXT = '–'
const EMPTY: CellView = { kind: 'empty', text: '' }
const ISO_DAY = /^(\d{4})-(\d{2})-(\d{2})/
const LINE_PREFIX = /^\s{0,3}(?:#{1,6}(?:\s+|$)|>\s?|[-*+]\s+|\d+[.)]\s+)+/
const IMAGE_OR_LINK = /!?\[([^\]]*)\]\([^)]*\)/g
const EMPHASIS = /(\*\*|__|\*|`|~~)/g
const UNDERSCORE_EMPHASIS = /(^|[\s(])_(?=\S)([^_]*?\S)_(?=$|[\s).,;:!?])/g
export function richTextFirstLine(markdown: string) {
for (const line of markdown.split(/\r?\n/)) {
@@ -24,6 +28,7 @@ export function richTextFirstLine(markdown: string) {
.replace(LINE_PREFIX, '')
.replace(IMAGE_OR_LINK, '$1')
.replace(EMPHASIS, '')
.replace(UNDERSCORE_EMPHASIS, '$1$2')
.trim()
if (plain) {
return plain
@@ -32,35 +37,26 @@ export function richTextFirstLine(markdown: string) {
return ''
}
export function formatDayValue(value: string) {
const match = ISO_DAY.exec(value)
if (!match) {
return value
}
return formatAbsoluteDate(new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])))
}
export function describeCell(field: BuiltinField, value: unknown): CellView {
if (value === undefined || value === null || value === '') {
return EMPTY
}
switch (field.type) {
const kind = fieldTypeSpec(field.type).cell
switch (kind) {
case 'boolean':
return { kind: 'boolean', text: '', yes: value === true }
return { kind, text: '', yes: value === true }
case 'number':
return typeof value === 'number'
? { kind: 'number', text: formatNumber(value) }
: { kind: 'number', text: String(value) }
return { kind, text: typeof value === 'number' ? formatNumber(value) : String(value) }
case 'date':
return { kind: 'date', text: formatDayValue(String(value)) }
case 'select':
return { kind: 'choice', text: String(value) }
return { kind, text: formatDayValue(String(value)) }
case 'choice':
return { kind, text: String(value) }
case 'richtext': {
const line = richTextFirstLine(String(value))
return line ? { kind: 'richtext', text: line } : EMPTY
return line ? { kind, text: line } : EMPTY
}
default:
return { kind: 'text', text: String(value) }
return { kind, text: String(value) }
}
}