< script >
import template from "lodash/template";
import Icon from "$/client/components/Icon.svelte";
import Toasts from "$/client/components/Toasts.svelte";
import Code from "$/client/components/Code.svelte";
import { log } from "$/client/logging.js";
import Layout from "../Layout.svelte";
import api from '$/client/api.js';
import { onMount } from "svelte";
export let selected_template;
let showing_rendered = false;
let results = "";
let source = "";
let variable_json = "{ } ";
let generators = [];
let variables = {} ;
let renderer = () => source;
let notice = "";
let last_good = "";
let send_toast;
let language = "javascript";
const language_list = {
"html": "html",
"svelte": "javascript",
"sh": "shell",
"js": "javascript"
}
const list_generators = async () => {
let [status, data] = await api.get('/api/devtools/djenterator');
if(status == 200) {
generators = data;
selected_template = generators[0];
} else {
log.debug("failed to load generators", status);
}
}
const render_template = () => {
try {
// avoid rendering when the current template doesn't match the renderer
if(selected_template == renderer._template) {
variables = variable_json ? JSON.parse(variable_json): {} ;
results = renderer(variables);
notice = "";
last_good = results;
}
return true;
} catch(err) {
log.error(err);
notice = err.message;
results = last_good;
return false;
}
}
const load_variables = async (template_name) => {
let res = await fetch(`/djenterator/${ template_name } .vars`);
if(res.status == 200) {
variable_json = await res.text();
} else {
variable_json = '{} ';
notice = `No ${ template_name } .vars file found. ${ res . status } `;
}
}
const detect_language = (name) => {
const ext = name.split(".")[1];
language = language_list[ext];
}
const load_template = async (template_name) => {
let res = await fetch(`/djenterator/${ template_name } `);
if(res.status == 200) {
source = await res.text();
last_good = source;
detect_language(template_name);
try {
renderer = template(source);
// tag this template renderer so that we don't try to render it against the wrong one
renderer._template = template_name;
render_template();
} catch(error) {
log.error(error);
notice = `${ error . message } `;
results = source;
}
} else {
notice = `Error loading ${ template_name } : ${ res . status } `;
}
}
const copy_code = () => {
navigator.clipboard.writeText(results).then(() => {
notice = "Code copied to clipboard.";
}, () => {
notice = "Failed copying to clipboard.";
});
}
$: if(variable_json) render_template();
// this reload the templates when you click on a new one
const re_render = async (what) => {
await load_variables(what);
await load_template(what);
}
$: if(selected_template) re_render(selected_template);
onMount(async () => await list_generators());
< / script >
< style >
textarea.editor {
height: 15em;
background-color: var(--value0);
color: var(--value9);
}
< / style >
< Layout fullscreen = { true } header= { false } footer = { false } testid="page-bando-djenterator" >
< blockstart style = "width: 100%" >
< block style = "--w: 100%" >
< select bind:value = { selected_template } >
{ #each generators as template }
< option value = { template } > { template } </option >
{ /each }
< / select >
< textarea class = "editor" bind:value = { variable_json } > </textarea >
{ #if notice }
< callout class = "error" > { notice } </ callout >
{ /if }
{ #if results }
< Code on:copy = { send_toast ( "Copied to clipboard!" ) } content= { results } language = { language } / >
{ /if }
< / block >
< / blockstart >
< Toasts bind:send_toast fade_after = { 10000 } orientation="bottom right " />
< / Layout >