126 lines
3.4 KiB
Svelte
126 lines
3.4 KiB
Svelte
<script lang="ts">
|
|
import { tick } from 'svelte';
|
|
import AppIcon from './AppIcon.svelte';
|
|
import ChoicePicker from './ChoicePicker.svelte';
|
|
import IconPicker from './IconPicker.svelte';
|
|
|
|
type Format = { id: string; name: string };
|
|
type Tool = {
|
|
id: string;
|
|
name: string;
|
|
startUrl: string;
|
|
description: string;
|
|
iconName: string;
|
|
isActive: boolean;
|
|
formatIds: string[];
|
|
};
|
|
|
|
let { formats }: { formats: Format[] } = $props();
|
|
let dialog: HTMLDialogElement;
|
|
let nameInput: HTMLInputElement;
|
|
let tool = $state<Tool | null>(null);
|
|
let name = $state('');
|
|
let startUrl = $state('');
|
|
let description = $state('');
|
|
let iconName = $state('wrench');
|
|
let isActive = $state(true);
|
|
let formatIds = $state<string[]>([]);
|
|
|
|
export async function showModal(selectedTool: Tool | null = null) {
|
|
tool = selectedTool;
|
|
name = selectedTool?.name ?? '';
|
|
startUrl = selectedTool?.startUrl ?? '';
|
|
description = selectedTool?.description ?? '';
|
|
iconName = selectedTool?.iconName || 'wrench';
|
|
isActive = selectedTool?.isActive ?? true;
|
|
formatIds = [...(selectedTool?.formatIds ?? [])];
|
|
dialog.showModal();
|
|
await tick();
|
|
nameInput.focus();
|
|
}
|
|
|
|
function close() {
|
|
dialog.close();
|
|
}
|
|
</script>
|
|
|
|
<dialog
|
|
bind:this={dialog}
|
|
class="management-dialog tool-editor-dialog"
|
|
aria-labelledby="tool-dialog-title"
|
|
onclick={(event) => event.target === dialog && close()}
|
|
>
|
|
<header>
|
|
<div class="management-dialog-title">
|
|
<span class="management-dialog-icon"><AppIcon name={iconName || 'wrench'} /></span>
|
|
<div>
|
|
<p class="eyebrow">{tool ? 'Werkzeug bearbeiten' : 'Werkzeug hinzufügen'}</p>
|
|
<h2 id="tool-dialog-title">{tool?.name || 'Neues Werkzeug'}</h2>
|
|
</div>
|
|
</div>
|
|
<button class="dialog-close" type="button" aria-label="Werkzeugdialog schließen" onclick={close}
|
|
><AppIcon name="xmark" /></button
|
|
>
|
|
</header>
|
|
<form
|
|
class="management-dialog-form"
|
|
method="POST"
|
|
action={tool ? '?/updateTool' : '?/createTool'}
|
|
>
|
|
{#if tool}<input type="hidden" name="toolId" value={tool.id} />{/if}
|
|
<div class="management-dialog-fields">
|
|
<label
|
|
>Name<input
|
|
bind:this={nameInput}
|
|
bind:value={name}
|
|
name="name"
|
|
required
|
|
maxlength="120"
|
|
/></label
|
|
>
|
|
<label
|
|
>Start-URL<input
|
|
bind:value={startUrl}
|
|
name="startUrl"
|
|
type="url"
|
|
maxlength="2000"
|
|
placeholder="https://…"
|
|
/></label
|
|
>
|
|
<label class="wide-field"
|
|
>Beschreibung<textarea bind:value={description} name="description" rows="3" maxlength="2000"
|
|
></textarea></label
|
|
>
|
|
</div>
|
|
<div class="management-dialog-selections">
|
|
<div>
|
|
<span class="field-label">Icon</span>
|
|
<IconPicker bind:name={iconName} />
|
|
</div>
|
|
<div>
|
|
<span class="field-label">Passende Formate</span>
|
|
<ChoicePicker
|
|
items={formats}
|
|
selectedIds={formatIds}
|
|
label="Formate"
|
|
fieldName="formatIds"
|
|
onselectionchange={(ids) => (formatIds = ids)}
|
|
/>
|
|
</div>
|
|
<label class="toggle-row"
|
|
><input type="checkbox" name="isActive" value="1" bind:checked={isActive} /><span
|
|
><strong>Aktiv</strong><small
|
|
>Deaktivierte Werkzeuge bleiben in bestehenden Pieces erhalten.</small
|
|
></span
|
|
></label
|
|
>
|
|
</div>
|
|
<footer>
|
|
<button class="secondary-button" type="button" onclick={close}>Abbrechen</button>
|
|
<button class="primary-button" type="submit"
|
|
>{tool ? 'Änderungen speichern' : 'Werkzeug anlegen'}</button
|
|
>
|
|
</footer>
|
|
</form>
|
|
</dialog>
|