2022-10-30 16:28:14 +08:00
|
|
|
<script context="module">
|
|
|
|
let cachedEditorComponent;
|
|
|
|
</script>
|
|
|
|
|
2022-08-15 00:30:45 +08:00
|
|
|
<script>
|
|
|
|
import { scale } from "svelte/transition";
|
|
|
|
import tooltip from "@/actions/tooltip";
|
|
|
|
import { errors, removeError } from "@/stores/errors";
|
|
|
|
import { addInfoToast } from "@/stores/toasts";
|
|
|
|
import CommonHelper from "@/utils/CommonHelper";
|
|
|
|
import Field from "@/components/base/Field.svelte";
|
2022-08-16 12:36:15 +08:00
|
|
|
import Accordion from "@/components/base/Accordion.svelte";
|
2022-08-15 00:30:45 +08:00
|
|
|
|
|
|
|
export let key;
|
|
|
|
export let title;
|
|
|
|
export let config = {};
|
|
|
|
|
|
|
|
let accordion;
|
2022-10-30 16:28:14 +08:00
|
|
|
let editorComponent = cachedEditorComponent;
|
2022-08-16 12:36:15 +08:00
|
|
|
let isEditorComponentLoading = false;
|
2022-08-15 00:30:45 +08:00
|
|
|
|
|
|
|
$: hasErrors = !CommonHelper.isEmpty(CommonHelper.getNestedVal($errors, key));
|
|
|
|
|
|
|
|
$: if (!config.enabled) {
|
|
|
|
removeError(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function expand() {
|
|
|
|
accordion?.expand();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function collapse() {
|
|
|
|
accordion?.collapse();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function collapseSiblings() {
|
|
|
|
accordion?.collapseSiblings();
|
|
|
|
}
|
|
|
|
|
2022-08-16 12:36:15 +08:00
|
|
|
async function loadEditorComponent() {
|
|
|
|
if (editorComponent || isEditorComponentLoading) {
|
|
|
|
return; // already loaded or in the process
|
|
|
|
}
|
|
|
|
|
|
|
|
isEditorComponentLoading = true;
|
|
|
|
|
|
|
|
editorComponent = (await import("@/components/base/CodeEditor.svelte")).default;
|
|
|
|
|
2022-10-30 16:28:14 +08:00
|
|
|
cachedEditorComponent = editorComponent;
|
|
|
|
|
2022-08-16 12:36:15 +08:00
|
|
|
isEditorComponentLoading = false;
|
|
|
|
}
|
|
|
|
|
2022-08-15 00:30:45 +08:00
|
|
|
function copy(param) {
|
|
|
|
CommonHelper.copyToClipboard(param);
|
|
|
|
addInfoToast(`Copied ${param} to clipboard`, 2000);
|
|
|
|
}
|
2022-08-21 19:30:36 +08:00
|
|
|
|
|
|
|
loadEditorComponent();
|
2022-08-15 00:30:45 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<Accordion bind:this={accordion} on:expand on:collapse on:toggle {...$$restProps}>
|
|
|
|
<svelte:fragment slot="header">
|
|
|
|
<div class="inline-flex">
|
|
|
|
<i class="ri-draft-line" />
|
|
|
|
<span class="txt">{title}</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex-fill" />
|
|
|
|
|
|
|
|
{#if hasErrors}
|
|
|
|
<i
|
|
|
|
class="ri-error-warning-fill txt-danger"
|
2023-01-08 04:25:56 +08:00
|
|
|
transition:scale|local={{ duration: 150, start: 0.7 }}
|
2022-08-15 00:30:45 +08:00
|
|
|
use:tooltip={{ text: "Has errors", position: "left" }}
|
|
|
|
/>
|
|
|
|
{/if}
|
|
|
|
</svelte:fragment>
|
|
|
|
|
|
|
|
<Field class="form-field required" name="{key}.subject" let:uniqueId>
|
|
|
|
<label for={uniqueId}>Subject</label>
|
|
|
|
<input type="text" id={uniqueId} bind:value={config.subject} spellcheck="false" required />
|
|
|
|
<div class="help-block">
|
|
|
|
Available placeholder parameters:
|
2023-01-17 19:31:48 +08:00
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_NAME}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_NAME}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_URL}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_URL}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>.
|
2022-08-15 00:30:45 +08:00
|
|
|
</div>
|
|
|
|
</Field>
|
|
|
|
|
|
|
|
<Field class="form-field required" name="{key}.actionUrl" let:uniqueId>
|
|
|
|
<label for={uniqueId}>Action URL</label>
|
|
|
|
<input type="text" id={uniqueId} bind:value={config.actionUrl} spellcheck="false" required />
|
|
|
|
<div class="help-block">
|
|
|
|
Available placeholder parameters:
|
2023-01-17 19:31:48 +08:00
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_NAME}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_NAME}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_URL}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_URL}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
2022-08-15 00:30:45 +08:00
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
title="Required parameter"
|
2023-01-17 19:31:48 +08:00
|
|
|
on:click={() => copy("{TOKEN}")}
|
|
|
|
>
|
|
|
|
{"{TOKEN}"}
|
|
|
|
</button>.
|
2022-08-15 00:30:45 +08:00
|
|
|
</div>
|
|
|
|
</Field>
|
|
|
|
|
|
|
|
<Field class="form-field m-0 required" name="{key}.body" let:uniqueId>
|
|
|
|
<label for={uniqueId}>Body (HTML)</label>
|
2022-08-16 12:36:15 +08:00
|
|
|
|
|
|
|
{#if editorComponent && !isEditorComponentLoading}
|
2022-08-21 19:30:36 +08:00
|
|
|
<svelte:component this={editorComponent} id={uniqueId} language="html" bind:value={config.body} />
|
2022-08-16 12:36:15 +08:00
|
|
|
{:else}
|
|
|
|
<textarea
|
|
|
|
id={uniqueId}
|
|
|
|
class="txt-mono"
|
|
|
|
spellcheck="false"
|
2022-08-21 19:30:36 +08:00
|
|
|
rows="14"
|
2022-08-16 12:36:15 +08:00
|
|
|
required
|
|
|
|
bind:value={config.body}
|
|
|
|
/>
|
|
|
|
{/if}
|
|
|
|
|
2022-08-15 00:30:45 +08:00
|
|
|
<div class="help-block">
|
|
|
|
Available placeholder parameters:
|
2023-01-17 19:31:48 +08:00
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_NAME}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_NAME}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{APP_URL}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{APP_URL}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
on:click={() => copy("{TOKEN}")}
|
|
|
|
>
|
2022-08-15 00:30:45 +08:00
|
|
|
{"{TOKEN}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>,
|
|
|
|
<button
|
|
|
|
type="button"
|
2022-08-15 00:30:45 +08:00
|
|
|
class="label label-sm link-primary txt-mono"
|
|
|
|
title="Required parameter"
|
|
|
|
on:click={() => copy("{ACTION_URL}")}
|
|
|
|
>
|
|
|
|
{"{ACTION_URL}"}
|
2023-01-17 19:31:48 +08:00
|
|
|
</button>.
|
2022-08-15 00:30:45 +08:00
|
|
|
</div>
|
|
|
|
</Field>
|
|
|
|
</Accordion>
|