initial ai assistance
This commit is contained in:
1 parent
1af9ec3172
commit
2e0bf1e88e
24 files changed
+1293
-60
No files matched your search
+72
-28
@@ -41,19 +41,21 @@ function Properties({ node, schema, ctrl, close }: EditorProps) {
|
||||
}}
|
||||
>
|
||||
<SchemaForm schema={schema} value={draft} onChange={setDraft} node={node} ctrl={ctrl} />
|
||||
<footer className="cms-actions">
|
||||
<button type="button" className="cms-btn" onClick={() => setDraft(node.data ?? {})} disabled={!changed}>
|
||||
<Icon name="reset" size={16} /> Reset
|
||||
</button>
|
||||
{problems.length > 0 && (
|
||||
<span className="cms-error cms-actions__note" role="alert" title={problems.map(([p, m]) => `${p || 'form'}: ${m}`).join('\n')}>
|
||||
{problems.length} problem{problems.length === 1 ? '' : 's'} to fix
|
||||
</span>
|
||||
)}
|
||||
<button type="submit" className="cms-btn cms-btn--primary" disabled={!changed || saving || problems.length > 0}>
|
||||
<Icon name="save" size={16} /> {saving ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
</footer>
|
||||
{changed && (
|
||||
<footer className="cms-actions">
|
||||
<button type="button" className="cms-btn" onClick={() => setDraft(node.data ?? {})}>
|
||||
<Icon name="reset" size={16} /> Reset
|
||||
</button>
|
||||
{problems.length > 0 && (
|
||||
<span className="cms-error cms-actions__note" role="alert" title={problems.map(([p, m]) => `${p || 'form'}: ${m}`).join('\n')}>
|
||||
{problems.length} problem{problems.length === 1 ? '' : 's'} to fix
|
||||
</span>
|
||||
)}
|
||||
<button type="submit" className="cms-btn cms-btn--primary" disabled={saving || problems.length > 0}>
|
||||
<Icon name="save" size={16} /> {saving ? 'Saving…' : 'Save'}
|
||||
</button>
|
||||
</footer>
|
||||
)}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -66,15 +68,13 @@ function RawJson({ node, ctrl, close }: EditorProps) {
|
||||
return (
|
||||
<div className="cms-form">
|
||||
<JsonArea value={node.data ?? {}} onChange={setDraft} />
|
||||
<footer className="cms-actions">
|
||||
<button
|
||||
className="cms-btn cms-btn--primary"
|
||||
disabled={!Object.keys(patch).length}
|
||||
onClick={async () => (await ctrl.setData(node.id, patch, { version: node.version })) && close()}
|
||||
>
|
||||
<Icon name="save" size={16} /> Save
|
||||
</button>
|
||||
</footer>
|
||||
{Object.keys(patch).length > 0 && (
|
||||
<footer className="cms-actions">
|
||||
<button className="cms-btn cms-btn--primary" onClick={async () => (await ctrl.setData(node.id, patch, { version: node.version })) && close()}>
|
||||
<Icon name="save" size={16} /> Save
|
||||
</button>
|
||||
</footer>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -155,7 +155,10 @@ function AddChild({ info, ctrl, close }: EditorProps) {
|
||||
}
|
||||
|
||||
function AddAfter({ info, ctrl, close }: EditorProps) {
|
||||
const [target, setTarget] = useState<{ parent: string; index: number } | null>(null)
|
||||
const [target, setTarget] = useState<{
|
||||
parent: string
|
||||
index: number
|
||||
} | null>(null)
|
||||
useEffect(() => {
|
||||
void (async () => {
|
||||
const parent = await ctrl.parentIdOf(info.id)
|
||||
@@ -168,12 +171,53 @@ function AddAfter({ info, ctrl, close }: EditorProps) {
|
||||
|
||||
export function registerBuiltins(): () => void {
|
||||
const off = [
|
||||
registerEditor({ id: 'properties', label: 'Properties', icon: 'edit', match: '*', priority: 100, onDoubleClick: true, component: Properties }),
|
||||
registerEditor({
|
||||
id: 'properties',
|
||||
label: 'Properties',
|
||||
icon: 'edit',
|
||||
match: '*',
|
||||
priority: 100,
|
||||
onDoubleClick: true,
|
||||
component: Properties,
|
||||
}),
|
||||
// Matches on the schema, not the node type: any type with x-style fields gets spacing/layout controls.
|
||||
registerEditor({ id: 'style', label: 'Style', icon: 'style', match: (i) => describeStyle(i.schema).length > 0, priority: 90, size: 'md', component: StylePanel }),
|
||||
registerEditor({ id: 'add-child', label: 'Add inside', icon: 'add-inside', match: (i) => i.container, priority: 50, size: 'sm', component: AddChild }),
|
||||
registerEditor({ id: 'add-after', label: 'Add after', icon: 'add', match: '*', priority: 40, size: 'sm', component: AddAfter }),
|
||||
registerEditor({ id: 'raw-json', label: 'JSON', icon: 'json', placement: 'menu', match: '*', priority: -100, size: 'lg', component: RawJson }),
|
||||
registerEditor({
|
||||
id: 'style',
|
||||
label: 'Style',
|
||||
icon: 'style',
|
||||
match: (i) => describeStyle(i.schema).length > 0,
|
||||
priority: 90,
|
||||
size: 'md',
|
||||
component: StylePanel,
|
||||
}),
|
||||
registerEditor({
|
||||
id: 'add-child',
|
||||
label: 'Add inside',
|
||||
icon: 'add-inside',
|
||||
match: (i) => i.container,
|
||||
priority: 50,
|
||||
size: 'sm',
|
||||
component: AddChild,
|
||||
}),
|
||||
registerEditor({
|
||||
id: 'add-after',
|
||||
label: 'Add after',
|
||||
icon: 'add',
|
||||
match: '*',
|
||||
priority: 40,
|
||||
size: 'sm',
|
||||
component: AddAfter,
|
||||
}),
|
||||
registerEditor({
|
||||
id: 'raw-json',
|
||||
label: 'JSON',
|
||||
icon: 'json',
|
||||
placement: 'menu',
|
||||
match: '*',
|
||||
priority: -100,
|
||||
size: 'lg',
|
||||
component: RawJson,
|
||||
}),
|
||||
registerInlineEditor({ id: 'text', start: startPlainText }),
|
||||
registerInlineEditor({ id: 'markdown', start: startMarkdown }),
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user