+ {!isMounted ? (
+
+ ) : element.type === "chart" ? (
+
) : (
renderWidget(element)
)}
diff --git a/frontend/components/dashboard/widgets/CustomMetricWidget.tsx b/frontend/components/dashboard/widgets/CustomMetricWidget.tsx
index d97ec05f..52c8411c 100644
--- a/frontend/components/dashboard/widgets/CustomMetricWidget.tsx
+++ b/frontend/components/dashboard/widgets/CustomMetricWidget.tsx
@@ -56,6 +56,7 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
// 자동 새로고침 (30초마다)
const interval = setInterval(loadData, 30000);
return () => clearInterval(interval);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [element]);
const loadData = async () => {
@@ -101,7 +102,7 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
body: JSON.stringify({
query: groupByDS.query,
connectionType: groupByDS.connectionType || "current",
- connectionId: groupByDS.connectionId,
+ connectionId: (groupByDS as any).connectionId,
}),
});
@@ -116,7 +117,7 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
const labelColumn = columns[0];
const valueColumn = columns[1];
- const cards = rows.map((row) => ({
+ const cards = rows.map((row: any) => ({
label: String(row[labelColumn] || ""),
value: parseFloat(row[valueColumn]) || 0,
}));
@@ -137,12 +138,12 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
- method: groupByDS.method || "GET",
+ method: (groupByDS as any).method || "GET",
url: groupByDS.endpoint,
- headers: groupByDS.headers || {},
- body: groupByDS.body,
- authType: groupByDS.authType,
- authConfig: groupByDS.authConfig,
+ headers: (groupByDS as any).headers || {},
+ body: (groupByDS as any).body,
+ authType: (groupByDS as any).authType,
+ authConfig: (groupByDS as any).authConfig,
}),
});
@@ -169,7 +170,7 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
const labelColumn = columns[0];
const valueColumn = columns[1];
- const cards = rows.map((row) => ({
+ const cards = rows.map((row: any) => ({
label: String(row[labelColumn] || ""),
value: parseFloat(row[valueColumn]) || 0,
}));
@@ -201,7 +202,7 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
body: JSON.stringify({
query: element.dataSource.query,
connectionType: element.dataSource.connectionType || "current",
- connectionId: element.dataSource.connectionId,
+ connectionId: (element.dataSource as any).connectionId,
}),
});
@@ -212,13 +213,14 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
if (result.success && result.data?.rows) {
const rows = result.data.rows;
- const calculatedMetrics = element.customMetricConfig.metrics.map((metric) => {
- const value = calculateMetric(rows, metric.field, metric.aggregation);
- return {
- ...metric,
- calculatedValue: value,
- };
- });
+ const calculatedMetrics =
+ element.customMetricConfig?.metrics.map((metric) => {
+ const value = calculateMetric(rows, metric.field, metric.aggregation);
+ return {
+ ...metric,
+ calculatedValue: value,
+ };
+ }) || [];
setMetrics(calculatedMetrics);
} else {
@@ -240,12 +242,12 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
- method: element.dataSource.method || "GET",
+ method: (element.dataSource as any).method || "GET",
url: element.dataSource.endpoint,
- headers: element.dataSource.headers || {},
- body: element.dataSource.body,
- authType: element.dataSource.authType,
- authConfig: element.dataSource.authConfig,
+ headers: (element.dataSource as any).headers || {},
+ body: (element.dataSource as any).body,
+ authType: (element.dataSource as any).authType,
+ authConfig: (element.dataSource as any).authConfig,
}),
});
@@ -278,13 +280,14 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
rows = [result.data];
}
- const calculatedMetrics = element.customMetricConfig.metrics.map((metric) => {
- const value = calculateMetric(rows, metric.field, metric.aggregation);
- return {
- ...metric,
- calculatedValue: value,
- };
- });
+ const calculatedMetrics =
+ element.customMetricConfig?.metrics.map((metric) => {
+ const value = calculateMetric(rows, metric.field, metric.aggregation);
+ return {
+ ...metric,
+ calculatedValue: value,
+ };
+ }) || [];
setMetrics(calculatedMetrics);
} else {
@@ -351,7 +354,9 @@ export default function CustomMetricWidget({ element }: CustomMetricWidgetProps)
• 선택한 컬럼의 데이터로 지표를 계산합니다
• COUNT, SUM, AVG, MIN, MAX 등 집계 함수 지원
• 사용자 정의 단위 설정 가능
-
• 그룹별 카드 생성 모드로 간편하게 사용 가능
+
+ • 그룹별 카드 생성 모드로 간편하게 사용 가능
+