fix(visual-editing): don’t open admin for portableText; simplify starter PT markup (#40)
* fix(visual-editing): PT inline editing; align starter templates * chore(admin): format router.tsx --------- Co-authored-by: Matt Kane <mkane@cloudflare.com>
This commit is contained in:
@@ -688,6 +688,11 @@ export function renderToolbar(config: ToolbarConfig): string {
|
|||||||
return f ? f.kind : null;
|
return f ? f.kind : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load manifest early so the first click can resolve field kinds without racing the event.
|
||||||
|
if (isEditMode) {
|
||||||
|
fetchManifest();
|
||||||
|
}
|
||||||
|
|
||||||
// Save a single field value
|
// Save a single field value
|
||||||
function saveField(collection, id, field, value) {
|
function saveField(collection, id, field, value) {
|
||||||
setSaveState("saving");
|
setSaveState("saving");
|
||||||
@@ -1236,31 +1241,39 @@ export function renderToolbar(config: ToolbarConfig): string {
|
|||||||
|
|
||||||
var ref = target.getAttribute && target.getAttribute("data-emdash-ref");
|
var ref = target.getAttribute && target.getAttribute("data-emdash-ref");
|
||||||
if (ref) {
|
if (ref) {
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var annotation = JSON.parse(ref);
|
var annotation = JSON.parse(ref);
|
||||||
|
|
||||||
// Entry-level annotation (no field) — ignore, it's a container
|
// Entry-level annotation (no field) — keep walking for a field-level ancestor
|
||||||
if (!annotation.field) return;
|
if (!annotation.field) {
|
||||||
|
target = target.parentElement;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch manifest to determine field type, then dispatch
|
function dispatchInline(kind) {
|
||||||
fetchManifest().then(function(manifest) {
|
|
||||||
var kind = getFieldKind(manifest, annotation.collection, annotation.field);
|
|
||||||
|
|
||||||
// Close any open image popover before starting a new edit
|
|
||||||
closeImagePopover();
|
closeImagePopover();
|
||||||
|
// Portable Text is edited in-page by InlinePortableTextEditor — do not open admin
|
||||||
|
if (kind === "portableText") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
if (kind === "string" || kind === "text") {
|
if (kind === "string" || kind === "text") {
|
||||||
startTextEdit(target, annotation);
|
startTextEdit(target, annotation);
|
||||||
} else if (kind === "image") {
|
} else if (kind === "image") {
|
||||||
startImageEdit(target, annotation);
|
startImageEdit(target, annotation);
|
||||||
} else {
|
} else {
|
||||||
// Fallback: open admin for unsupported types
|
|
||||||
openAdmin(annotation);
|
openAdmin(annotation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifestCache) {
|
||||||
|
dispatchInline(getFieldKind(manifestCache, annotation.collection, annotation.field));
|
||||||
|
} else {
|
||||||
|
fetchManifest().then(function(manifest) {
|
||||||
|
dispatchInline(getFieldKind(manifest, annotation.collection, annotation.field));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to parse emdash ref:", err);
|
console.error("Failed to parse emdash ref:", err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ describe("renderToolbar", () => {
|
|||||||
expect(html).toContain("/_emdash/api/manifest");
|
expect(html).toContain("/_emdash/api/manifest");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("skips toolbar interception for portableText (inline editor)", () => {
|
||||||
|
const html = renderToolbar({ editMode: true, isPreview: false });
|
||||||
|
expect(html).toContain("portableText");
|
||||||
|
});
|
||||||
|
|
||||||
it("includes entry status badge styles", () => {
|
it("includes entry status badge styles", () => {
|
||||||
const html = renderToolbar({ editMode: true, isPreview: false });
|
const html = renderToolbar({ editMode: true, isPreview: false });
|
||||||
expect(html).toContain("emdash-tb-badge--draft");
|
expect(html).toContain("emdash-tb-badge--draft");
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ const seo = getSeoMeta(page, {
|
|||||||
<article>
|
<article>
|
||||||
<h1 {...page.edit.title}>{page.data.title}</h1>
|
<h1 {...page.edit.title}>{page.data.title}</h1>
|
||||||
|
|
||||||
<div {...page.edit.content}>
|
|
||||||
<PortableText value={page.data.content} />
|
<PortableText value={page.data.content} />
|
||||||
</div>
|
|
||||||
</article>
|
</article>
|
||||||
</Base>
|
</Base>
|
||||||
|
|||||||
@@ -69,9 +69,7 @@ const categories = await getEntryTerms("posts", post.data.id, "category");
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<div {...post.edit.content}>
|
|
||||||
<PortableText value={post.data.content} />
|
<PortableText value={post.data.content} />
|
||||||
</div>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
tags.length > 0 && (
|
tags.length > 0 && (
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ const seo = getSeoMeta(page, {
|
|||||||
<article>
|
<article>
|
||||||
<h1 {...page.edit.title}>{page.data.title}</h1>
|
<h1 {...page.edit.title}>{page.data.title}</h1>
|
||||||
|
|
||||||
<div {...page.edit.content}>
|
|
||||||
<PortableText value={page.data.content} />
|
<PortableText value={page.data.content} />
|
||||||
</div>
|
|
||||||
</article>
|
</article>
|
||||||
</Base>
|
</Base>
|
||||||
|
|||||||
@@ -69,9 +69,7 @@ const categories = await getEntryTerms("posts", post.data.id, "category");
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<div {...post.edit.content}>
|
|
||||||
<PortableText value={post.data.content} />
|
<PortableText value={post.data.content} />
|
||||||
</div>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
tags.length > 0 && (
|
tags.length > 0 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user