This commit is contained in:
@@ -80,6 +80,7 @@ export function DeploymentManagementPage() {
|
||||
const [deployModalOpen, setDeployModalOpen] = useState(false);
|
||||
const [selectedDeployment, setSelectedDeployment] = useState<DeploymentJob | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [deploying, setDeploying] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [range, setRange] = useState<DeploymentRange>('week');
|
||||
const [totalDeployments, setTotalDeployments] = useState(0);
|
||||
@@ -159,6 +160,8 @@ export function DeploymentManagementPage() {
|
||||
};
|
||||
|
||||
const deploy = async () => {
|
||||
if (deploying) return;
|
||||
setDeploying(true);
|
||||
try {
|
||||
const result = await createDeployment({ releaseId, environment: 'prod', namespace, updateLauncherAppVersion });
|
||||
toast({ type: 'success', message: '배포 작업이 실행되었습니다.' });
|
||||
@@ -167,6 +170,8 @@ export function DeploymentManagementPage() {
|
||||
await refresh();
|
||||
} catch (error) {
|
||||
toast({ type: 'error', message: error instanceof Error ? error.message : '배포 실행에 실패했습니다.' });
|
||||
} finally {
|
||||
setDeploying(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -310,9 +315,11 @@ export function DeploymentManagementPage() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Modal open={deployModalOpen} title="배포 실행" onClose={() => setDeployModalOpen(false)} footer={<><Button variant="outline" onClick={() => setDeployModalOpen(false)}>취소</Button><Button disabled={!releaseId || !namespace} onClick={deploy}>실행</Button></>}>
|
||||
<Modal open={deployModalOpen} title="배포 실행" onClose={() => {
|
||||
if (!deploying) setDeployModalOpen(false);
|
||||
}} footer={<><Button variant="outline" disabled={deploying} onClick={() => setDeployModalOpen(false)}>취소</Button><Button disabled={deploying || !releaseId || !namespace} onClick={deploy}>{deploying ? '실행 중' : '실행'}</Button></>}>
|
||||
<div className="space-y-3">
|
||||
<select className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm outline-none" value={releaseId} onChange={(event) => {
|
||||
<select className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm outline-none" value={releaseId} disabled={deploying} onChange={(event) => {
|
||||
const release = releases.find((item) => item.id === event.target.value);
|
||||
setReleaseId(event.target.value);
|
||||
setNamespace(release?.app.namespace || '');
|
||||
@@ -320,12 +327,13 @@ export function DeploymentManagementPage() {
|
||||
<option value="">릴리즈 선택</option>
|
||||
{deployableReleases.map((release) => <option key={release.id} value={release.id}>{release.app.name} {release.version}</option>)}
|
||||
</select>
|
||||
<input className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm outline-none" value={namespace} onChange={(event) => setNamespace(event.target.value)} placeholder="stdo-lms" />
|
||||
<input className="h-9 w-full rounded-md border border-input bg-background px-3 text-sm outline-none" value={namespace} disabled={deploying} onChange={(event) => setNamespace(event.target.value)} placeholder="stdo-lms" />
|
||||
<label className="flex items-center gap-2 rounded-md border border-border bg-muted/20 px-3 py-2 text-sm text-foreground">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="size-4 accent-primary"
|
||||
checked={updateLauncherAppVersion}
|
||||
disabled={deploying}
|
||||
onChange={(event) => setUpdateLauncherAppVersion(event.target.checked)}
|
||||
/>
|
||||
런처 앱 버전 업데이트
|
||||
|
||||
@@ -75,6 +75,7 @@ export function MigrationManagementPage() {
|
||||
const [selectedJob, setSelectedJob] = useState<RuntimeControlJob | null>(null);
|
||||
const [confirmOpen, setConfirmOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [runningMigration, setRunningMigration] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [range, setRange] = useState<MigrationRange>('week');
|
||||
const [totalJobs, setTotalJobs] = useState(0);
|
||||
@@ -152,6 +153,8 @@ export function MigrationManagementPage() {
|
||||
}, [range]);
|
||||
|
||||
const runMigration = async () => {
|
||||
if (runningMigration) return;
|
||||
setRunningMigration(true);
|
||||
try {
|
||||
setConfirmOpen(false);
|
||||
const result = await createMigration({ releaseId, migrationComponentId, imageComponentName, namespace, command, envSecretName });
|
||||
@@ -160,6 +163,8 @@ export function MigrationManagementPage() {
|
||||
await refresh();
|
||||
} catch (error) {
|
||||
toast({ type: 'error', message: error instanceof Error ? error.message : '마이그레이션 실행에 실패했습니다.' });
|
||||
} finally {
|
||||
setRunningMigration(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -364,11 +369,13 @@ export function MigrationManagementPage() {
|
||||
<Modal
|
||||
open={confirmOpen}
|
||||
title="마이그레이션 실행"
|
||||
onClose={() => setConfirmOpen(false)}
|
||||
onClose={() => {
|
||||
if (!runningMigration) setConfirmOpen(false);
|
||||
}}
|
||||
footer={(
|
||||
<>
|
||||
<Button variant="outline" onClick={() => setConfirmOpen(false)}>취소</Button>
|
||||
<Button disabled={!canRun || loading} onClick={runMigration}>실행</Button>
|
||||
<Button variant="outline" disabled={runningMigration} onClick={() => setConfirmOpen(false)}>취소</Button>
|
||||
<Button disabled={!canRun || loading || runningMigration} onClick={runMigration}>{runningMigration ? '실행 중' : '실행'}</Button>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { ChevronLeft, ChevronRight, Plus } from 'lucide-react';
|
||||
import { ChevronLeft, ChevronRight, MoreHorizontal, Plus } from 'lucide-react';
|
||||
import { Badge, Button, Card, CardHeader, Modal } from '../../components/ui';
|
||||
import { useToast } from '../../components/toast';
|
||||
import { PageTitle } from '../../layout/AppLayout';
|
||||
@@ -317,11 +317,13 @@ export function ReleaseManagementPage() {
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-8 px-3 text-[13px]"
|
||||
className="size-8 px-0"
|
||||
disabled={!release.logs}
|
||||
title={isLogOpen ? '로그 닫기' : '로그'}
|
||||
aria-label={isLogOpen ? '로그 닫기' : '로그'}
|
||||
onClick={() => setOpenLogReleaseId((prev) => prev === release.id ? '' : release.id)}
|
||||
>
|
||||
{isLogOpen ? '로그 닫기' : '로그'}
|
||||
<MoreHorizontal className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-xs">
|
||||
|
||||
Reference in New Issue
Block a user