카드 컴포넌트 추가 및 페이지번호/쿼리 버그 수정

This commit is contained in:
dohyeons
2025-12-18 10:39:57 +09:00
parent 0ed8e686c0
commit 1fd428c016
8 changed files with 831 additions and 2 deletions

View File

@@ -161,6 +161,58 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
content = `<div style="display: flex; align-items: center; justify-content: center; height: 100%; font-size: ${component.fontSize}px; color: ${component.fontColor}; font-weight: ${component.fontWeight}; text-align: ${component.textAlign};">${pageNumberText}</div>`;
}
// Card 컴포넌트
else if (component.type === "card") {
const cardTitle = component.cardTitle || "정보 카드";
const cardItems = component.cardItems || [];
const labelWidth = component.labelWidth || 80;
const showCardTitle = component.showCardTitle !== false;
const titleFontSize = component.titleFontSize || 14;
const labelFontSize = component.labelFontSize || 13;
const valueFontSize = component.valueFontSize || 13;
const titleColor = component.titleColor || "#1e40af";
const labelColor = component.labelColor || "#374151";
const valueColor = component.valueColor || "#000000";
const borderColor = component.borderColor || "#e5e7eb";
// 쿼리 바인딩된 값 가져오기
const getCardValue = (item: { label: string; value: string; fieldName?: string }) => {
if (item.fieldName && queryResult && queryResult.rows && queryResult.rows.length > 0) {
const row = queryResult.rows[0];
return row[item.fieldName] !== undefined ? String(row[item.fieldName]) : item.value;
}
return item.value;
};
const itemsHtml = cardItems
.map(
(item: { label: string; value: string; fieldName?: string }) => `
<div style="display: flex; padding: 2px 0;">
<span style="width: ${labelWidth}px; flex-shrink: 0; font-size: ${labelFontSize}px; color: ${labelColor}; font-weight: 500;">${item.label}</span>
<span style="flex: 1; font-size: ${valueFontSize}px; color: ${valueColor};">${getCardValue(item)}</span>
</div>
`
)
.join("");
content = `
<div style="display: flex; flex-direction: column; height: 100%; overflow: hidden;">
${
showCardTitle
? `
<div style="flex-shrink: 0; padding: 4px 8px; font-size: ${titleFontSize}px; font-weight: 600; color: ${titleColor};">
${cardTitle}
</div>
<div style="flex-shrink: 0; margin: 0 4px; border-bottom: 1px solid ${borderColor};"></div>
`
: ""
}
<div style="flex: 1; padding: 4px 8px; overflow: auto;">
${itemsHtml}
</div>
</div>`;
}
// Table 컴포넌트
else if (component.type === "table" && queryResult && queryResult.rows.length > 0) {
const columns =
@@ -764,6 +816,93 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
</div>
);
})()}
{/* Card 컴포넌트 */}
{component.type === "card" && (() => {
const cardTitle = component.cardTitle || "정보 카드";
const cardItems = component.cardItems || [];
const labelWidth = component.labelWidth || 80;
const showCardTitle = component.showCardTitle !== false;
const titleFontSize = component.titleFontSize || 14;
const labelFontSize = component.labelFontSize || 13;
const valueFontSize = component.valueFontSize || 13;
const titleColor = component.titleColor || "#1e40af";
const labelColor = component.labelColor || "#374151";
const valueColor = component.valueColor || "#000000";
const borderColor = component.borderColor || "#e5e7eb";
// 쿼리 바인딩된 값 가져오기
const getCardValue = (item: { label: string; value: string; fieldName?: string }) => {
if (item.fieldName && component.queryId) {
const qResult = getQueryResult(component.queryId);
if (qResult && qResult.rows && qResult.rows.length > 0) {
const row = qResult.rows[0];
return row[item.fieldName] !== undefined ? String(row[item.fieldName]) : item.value;
}
}
return item.value;
};
return (
<div
style={{
display: "flex",
flexDirection: "column",
height: "100%",
overflow: "hidden",
}}
>
{showCardTitle && (
<>
<div
style={{
flexShrink: 0,
padding: "4px 8px",
fontSize: `${titleFontSize}px`,
fontWeight: 600,
color: titleColor,
}}
>
{cardTitle}
</div>
<div
style={{
flexShrink: 0,
margin: "0 4px",
borderBottom: `1px solid ${borderColor}`,
}}
/>
</>
)}
<div style={{ flex: 1, padding: "4px 8px", overflow: "auto" }}>
{cardItems.map((item: { label: string; value: string; fieldName?: string }, idx: number) => (
<div key={idx} style={{ display: "flex", padding: "2px 0" }}>
<span
style={{
width: `${labelWidth}px`,
flexShrink: 0,
fontSize: `${labelFontSize}px`,
color: labelColor,
fontWeight: 500,
}}
>
{item.label}
</span>
<span
style={{
flex: 1,
fontSize: `${valueFontSize}px`,
color: valueColor,
}}
>
{getCardValue(item)}
</span>
</div>
))}
</div>
</div>
);
})()}
</div>
);
})}