후판정보 조회 방식 개선

This commit is contained in:
dohyeons 2025-12-18 13:26:11 +09:00
parent 403bd0f8a1
commit 36bac321b8
2 changed files with 75 additions and 79 deletions

View File

@ -19,6 +19,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import dynamic from "next/dynamic";
import { useToast } from "@/hooks/use-toast";
import type { PlacedObject, ToolType, Warehouse, Area, Location, ObjectType } from "@/types/digitalTwin";
@ -2141,45 +2142,39 @@ export default function DigitalTwinEditor({ layoutId, layoutName, onBack }: Digi
</div>
) : (
<Accordion type="single" collapsible className="w-full">
<div className="max-h-[400px] overflow-y-auto rounded-md border">
<Table>
<TableHeader className="bg-muted sticky top-0">
<TableRow>
<TableHead className="w-[60px] text-xs"></TableHead>
{(hierarchyConfig?.material?.displayColumns || []).map((col) => (
<TableHead key={col.column} className="text-xs">
{col.label}
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{materials.map((material, index) => {
const layerColumn = hierarchyConfig?.material?.layerColumn || "LOLAYER";
const keyColumn = hierarchyConfig?.material?.keyColumn || "STKKEY";
const displayColumns = hierarchyConfig?.material?.displayColumns || [];
const layerValue = material[layerColumn] || index + 1;
const keyValue = material[keyColumn] || `자재 ${index + 1}`;
const layerNumber = material[layerColumn] || index + 1;
return (
<AccordionItem key={`${keyValue}-${index}`} value={`item-${index}`} className="border-b">
<AccordionTrigger className="px-2 py-3 hover:no-underline">
<div className="flex w-full items-center justify-between pr-2">
<span className="text-sm font-medium"> {layerValue}</span>
<span className="text-muted-foreground max-w-[150px] truncate text-xs">{keyValue}</span>
</div>
</AccordionTrigger>
<AccordionContent className="px-2 pb-3">
{displayColumns.length === 0 ? (
<p className="text-muted-foreground py-2 text-center text-xs">
</p>
) : (
<div className="space-y-1.5">
{displayColumns.map((item) => (
<div key={item.column} className="flex justify-between gap-2 text-xs">
<span className="text-muted-foreground shrink-0">{item.label}:</span>
<span className="text-right font-medium break-all">
{material[item.column] || "-"}
</span>
</div>
<TableRow key={material[keyColumn] || `material-${index}`}>
<TableCell className="text-xs font-medium">{layerNumber}</TableCell>
{displayColumns.map((col) => (
<TableCell key={col.column} className="text-xs">
{material[col.column] || "-"}
</TableCell>
))}
</div>
)}
</AccordionContent>
</AccordionItem>
</TableRow>
);
})}
</Accordion>
</TableBody>
</Table>
</div>
)}
</div>
) : selectedObject ? (

View File

@ -624,7 +624,7 @@ export default function DigitalTwinViewer({ layoutId }: DigitalTwinViewerProps)
)}
</div>
{/* 자재 목록 (Location인 경우) - 아코디언 */}
{/* 자재 목록 (Location인 경우) - 테이블 형태 */}
{(selectedObject.type === "location-bed" ||
selectedObject.type === "location-stp" ||
selectedObject.type === "location-temp" ||
@ -640,47 +640,48 @@ export default function DigitalTwinViewer({ layoutId }: DigitalTwinViewerProps)
</div>
) : (
<div className="space-y-2">
<Label className="mb-2 block text-sm font-semibold"> ({materials.length})</Label>
<Label className="mb-2 block text-sm font-semibold">
({materials.length})
</Label>
{/* 테이블 형태로 전체 조회 */}
<div className="max-h-[400px] overflow-auto rounded-lg border">
<table className="w-full text-xs">
<thead className="bg-muted sticky top-0">
<tr>
<th className="border-b px-2 py-2 text-left font-semibold"></th>
{(hierarchyConfig?.material?.displayColumns || []).map((colConfig: any) => (
<th
key={colConfig.column}
className="border-b px-2 py-2 text-left font-semibold"
>
{colConfig.label}
</th>
))}
</tr>
</thead>
<tbody>
{materials.map((material, index) => {
const layerColumn = hierarchyConfig?.material?.layerColumn || "LOLAYER";
const displayColumns = hierarchyConfig?.material?.displayColumns || [];
return (
<details
<tr
key={`${material.STKKEY}-${index}`}
className="bg-muted group hover:bg-accent rounded-lg border transition-colors"
className="hover:bg-accent border-b transition-colors last:border-0"
>
<summary className="flex cursor-pointer items-center justify-between p-3 text-sm font-medium">
<div className="flex-1">
<div className="flex items-center gap-2">
<span className="font-semibold">
{material[hierarchyConfig?.material?.layerColumn || "LOLAYER"]}
</span>
{displayColumns[0] && (
<span className="text-muted-foreground text-xs">
{material[displayColumns[0].column]}
</span>
)}
</div>
</div>
<svg
className="text-muted-foreground h-4 w-4 transition-transform group-open:rotate-180"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</summary>
<div className="space-y-2 border-t p-3 pt-3">
<td className="px-2 py-2 font-medium">
{material[layerColumn]}
</td>
{displayColumns.map((colConfig: any) => (
<div key={colConfig.column} className="flex justify-between text-xs">
<span className="text-muted-foreground">{colConfig.label}:</span>
<span className="font-medium">{material[colConfig.column] || "-"}</span>
</div>
<td key={colConfig.column} className="px-2 py-2">
{material[colConfig.column] || "-"}
</td>
))}
</div>
</details>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
)}
</div>