This is the template project that's checked out and configured when you run the bando-up command from ljsthw-bandolier. This is where the code really lives.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bandolier-template/admin/bando/Djenterator.svelte

258 lines
5.8 KiB

<script>
import template from "lodash/template";
import { fade } from "svelte/transition";
import Icon from "$/client/components/Icon.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 = "";
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) {
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 load_template = async (template_name) => {
let res = await fetch(`/djenterator/${template_name}`);
if(res.status == 200) {
source = await res.text();
last_good = source;
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 toggle_template = () => {
if(showing_rendered) {
render_template();
} else {
results = renderer.toString();
}
showing_rendered = !showing_rendered;
}
const copy_code = () => {
navigator.clipboard.writeText(results).then(() => {
notice = "Code copied to clipboard.";
}, () => {
notice = "Failed copying to clipboard.";
});
}
const canary = '3a025dba-1a62-4169-ae9f-f7cd4104c4f4';
log.debug("Canary is compiled into build as", canary);
$: 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>
content {
display: flex;
flex-direction: row;
width: 100%;
}
template-editor {
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
}
pre {
position: relative;
height: 90vh;
max-height: 90vh;
overflow-y: auto;
}
right pre {
display: flex;
font-size: 1em;
flex-basis: 100%;
margin: 0;
padding: 0;
}
right pre code {
padding-top: 2rem;
display: flex;
flex-basis: 100%;
border-radius: 0px 4px 4px 0px;
line-height: unset;
margin: 0;
}
left {
display: flex;
flex-grow: 1;
flex-basis: 70ch;
}
left textarea {
border-radius: 4px 0px 0px 4px;
margin: 0;
background-color: var(--color-secondary);
color: var(--color-bg);
height: 90vh;
max-height: 90vh;
}
right {
position: relative;
display: flex;
flex-direction: column;
flex-grow: 3;
flex-basis: 100ch;
align-items: stretch;
}
status {
position: absolute;
z-index: 100;
top: 0;
padding-right: 1rem;
padding-left: 1rem;
padding-top: 0.1rem;
width: 90%;
color: var(--color-bg);
display: flex;
box-sizing: border-box;
background-color: var(--color-secondary);
border-radius: 0px 4px 0px 0px;
justify-content: space-evenly;
}
status file {
flex-basis: 90%;
text-align: right;
}
status buttons {
display: flex;
justify-content: space-around;
flex-basis: 10%;
padding-top: 0.5rem;
}
pre notice {
position: absolute;
bottom: 0;
left: 0.3rem;
right: 0.3rem;
text-align: right;
padding: 0.5rem;
font-size: 1rem;
background-color: var(--color-bg-tertiary);
border-radius: 4px 4px 0px 0px;
}
</style>
<Layout fullscreen={ true } header={ false } testid="page-bando-djenterator">
<template-editor>
<select bind:value={ selected_template }>
{#each generators as template}
<option value={ template }>{ template }</option>
{/each}
</select>
<content>
<left>
<textarea class="editor" bind:value={ variable_json } rows="15"></textarea>
</left>
<right>
<status>
<buttons>
<span on:click={ copy_code }><Icon name="copy" size="24" color="var(--color-bg)" /></span>
<span on:click={ toggle_template }><Icon name="code" size="24" color="var(--color-bg)" /></span>
</buttons>
<file>static/djenterator/{ selected_template }</file>
</status>
<pre>
<code>
{results}
</code>
{#if notice}
<notice in:fade on:click={ () => notice = "" }>
<b>{ notice }</b>
</notice>
{/if}
</pre>
</right>
</content>
<template-editor>
</Layout>