feat: Enhance BOM and UI components with improved label handling and data mapping

- Updated the BOM service to include additional fields in the BOM header retrieval, enhancing data richness.
- Enhanced the EditModal to automatically map foreign key fields to dot notation, improving data handling and user experience.
- Improved the rendering of labels in various components, allowing for customizable label positions and styles, enhancing UI flexibility.
- Added new properties for label positioning and spacing in the V2 component styles, allowing for better layout control.
- Enhanced the BomTreeComponent to support additional data mapping for entity joins, improving data accessibility and management.
This commit is contained in:
DDD1542
2026-02-27 07:33:54 +09:00
parent 385a10e2e7
commit bfc89501ba
12 changed files with 409 additions and 145 deletions

View File

@@ -2208,15 +2208,21 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
});
}
// 라벨 스타일 적용
const labelStyle = {
// 라벨 위치 및 스타일
const labelPosition = component.style?.labelPosition || "top";
const isHorizontalLabel = labelPosition === "left" || labelPosition === "right";
const labelGap = component.style?.labelGap || "8px";
const labelStyle: React.CSSProperties = {
fontSize: component.style?.labelFontSize || "14px",
color: component.style?.labelColor || "#212121",
fontWeight: component.style?.labelFontWeight || "500",
backgroundColor: component.style?.labelBackgroundColor || "transparent",
padding: component.style?.labelPadding || "0",
borderRadius: component.style?.labelBorderRadius || "0",
marginBottom: component.style?.labelMarginBottom || "4px",
...(isHorizontalLabel
? { whiteSpace: "nowrap" as const, display: "flex", alignItems: "center" }
: { marginBottom: component.style?.labelMarginBottom || "4px" }),
};
@@ -2452,18 +2458,45 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
{/* 테이블 옵션 툴바 */}
<TableOptionsToolbar />
{/* 메인 컨텐츠 */}
<div className="h-full flex-1" style={{ width: '100%' }}>
{/* 라벨이 있는 경우 표시 (데이터 테이블 제외) */}
{shouldShowLabel && (
<label className="mb-2 block text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{/* 메인 컨텐츠 - 라벨 위치에 따라 flex 방향 변경 */}
<div
className="h-full flex-1"
style={{
width: '100%',
...(shouldShowLabel && isHorizontalLabel
? { display: 'flex', flexDirection: labelPosition === 'left' ? 'row' : 'row-reverse', alignItems: 'center', gap: labelGap }
: {}),
}}
>
{/* 라벨: top 또는 left일 때 위젯보다 먼저 렌더링 */}
{shouldShowLabel && (labelPosition === "top" || labelPosition === "left") && (
<label
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
style={labelStyle}
>
{labelText}
{(component.required || component.componentConfig?.required) && <span className="ml-1 text-destructive">*</span>}
</label>
)}
{/* 실제 위젯 - 상위에서 라벨을 렌더링했으므로 자식은 라벨 숨김 */}
<div className="h-full" style={{ width: '100%', height: '100%' }}>{renderInteractiveWidget(componentForRendering)}</div>
{/* 실제 위젯 */}
<div className="h-full" style={{ width: '100%', height: '100%', ...(isHorizontalLabel ? { flex: 1, minWidth: 0 } : {}) }}>
{renderInteractiveWidget(componentForRendering)}
</div>
{/* 라벨: bottom 또는 right일 때 위젯 뒤에 렌더링 */}
{shouldShowLabel && (labelPosition === "bottom" || labelPosition === "right") && (
<label
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
style={{
...labelStyle,
...(labelPosition === "bottom" ? { marginBottom: 0, marginTop: component.style?.labelMarginBottom || "4px" } : {}),
}}
>
{labelText}
{(component.required || component.componentConfig?.required) && <span className="ml-1 text-destructive">*</span>}
</label>
)}
</div>
</div>