대시보드 제목 누르면 편집화면으로 이동 구현

This commit is contained in:
dohyeons 2025-11-17 09:49:13 +09:00
parent 385ecdc46a
commit ff23aa7d1d
2 changed files with 51 additions and 37 deletions

View File

@ -300,7 +300,14 @@ export default function DashboardListClient({ initialDashboards, initialPaginati
<TableBody>
{dashboards.map((dashboard) => (
<TableRow key={dashboard.id} className="hover:bg-muted/50 border-b transition-colors">
<TableCell className="h-16 text-sm font-medium">{dashboard.title}</TableCell>
<TableCell className="h-16 text-sm font-medium">
<button
onClick={() => router.push(`/admin/dashboard/edit/${dashboard.id}`)}
className="hover:text-primary cursor-pointer text-left transition-colors hover:underline"
>
{dashboard.title}
</button>
</TableCell>
<TableCell className="text-muted-foreground h-16 max-w-md truncate text-sm">
{dashboard.description || "-"}
</TableCell>
@ -355,7 +362,12 @@ export default function DashboardListClient({ initialDashboards, initialPaginati
{/* 헤더 */}
<div className="mb-4 flex items-start justify-between">
<div className="flex-1">
<h3 className="text-base font-semibold">{dashboard.title}</h3>
<button
onClick={() => router.push(`/admin/dashboard/edit/${dashboard.id}`)}
className="hover:text-primary cursor-pointer text-left transition-colors hover:underline"
>
<h3 className="text-base font-semibold">{dashboard.title}</h3>
</button>
<p className="text-muted-foreground mt-1 text-sm">{dashboard.id}</p>
</div>
</div>

View File

@ -89,68 +89,70 @@ export function CustomMetricSection({ queryResult, config, onConfigChange }: Cus
</div>
{config.filters && config.filters.length > 0 ? (
<div className="space-y-2">
<div className="space-y-3">
{config.filters.map((filter, index) => (
<div key={index} className="bg-muted/50 flex items-center gap-2 rounded-md border p-2">
{/* 컬럼 선택 */}
<Select value={filter.column} onValueChange={(value) => updateFilter(index, "column", value)}>
<SelectTrigger className="h-8 flex-1 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
{queryResult.columns.map((col) => (
<SelectItem key={col} value={col} className="text-xs">
{col}
</SelectItem>
))}
</SelectContent>
</Select>
<div key={index} className="bg-muted/50 space-y-2 rounded-md border p-3">
{/* 첫 번째 줄: 컬럼 선택 */}
<div className="flex items-center gap-2">
<Select value={filter.column} onValueChange={(value) => updateFilter(index, "column", value)}>
<SelectTrigger className="h-9 flex-1 text-sm">
<SelectValue placeholder="컬럼 선택" />
</SelectTrigger>
<SelectContent>
{queryResult.columns.map((col) => (
<SelectItem key={col} value={col} className="text-sm">
{col}
</SelectItem>
))}
</SelectContent>
</Select>
{/* 삭제 버튼 */}
<Button onClick={() => removeFilter(index)} variant="ghost" size="icon" className="h-9 w-9 shrink-0">
<X className="h-4 w-4" />
</Button>
</div>
{/* 연산자 선택 */}
{/* 두 번째 줄: 연산자 선택 */}
<Select value={filter.operator} onValueChange={(value) => updateFilter(index, "operator", value)}>
<SelectTrigger className="h-8 w-[100px] text-xs">
<SelectValue />
<SelectTrigger className="h-9 w-full text-sm">
<SelectValue placeholder="연산자 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="=" className="text-xs">
<SelectItem value="=" className="text-sm">
(=)
</SelectItem>
<SelectItem value="!=" className="text-xs">
<SelectItem value="!=" className="text-sm">
()
</SelectItem>
<SelectItem value=">" className="text-xs">
<SelectItem value=">" className="text-sm">
(&gt;)
</SelectItem>
<SelectItem value="<" className="text-xs">
<SelectItem value="<" className="text-sm">
(&lt;)
</SelectItem>
<SelectItem value=">=" className="text-xs">
<SelectItem value=">=" className="text-sm">
()
</SelectItem>
<SelectItem value="<=" className="text-xs">
<SelectItem value="<=" className="text-sm">
()
</SelectItem>
<SelectItem value="contains" className="text-xs">
<SelectItem value="contains" className="text-sm">
</SelectItem>
<SelectItem value="not_contains" className="text-xs">
<SelectItem value="not_contains" className="text-sm">
</SelectItem>
</SelectContent>
</Select>
{/* 값 입력 */}
{/* 세 번째 줄: 값 입력 */}
<Input
value={filter.value}
onChange={(e) => updateFilter(index, "value", e.target.value)}
placeholder="값"
className="h-8 flex-1 text-xs"
placeholder="값을 입력하세요"
className="h-9 w-full text-sm"
/>
{/* 삭제 버튼 */}
<Button onClick={() => removeFilter(index)} variant="ghost" size="icon" className="h-8 w-8">
<X className="h-3 w-3" />
</Button>
</div>
))}
</div>
@ -264,7 +266,7 @@ export function CustomMetricSection({ queryResult, config, onConfigChange }: Cus
<div className="space-y-1">
<p className="text-xs font-medium">:</p>
{config.filters.map((filter, idx) => (
<p key={idx} className="text-muted-foreground text-xs">
<p key={idx} className="text-muted-foreground text-xs" dir="ltr">
· {filter.column} {filter.operator} &quot;{filter.value}&quot;
</p>
))}