diff options
Diffstat (limited to 'ui/src/components/InstancesView.svelte')
| -rw-r--r-- | ui/src/components/InstancesView.svelte | 110 |
1 files changed, 19 insertions, 91 deletions
diff --git a/ui/src/components/InstancesView.svelte b/ui/src/components/InstancesView.svelte index a4881e6..5334f9e 100644 --- a/ui/src/components/InstancesView.svelte +++ b/ui/src/components/InstancesView.svelte @@ -3,12 +3,15 @@ import { instancesState } from "../stores/instances.svelte"; import { Plus, Trash2, Edit2, Copy, Check, X } from "lucide-svelte"; import type { Instance } from "../types"; + import InstanceCreationModal from "./InstanceCreationModal.svelte"; + import InstanceEditorModal from "./InstanceEditorModal.svelte"; let showCreateModal = $state(false); let showEditModal = $state(false); let showDeleteConfirm = $state(false); let showDuplicateModal = $state(false); let selectedInstance: Instance | null = $state(null); + let editingInstance: Instance | null = $state(null); let newInstanceName = $state(""); let duplicateName = $state(""); @@ -17,14 +20,11 @@ }); function handleCreate() { - newInstanceName = ""; showCreateModal = true; } function handleEdit(instance: Instance) { - selectedInstance = instance; - newInstanceName = instance.name; - showEditModal = true; + editingInstance = instance; } function handleDelete(instance: Instance) { @@ -38,24 +38,6 @@ showDuplicateModal = true; } - async function confirmCreate() { - if (!newInstanceName.trim()) return; - await instancesState.createInstance(newInstanceName.trim()); - showCreateModal = false; - newInstanceName = ""; - } - - async function confirmEdit() { - if (!selectedInstance || !newInstanceName.trim()) return; - await instancesState.updateInstance({ - ...selectedInstance, - name: newInstanceName.trim(), - }); - showEditModal = false; - selectedInstance = null; - newInstanceName = ""; - } - async function confirmDelete() { if (!selectedInstance) return; await instancesState.deleteInstance(selectedInstance.id); @@ -111,10 +93,13 @@ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> {#each instancesState.instances as instance (instance.id)} <div + role="button" + tabindex="0" class="relative p-4 bg-gray-100 dark:bg-gray-800 rounded-lg border-2 transition-all cursor-pointer hover:border-blue-500 {instancesState.activeInstanceId === instance.id ? 'border-blue-500' : 'border-transparent'}" onclick={() => instancesState.setActiveInstance(instance.id)} + onkeydown={(e) => e.key === "Enter" && instancesState.setActiveInstance(instance.id)} > {#if instancesState.activeInstanceId === instance.id} <div class="absolute top-2 right-2"> @@ -128,6 +113,7 @@ </h3> <div class="flex gap-1"> <button + type="button" onclick={(e) => { e.stopPropagation(); handleEdit(instance); @@ -138,6 +124,7 @@ <Edit2 size={16} class="text-gray-600 dark:text-gray-400" /> </button> <button + type="button" onclick={(e) => { e.stopPropagation(); handleDuplicate(instance); @@ -148,6 +135,7 @@ <Copy size={16} class="text-gray-600 dark:text-gray-400" /> </button> <button + type="button" onclick={(e) => { e.stopPropagation(); handleDelete(instance); @@ -195,75 +183,16 @@ </div> <!-- Create Modal --> -{#if showCreateModal} - <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> - <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96"> - <h2 class="text-xl font-bold mb-4 text-gray-900 dark:text-white">Create Instance</h2> - <input - type="text" - bind:value={newInstanceName} - placeholder="Instance name" - class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4" - onkeydown={(e) => e.key === "Enter" && confirmCreate()} - autofocus - /> - <div class="flex gap-2 justify-end"> - <button - onclick={() => { - showCreateModal = false; - newInstanceName = ""; - }} - class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors" - > - Cancel - </button> - <button - onclick={confirmCreate} - disabled={!newInstanceName.trim()} - class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors" - > - Create - </button> - </div> - </div> - </div> -{/if} +<InstanceCreationModal isOpen={showCreateModal} onClose={() => (showCreateModal = false)} /> -<!-- Edit Modal --> -{#if showEditModal && selectedInstance} - <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> - <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96"> - <h2 class="text-xl font-bold mb-4 text-gray-900 dark:text-white">Edit Instance</h2> - <input - type="text" - bind:value={newInstanceName} - placeholder="Instance name" - class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4" - onkeydown={(e) => e.key === "Enter" && confirmEdit()} - autofocus - /> - <div class="flex gap-2 justify-end"> - <button - onclick={() => { - showEditModal = false; - selectedInstance = null; - newInstanceName = ""; - }} - class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors" - > - Cancel - </button> - <button - onclick={confirmEdit} - disabled={!newInstanceName.trim()} - class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors" - > - Save - </button> - </div> - </div> - </div> -{/if} +<!-- Instance Editor Modal --> +<InstanceEditorModal + isOpen={editingInstance !== null} + instance={editingInstance} + onClose={() => { + editingInstance = null; + }} +/> <!-- Delete Confirmation --> {#if showDeleteConfirm && selectedInstance} @@ -305,7 +234,6 @@ placeholder="New instance name" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4" onkeydown={(e) => e.key === "Enter" && confirmDuplicate()} - autofocus /> <div class="flex gap-2 justify-end"> <button |