bliss/bliss-cli/live-editor/artifact-editor.eta

58 lines
3.4 KiB
Text
Raw Permalink Normal View History

<article data-bliss-artifact-editor
data-kind="<%= it.kind %>" data-id="<%= it.artifact.id %>"
data-structure-id="<%= it.artifact.structure_id %>" data-method="<%= it.artifact.verb || '' %>"
class="border-2 border-black bg-white text-black shadow-[4px_4px_0_#000]">
<header class="flex items-center gap-2 border-b-4 border-double border-black p-3">
<strong class="min-w-0 flex-1 truncate"><% if (it.kind === 'route') { %><%= it.artifact.verb %> <%= it.artifact.path %><% } else { %><%= it.artifact.name %><% } %></strong>
<span class="text-xs uppercase"><%= it.kind %></span><span data-status class="text-xs"></span>
</header>
<div class="p-3">
<% if (it.kind === 'route' && it.artifact.verb !== 'GET') { %>
<p class="mb-2 border border-amber-700 bg-amber-100 p-2 text-sm">Saving does not replay this <%= it.artifact.verb %> route.</p>
<% } %>
<label class="block text-xs font-bold uppercase tracking-widest"><%= it.kind === 'route' ? 'Handler' : 'Template' %></label>
<div data-editor="<%= it.kind === 'route' ? 'handler' : 'content' %>" data-mode="<%= it.kind === 'route' ? 'javascript' : 'html' %>" class="h-[min(55vh,34rem)] w-full border-2 border-black"><%= it.kind === 'route' ? it.artifact.handler : it.artifact.content %></div>
<% if (it.kind === 'template') { %>
<details class="mt-3" open>
<summary class="cursor-pointer text-xs font-bold uppercase tracking-widest">Rendering test</summary>
<div data-editor="test_object" data-mode="javascript" class="mt-1 h-32 w-full border-2 border-black"><%= it.artifact.test_object || '' %></div>
<iframe data-template-test title="Template rendering test" src="/workshop/<%= it.artifact.structure_id %>/template/<%= it.artifact.id %>/preview" class="mt-2 h-64 w-full border-2 border-black"></iframe>
</details>
<% } %>
<button data-save type="button" class="mt-3 border-2 border-black bg-white px-3 py-2 font-bold shadow-[3px_3px_0_#000]">Save</button>
</div>
</article>
<script>
(function () {
const card = document.currentScript.previousElementSibling;
if (!card || card.dataset.ready) return;
card.dataset.ready = "true";
const editors = Object.fromEntries([...card.querySelectorAll("[data-editor]")].map((node) => {
const editor = ace.edit(node);
editor.setTheme("ace/theme/monokai");
editor.session.setMode(`ace/mode/${node.dataset.mode}`);
return [node.dataset.editor, editor];
}));
card.querySelector("[data-save]").onclick = async () => {
const status = card.querySelector("[data-status]");
const { kind, id, structureId } = card.dataset;
status.textContent = "Saving…";
const body = kind === "route"
? { handler: editors.handler.getValue() }
: { content: editors.content.getValue(), test_object: editors.test_object.getValue() };
const response = await fetch(`/workshop/${structureId}/${kind}/${id}`, {
method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body),
});
if (!response.ok) return void (status.textContent = "Save failed");
status.textContent = "Saved";
if (kind === "template") {
const frame = card.querySelector("[data-template-test]");
frame.src = `${frame.src.split("?")[0]}?t=${Date.now()}`;
}
document.dispatchEvent(new CustomEvent("bliss:source-saved", {
detail: { kind, id, method: kind === "route" ? card.dataset.verb : undefined },
}));
};
})();
</script>