From 009f698a9fc6b2466f604695aafea0523cc8952a Mon Sep 17 00:00:00 2001 From: chyoo Date: Thu, 9 Jul 2026 14:53:39 +0900 Subject: [PATCH] add runtime profile deletion and refine config forms --- src/pages/runtime/RuntimeConfigPage.tsx | 69 +++++++++++++++++++++++-- src/pages/runtime/runtime-api.ts | 6 +++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/pages/runtime/RuntimeConfigPage.tsx b/src/pages/runtime/RuntimeConfigPage.tsx index c180984..6f6eb3b 100644 --- a/src/pages/runtime/RuntimeConfigPage.tsx +++ b/src/pages/runtime/RuntimeConfigPage.tsx @@ -14,6 +14,7 @@ import { createRuntimeProfile, createRuntimeVariable, deleteRuntimeIngressRule, + deleteRuntimeProfile, deleteRuntimeVariable, loadApps, loadRuntimeProfiles, @@ -80,6 +81,7 @@ export function RuntimeConfigPage() { const [actionKey, setActionKey] = useState(''); const [error, setError] = useState(''); const [profileModalOpen, setProfileModalOpen] = useState(false); + const [deleteProfileTarget, setDeleteProfileTarget] = useState(null); const [deleteVariableTarget, setDeleteVariableTarget] = useState(null); const [deleteIngressTarget, setDeleteIngressTarget] = useState(null); const loadingVisible = useMinimumLoading(loading); @@ -116,6 +118,7 @@ export function RuntimeConfigPage() { profile.environment === profileEnvironment && profile.namespace.trim() === profileNamespace.trim() )); + const showDuplicateProfileWarning = Boolean(profileName.trim() && duplicateProfile); const refreshResources = (targetNamespace = namespace) => { if (!targetNamespace.trim()) { @@ -235,6 +238,23 @@ export function RuntimeConfigPage() { .catch((createError: Error) => setError(createError.message)); }; + const removeProfile = () => { + if (!deleteProfileTarget) return; + const target = deleteProfileTarget; + setActionKey(`profile-delete-${target.id}`); + deleteRuntimeProfile(target.id) + .then(() => { + toast({ type: 'success', title: '프로필 삭제', message: `${target.name} 프로필을 삭제했습니다.` }); + setDeleteProfileTarget(null); + return refreshProfiles(appId); + }) + .catch((deleteError: Error) => { + setError(deleteError.message); + toast({ type: 'error', title: '프로필 삭제 실패', message: deleteError.message }); + }) + .finally(() => setActionKey('')); + }; + const addVariable = () => { if (!selectedProfile || !variableComponentId || !variableKey.trim() || !variableValue.trim()) return; const profile = selectedProfile; @@ -367,6 +387,13 @@ export function RuntimeConfigPage() { }); }; + const openProfileModal = () => { + setProfileName(''); + setProfileEnvironment('dev'); + setProfileNamespace(selectedApp?.namespace ?? ''); + setProfileModalOpen(true); + }; + return ( <> setProfileModalOpen(true)} disabled={!appId}> + @@ -475,6 +502,19 @@ export function RuntimeConfigPage() { 수정 {formatDate(profile.updatedAt ?? profile.createdAt)} + ))} @@ -699,7 +739,7 @@ export function RuntimeConfigPage() { footer={( <> - + )} > @@ -728,13 +768,36 @@ export function RuntimeConfigPage() { {namespaceOptions.map((item) =>