improve launcher history and runtime config UX
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-07-07 09:51:24 +09:00
parent a48055bf65
commit 88d9c25b43
4 changed files with 41 additions and 19 deletions
@@ -1,4 +1,4 @@
import { MoreHorizontal, Plus, SlidersHorizontal, Trash2 } from 'lucide-react';
import { ChevronLeft, ChevronRight, MoreHorizontal, Plus, SlidersHorizontal, Trash2 } from 'lucide-react';
import { useEffect, useMemo, useState, type FormEvent } from 'react';
import { Badge, Button, Card, CardHeader, Modal } from '../../components/ui';
import { useToast } from '../../components/toast';
@@ -33,6 +33,8 @@ const emptyForm: FormState = {
isSecret: false
};
const settingsPageSize = 10;
function maskValue(setting: LauncherCommonSetting) {
if (!setting.isSecret) return setting.value;
if (!setting.value) return '-';
@@ -61,8 +63,11 @@ export function LauncherCommonSettingsPage() {
const [editing, setEditing] = useState<LauncherCommonSetting | null>(null);
const [form, setForm] = useState<FormState>(emptyForm);
const [saving, setSaving] = useState(false);
const [page, setPage] = useState(1);
const loadingVisible = useMinimumLoading(loading);
const totalPages = Math.max(1, Math.ceil(settings.length / settingsPageSize));
const pagedSettings = settings.slice((page - 1) * settingsPageSize, page * settingsPageSize);
const summary = useMemo(() => ({
total: settings.length,
endpoint: settings.filter((item) => item.type === 'endpoint').length,
@@ -84,6 +89,10 @@ export function LauncherCommonSettingsPage() {
refresh();
}, []);
useEffect(() => {
setPage((currentPage) => Math.min(currentPage, totalPages));
}, [totalPages]);
const openCreate = () => {
setEditing(null);
setForm(emptyForm);
@@ -192,7 +201,7 @@ export function LauncherCommonSettingsPage() {
<td colSpan={5} className="px-5 py-12 text-center text-sm text-muted-foreground">등록된 설정이 없습니다.</td>
</tr>
) : null}
{settings.map((setting) => (
{pagedSettings.map((setting) => (
<tr className="hover:bg-muted/20" key={setting.id}>
<td className="px-5 py-3">
<p className="inline-flex items-center gap-2 font-medium">
@@ -214,6 +223,31 @@ export function LauncherCommonSettingsPage() {
</tbody>
</table>
</div>
<div className="flex items-center justify-between gap-4 border-t border-border px-5 py-3 text-sm">
<span className="text-xs text-muted-foreground">
{loading ? '불러오는 중' : `총 ${settings.length}건 · ${page} / ${totalPages}`}
</span>
<div className="flex gap-2">
<Button
variant="outline"
className="h-8 px-3 text-[13px]"
disabled={page <= 1}
onClick={() => setPage((currentPage) => Math.max(1, currentPage - 1))}
>
<ChevronLeft className="size-4" />
이전
</Button>
<Button
variant="outline"
className="h-8 px-3 text-[13px]"
disabled={page >= totalPages}
onClick={() => setPage((currentPage) => Math.min(totalPages, currentPage + 1))}
>
다음
<ChevronRight className="size-4" />
</Button>
</div>
</div>
</Card>
<Modal