feat(apps): add asJson for customcss

This commit is contained in:
Ruben Fiszel
2023-02-19 13:10:57 +01:00
parent 7f00e1c1a8
commit 71d6dad37c
@@ -1,6 +1,8 @@
<script lang="ts">
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import Tooltip from '$lib/components/Tooltip.svelte'
import { emptyString } from '$lib/utils'
import { faAngleDown } from '@fortawesome/free-solid-svg-icons'
import { LayoutDashboardIcon } from 'lucide-svelte'
import { getContext } from 'svelte'
@@ -12,8 +14,28 @@
const { app } = getContext<AppEditorContext>('AppEditorContext')
function switchTab(detail: any): void {
throw new Error('Function not implemented.')
let rawCode = ''
let viewJsonSchema = false
$: rawCode && parseJson()
let jsonError = ''
function parseJson() {
try {
$app.css = JSON.parse(rawCode ?? '')
jsonError = ''
} catch (e) {
jsonError = e.message
}
}
function switchTab(asJson: boolean) {
viewJsonSchema = asJson
if (asJson) {
rawCode = JSON.stringify($app.css, null, 2)
} else {
parseJson()
}
}
const entries: { type: 'app' | AppComponent['type']; name: string; icon: any; ids: string[] }[] =
@@ -62,64 +84,71 @@
$app.css = newCss
</script>
<div class="flex items-center">
<div class="flex flex-row-reverse px-2">
<Toggle
on:change={(e) => switchTab(e.detail)}
options={{
right: 'As JSON'
}}
/>
<div class="ml-2">
<Tooltip>
Arguments can be edited either using the wizard, or by editing their JSON Schema,
<a href="https://docs.windmill.dev/docs/reference/#script-parameters-to-json-schema"
>see docs</a
>
</Tooltip>
</div>
</div>
<div class="flex flex-col gap-2 p-1">
{#each entries as { type, name, icon, ids }}
{#if ids.length > 0}
<div>
<button
on:click|preventDefault={() => ($isOpenStoreCss[type] = !$isOpenStoreCss[type])}
class="w-full flex justify-between items-center px-1 py-1
{#if !viewJsonSchema}
<div class="flex flex-col gap-2 p-1">
{#each entries as { type, name, icon, ids }}
{#if ids.length > 0}
<div>
<button
on:click|preventDefault={() => ($isOpenStoreCss[type] = !$isOpenStoreCss[type])}
class="w-full flex justify-between items-center px-1 py-1
rounded-sm duration-200 hover:bg-gray-100"
>
<h3 class="inline-flex gap-2 {isCustom[type] ? 'text-gray-800' : 'text-gray-500'}"
>{name} <svelte:component this={icon} />
</h3>
<Icon
data={faAngleDown}
class="rotate-0 duration-300 {$isOpenStoreCss[type] ? '!rotate-180' : ''}"
/>
</button>
{#if $isOpenStoreCss[type]}
<div transition:slide|local={{ duration: 300 }} class="flex flex-col px-2 border">
{#each ids as id}
<div class="mb-2">
<div class="mt-1 font-semibold">{id}</div>
{#if $app?.css?.[type]?.[id]}
<span class="text-xs">style</span>
<input
type="text"
on:focus={() => (isCustom[type] = true)}
bind:value={$app.css[type][id].style}
/>
<span class="text-xs">class</span>
<input
type="text"
on:focus={() => (isCustom[type] = true)}
bind:value={$app.css[type][id].class}
/>
{/if}
</div>
{/each}
</div>
{/if}
</div>
{/if}
{/each}
</div>
>
<h3 class="inline-flex gap-2 {isCustom[type] ? 'text-gray-800' : 'text-gray-500'}"
>{name} <svelte:component this={icon} />
</h3>
<Icon
data={faAngleDown}
class="rotate-0 duration-300 {$isOpenStoreCss[type] ? '!rotate-180' : ''}"
/>
</button>
{#if $isOpenStoreCss[type]}
<div transition:slide|local={{ duration: 300 }} class="flex flex-col px-2 border">
{#each ids as id}
<div class="mb-2">
<div class="mt-1 font-semibold">{id}</div>
{#if $app?.css?.[type]?.[id]}
<span class="text-xs">style</span>
<input
type="text"
on:focus={() => (isCustom[type] = true)}
bind:value={$app.css[type][id].style}
/>
<span class="text-xs">class</span>
<input
type="text"
on:focus={() => (isCustom[type] = true)}
bind:value={$app.css[type][id].class}
/>
{/if}
</div>
{/each}
</div>
{/if}
</div>
{/if}
{/each}
</div>
{:else}
{#if !emptyString(jsonError)}<span class="text-red-400 text-xs mb-1 flex flex-row-reverse"
>{jsonError}</span
>{:else}<div class="py-2" />{/if}
<div class="h-full w-full border p-1 rounded">
<SimpleEditor
autoHeight
class="editor"
lang="json"
bind:code={rawCode}
fixedOverflowWidgets={false}
/>
</div>
{/if}