Skip to main content
Glama
+page.svelte7.14 kB
<script> import { goto } from '$app/navigation'; let form = { name: '', environment_type: 'development', description: '', url: '', status: 'active', tags: [], project_id: '' }; let projects = []; let newTag = ''; let loading = false; let error = null; // 프로젝트 목록 로드 (선택사항) import { onMount } from 'svelte'; onMount(async () => { try { const response = await fetch('/api/projects'); if (response.ok) { projects = await response.json(); } } catch (e) { console.error('프로젝트 목록 로드 실패:', e); } }); function addTag() { if (newTag.trim() && !form.tags.includes(newTag.trim())) { form.tags = [...form.tags, newTag.trim()]; newTag = ''; } } function removeTag(tagToRemove) { form.tags = form.tags.filter(tag => tag !== tagToRemove); } function handleTagKeydown(event) { if (event.key === 'Enter') { event.preventDefault(); addTag(); } } async function handleSubmit() { if (!form.name.trim()) { error = '환경 이름을 입력해주세요'; return; } try { loading = true; error = null; const response = await fetch('/api/environments', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form) }); if (response.ok) { const result = await response.json(); goto(`/environments/${result.id}`); } else { const errorData = await response.json(); error = errorData.error || '환경 생성 중 오류가 발생했습니다'; } } catch (e) { error = '환경 생성 중 오류: ' + e.message; } finally { loading = false; } } function handleCancel() { goto('/environments'); } </script> <svelte:head> <title>새 환경 생성 - WorkflowMCP</title> </svelte:head> <div class="container mx-auto px-4 py-8"> <div class="flex justify-between items-center mb-6"> <div class="flex items-center gap-4"> <button on:click={handleCancel} class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg flex items-center gap-2" > ← 목록으로 </button> <h1 class="text-3xl font-bold text-gray-900">새 환경 생성</h1> </div> </div> <div class="bg-white rounded-lg shadow p-6"> {#if error} <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> {error} </div> {/if} <form on:submit|preventDefault={handleSubmit} class="space-y-6"> <!-- 환경 이름 --> <div> <label for="name" class="block text-sm font-medium text-gray-700 mb-2"> 환경 이름 <span class="text-red-500">*</span> </label> <input id="name" bind:value={form.name} type="text" required class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="예: Production API Server" /> </div> <!-- 환경 유형 --> <div> <label for="environment_type" class="block text-sm font-medium text-gray-700 mb-2"> 환경 유형 <span class="text-red-500">*</span> </label> <select id="environment_type" bind:value={form.environment_type} required class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" > <option value="development">Development</option> <option value="staging">Staging</option> <option value="production">Production</option> <option value="testing">Testing</option> </select> </div> <!-- 설명 --> <div> <label for="description" class="block text-sm font-medium text-gray-700 mb-2"> 설명 </label> <textarea id="description" bind:value={form.description} rows="3" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="환경에 대한 설명을 입력해주세요" ></textarea> </div> <!-- URL --> <div> <label for="url" class="block text-sm font-medium text-gray-700 mb-2"> URL </label> <input id="url" bind:value={form.url} type="url" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="https://api.example.com" /> </div> <!-- 상태 --> <div> <label for="status" class="block text-sm font-medium text-gray-700 mb-2"> 상태 </label> <select id="status" bind:value={form.status} class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" > <option value="active">활성</option> <option value="inactive">비활성</option> <option value="maintenance">점검중</option> </select> </div> <!-- 태그 --> <div> <label class="block text-sm font-medium text-gray-700 mb-2"> 태그 </label> <div class="flex flex-wrap gap-2 mb-2"> {#each form.tags as tag} <span class="px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm flex items-center gap-2"> {tag} <button type="button" on:click={() => removeTag(tag)} class="text-blue-500 hover:text-blue-700" > × </button> </span> {/each} </div> <div class="flex gap-2"> <input bind:value={newTag} on:keydown={handleTagKeydown} type="text" placeholder="태그를 입력하고 Enter를 누르세요" class="flex-1 border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" /> <button type="button" on:click={addTag} class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300" > 추가 </button> </div> </div> <!-- 프로젝트 (선택사항) --> {#if projects.length > 0} <div> <label for="project_id" class="block text-sm font-medium text-gray-700 mb-2"> 프로젝트 (선택사항) </label> <select id="project_id" bind:value={form.project_id} class="w-full border border-gray-300 rounded-md px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500" > <option value="">프로젝트 선택 안함</option> {#each projects as project} <option value={project.id}>{project.name}</option> {/each} </select> </div> {/if} <!-- 제출 버튼 --> <div class="flex justify-end gap-4 pt-6 border-t"> <button type="button" on:click={handleCancel} class="px-6 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50" > 취소 </button> <button type="submit" disabled={loading || !form.name.trim()} class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2" > {#if loading} <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div> {/if} {loading ? '생성 중...' : '환경 생성'} </button> </div> </form> </div> </div>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/foswmine/workflow-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server