mirror of
https://github.com/LukeHagar/toasty.git
synced 2025-12-06 04:21:49 +00:00
180 lines
6.2 KiB
Svelte
180 lines
6.2 KiB
Svelte
<script lang="ts">
|
|
import { Button } from '$lib/components/ui/button';
|
|
import { Badge } from '$lib/components/ui/badge';
|
|
import { Separator } from '$lib/components/ui/separator';
|
|
import { Plus, FileText, Settings, Download, Upload, Info } from 'lucide-svelte';
|
|
|
|
import VersionAwareSchemaTypes from '$lib/components/schema/VersionAwareSchemaTypes.svelte';
|
|
import VersionAwareAPIComponents from '$lib/components/schema/VersionAwareAPIComponents.svelte';
|
|
import DragDropCanvas from '$lib/components/schema/DragDropCanvas.svelte';
|
|
import PropertyEditor from '$lib/components/schema/PropertyEditor.svelte';
|
|
import ExportDialog from '$lib/components/schema/ExportDialog.svelte';
|
|
import InfoEditor from '$lib/components/structure/InfoEditor.svelte';
|
|
import ServersEditor from '$lib/components/structure/ServersEditor.svelte';
|
|
import SecurityEditor from '$lib/components/structure/SecurityEditor.svelte';
|
|
import PathsEditor from '$lib/components/structure/PathsEditor.svelte';
|
|
import { schemaStore } from '$lib/stores/schema';
|
|
import { getVersionConfig } from '$lib/utils/openapi-versions';
|
|
|
|
let versionConfig = $derived(getVersionConfig($schemaStore.openApiVersion));
|
|
let showExportDialog = $state(false);
|
|
let showPreviewDialog = $state(false);
|
|
let activePanel = $state<'schemas' | 'paths' | 'info' | 'servers' | 'security'>('schemas');
|
|
|
|
function handleExport() {
|
|
showExportDialog = true;
|
|
}
|
|
|
|
function handlePreview() {
|
|
showPreviewDialog = true;
|
|
}
|
|
</script>
|
|
|
|
<div class="flex h-screen bg-background">
|
|
<!-- Sidebar -->
|
|
<div class="w-80 bg-sidebar border-r border-sidebar-border flex flex-col">
|
|
<!-- Header -->
|
|
<div class="p-6 border-b border-sidebar-border">
|
|
<h1 class="text-2xl font-bold text-sidebar-foreground">OpenAPI Designer</h1>
|
|
<p class="text-sm text-sidebar-foreground/70 mt-1">Drag & drop schema builder</p>
|
|
</div>
|
|
|
|
<!-- Version Selector -->
|
|
<div class="p-4 border-b border-sidebar-border">
|
|
<label class="text-sm font-medium text-sidebar-foreground mb-2 block" for="openapi-version">OpenAPI Version</label>
|
|
<select
|
|
id="openapi-version"
|
|
class="w-full p-2 rounded-md bg-sidebar-accent border border-sidebar-border text-sidebar-accent-foreground"
|
|
bind:value={$schemaStore.openApiVersion}
|
|
>
|
|
<option value="3.1.0">OpenAPI 3.1.0</option>
|
|
<option value="3.0.3">OpenAPI 3.0.3</option>
|
|
<option value="2.0">Swagger 2.0</option>
|
|
</select>
|
|
|
|
<!-- Version info -->
|
|
<div class="mt-2 p-2 bg-sidebar-accent/50 rounded text-xs">
|
|
<div class="flex items-center gap-1 mb-1">
|
|
<Info class="w-3 h-3" />
|
|
<span class="font-medium">Version Features</span>
|
|
</div>
|
|
<div class="space-y-1 text-sidebar-foreground/70">
|
|
<div>Types: {versionConfig.supportedTypes.length}</div>
|
|
<div>Nullable: {versionConfig.features.nullable ? 'Yes' : 'No'}</div>
|
|
<div>Callbacks: {versionConfig.features.callbacks ? 'Yes' : 'No'}</div>
|
|
<div>Webhooks: {versionConfig.features.webhooks ? 'Yes' : 'No'}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Navigation & Editors -->
|
|
<div class="flex-1 p-4 overflow-y-auto space-y-3">
|
|
<div class="grid grid-cols-2 gap-2">
|
|
<Button size="sm" variant={activePanel === 'schemas' ? 'default' : 'outline'} onclick={() => activePanel = 'schemas'}>Schemas</Button>
|
|
<Button size="sm" variant={activePanel === 'paths' ? 'default' : 'outline'} onclick={() => activePanel = 'paths'}>Paths</Button>
|
|
<Button size="sm" variant={activePanel === 'info' ? 'default' : 'outline'} onclick={() => activePanel = 'info'}>Info</Button>
|
|
<Button size="sm" variant={activePanel === 'servers' ? 'default' : 'outline'} onclick={() => activePanel = 'servers'}>Servers</Button>
|
|
<Button size="sm" variant={activePanel === 'security' ? 'default' : 'outline'} onclick={() => activePanel = 'security'}>Security</Button>
|
|
</div>
|
|
|
|
{#if activePanel === 'schemas'}
|
|
<VersionAwareSchemaTypes />
|
|
<Separator class="my-4" />
|
|
<VersionAwareAPIComponents />
|
|
{/if}
|
|
|
|
{#if activePanel === 'paths'}
|
|
<PathsEditor />
|
|
{/if}
|
|
|
|
{#if activePanel === 'info'}
|
|
<InfoEditor />
|
|
{/if}
|
|
|
|
{#if activePanel === 'servers'}
|
|
<ServersEditor />
|
|
{/if}
|
|
|
|
{#if activePanel === 'security'}
|
|
<SecurityEditor />
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="p-4 border-t border-sidebar-border">
|
|
<div class="flex gap-2">
|
|
<Button size="sm" class="flex-1">
|
|
<Upload class="w-4 h-4 mr-2" />
|
|
Import
|
|
</Button>
|
|
<Button size="sm" variant="outline" class="flex-1" onclick={handleExport}>
|
|
<Download class="w-4 h-4 mr-2" />
|
|
Export
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Content Area -->
|
|
<div class="flex-1 flex flex-col">
|
|
<!-- Toolbar -->
|
|
<div class="h-14 border-b border-border bg-card flex items-center justify-between px-6">
|
|
<div class="flex items-center gap-4">
|
|
<h2 class="font-semibold text-card-foreground">Schema Designer</h2>
|
|
<Badge variant="outline">
|
|
{$schemaStore.schemas.length + $schemaStore.endpoints.length} components
|
|
</Badge>
|
|
<Badge variant="secondary" class="text-xs">
|
|
{versionConfig.displayName}
|
|
</Badge>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<Button size="sm" variant="outline">
|
|
<Settings class="w-4 h-4 mr-2" />
|
|
Settings
|
|
</Button>
|
|
<Button size="sm" onclick={handlePreview}>
|
|
<FileText class="w-4 h-4 mr-2" />
|
|
Preview
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Canvas Area -->
|
|
<div class="flex-1 p-6 overflow-auto">
|
|
{#if activePanel === 'schemas'}
|
|
<div class="max-w-full mx-auto">
|
|
<DragDropCanvas />
|
|
</div>
|
|
{:else}
|
|
<div class="max-w-full mx-auto text-sm text-muted-foreground">
|
|
Use the sidebar to manage {activePanel}.
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Properties Panel -->
|
|
<div class="w-80 bg-card border-l border-border flex flex-col">
|
|
<div class="p-4 border-b border-border">
|
|
<h3 class="font-semibold text-card-foreground">Properties</h3>
|
|
<p class="text-sm text-muted-foreground mt-1">Configure selected component</p>
|
|
</div>
|
|
<div class="flex-1 p-4 overflow-y-auto">
|
|
<PropertyEditor />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Export Dialog -->
|
|
<ExportDialog
|
|
open={showExportDialog}
|
|
onClose={() => showExportDialog = false}
|
|
/>
|
|
|
|
<!-- Preview Dialog (reuse ExportDialog for now) -->
|
|
<ExportDialog
|
|
open={showPreviewDialog}
|
|
onClose={() => showPreviewDialog = false}
|
|
/>
|