diff --git a/frontend/components/admin/dashboard/ChartConfigPanel.tsx b/frontend/components/admin/dashboard/ChartConfigPanel.tsx index 2c7ff14b..2257848d 100644 --- a/frontend/components/admin/dashboard/ChartConfigPanel.tsx +++ b/frontend/components/admin/dashboard/ChartConfigPanel.tsx @@ -10,7 +10,7 @@ import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Checkbox } from "@/components/ui/checkbox"; import { Separator } from "@/components/ui/separator"; -import { TrendingUp, AlertCircle } from "lucide-react"; +import { AlertCircle } from "lucide-react"; import { DateFilterPanel } from "./DateFilterPanel"; import { extractTableNameFromQuery } from "./utils/queryHelpers"; import { dashboardApi } from "@/lib/api/dashboard"; @@ -85,34 +85,23 @@ export function ChartConfigPanel({ } const tableName = extractTableNameFromQuery(query); - console.log("๐Ÿ“‹ ์ฟผ๋ฆฌ์—์„œ ์ถ”์ถœํ•œ ํ…Œ์ด๋ธ”๋ช…:", tableName); - console.log("๐Ÿ“‹ ์›๋ณธ ์ฟผ๋ฆฌ:", query); if (!tableName) { - console.log("โš ๏ธ ํ…Œ์ด๋ธ”๋ช…์„ ์ถ”์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); setDateColumns([]); return; } - - console.log("๐Ÿ” ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ ์กฐํšŒ ์ค‘:", tableName); dashboardApi .getTableSchema(tableName) .then((schema) => { - console.log("โœ… ์Šคํ‚ค๋งˆ ์กฐํšŒ ์„ฑ๊ณต:", schema); - console.log("๐Ÿ“… ์ „์ฒด ๋‚ ์งœ ์ปฌ๋Ÿผ:", schema.dateColumns); - console.log("๐Ÿ“Š ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์ปฌ๋Ÿผ:", availableColumns); - // ์›๋ณธ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋‚ ์งœ ์ปฌ๋Ÿผ์„ ํ‘œ์‹œ // (SELECT์— ์—†์–ด๋„ WHERE ์ ˆ์— ์‚ฌ์šฉ ๊ฐ€๋Šฅ) setDateColumns(schema.dateColumns); - console.log("โœจ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‚ ์งœ ํ•„ํ„ฐ ์ปฌ๋Ÿผ:", schema.dateColumns); }) .catch((error) => { console.error("โŒ ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ ์กฐํšŒ ์‹คํŒจ:", error); // ์‹คํŒจ ์‹œ ๋นˆ ๋ฐฐ์—ด (๋‚ ์งœ ํ•„ํ„ฐ ๋น„ํ™œ์„ฑํ™”) setDateColumns([]); }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [query, queryResult, dataSourceType]); return ( @@ -125,7 +114,7 @@ export function ChartConfigPanel({
-

๐Ÿ“‹ API ์‘๋‹ต ๋ฐ์ดํ„ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ

+

API ์‘๋‹ต ๋ฐ์ดํ„ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ

์ด {queryResult.totalRows}๊ฐœ ๋ฐ์ดํ„ฐ ์ค‘ ์ฒซ ๋ฒˆ์งธ ํ–‰:
@@ -139,7 +128,7 @@ export function ChartConfigPanel({ -
โš ๏ธ ์ฐจํŠธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ปฌ๋Ÿผ ๊ฐ์ง€
+
์ฐจํŠธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ปฌ๋Ÿผ ๊ฐ์ง€
๋‹ค์Œ ์ปฌ๋Ÿผ์€ ๊ฐ์ฒด ๋˜๋Š” ๋ฐฐ์—ด ํƒ€์ž…์ด๋ผ์„œ ์ฐจํŠธ ์ถ•์œผ๋กœ ์„ ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค:
@@ -151,7 +140,7 @@ export function ChartConfigPanel({
- ๐Ÿ’ก ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: JSON Path๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ’์„ ์ง์ ‘ ์ถ”์ถœํ•˜์„ธ์š”. + ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: JSON Path๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ๋œ ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ’์„ ์ง์ ‘ ์ถ”์ถœํ•˜์„ธ์š”.
์˜ˆ: main ๋˜๋Š”{" "} data.items @@ -203,7 +192,7 @@ export function ChartConfigPanel({ {simpleColumns.length === 0 && ( -

โš ๏ธ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปฌ๋Ÿผ์ด ์—†์Šต๋‹ˆ๋‹ค. JSON Path๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

+

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปฌ๋Ÿผ์ด ์—†์Šต๋‹ˆ๋‹ค. JSON Path๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

)}
@@ -221,17 +210,14 @@ export function ChartConfigPanel({ {/* ์ˆซ์ž ํƒ€์ž… ์šฐ์„  ํ‘œ์‹œ */} {numericColumns.length > 0 && ( <> -
โœ… ์ˆซ์ž ํƒ€์ž… (๊ถŒ์žฅ)
+
์ˆซ์ž ํƒ€์ž… (๊ถŒ์žฅ)
{numericColumns.map((col) => { const isSelected = Array.isArray(currentConfig.yAxis) ? currentConfig.yAxis.includes(col) : currentConfig.yAxis === col; return ( -
+
{ @@ -271,7 +257,7 @@ export function ChartConfigPanel({ {simpleColumns.filter((col) => !numericColumns.includes(col)).length > 0 && ( <> {numericColumns.length > 0 &&
} -
๐Ÿ“ ๊ธฐํƒ€ ํƒ€์ž…
+
๊ธฐํƒ€ ํƒ€์ž…
{simpleColumns .filter((col) => !numericColumns.includes(col)) .map((col) => { @@ -320,7 +306,7 @@ export function ChartConfigPanel({
{simpleColumns.length === 0 && ( -

โš ๏ธ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปฌ๋Ÿผ์ด ์—†์Šต๋‹ˆ๋‹ค. JSON Path๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

+

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปฌ๋Ÿผ์ด ์—†์Šต๋‹ˆ๋‹ค. JSON Path๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

)}

ํŒ: ์—ฌ๋Ÿฌ ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜๋ฉด ๋น„๊ต ์ฐจํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค (์˜ˆ: ๊ฐค๋Ÿญ์‹œ vs ์•„์ดํฐ) @@ -356,7 +342,7 @@ export function ChartConfigPanel({

- ๐Ÿ’ก ๊ทธ๋ฃนํ•‘ ํ•„๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘๊ณ„ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: ๋ถ€์„œ๋ณ„ ๊ฐœ์ˆ˜, ์›”๋ณ„ ํ•ฉ๊ณ„) + ๊ทธ๋ฃนํ•‘ ํ•„๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘๊ณ„ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: ๋ถ€์„œ๋ณ„ ๊ฐœ์ˆ˜, ์›”๋ณ„ ํ•ฉ๊ณ„)

@@ -432,45 +418,6 @@ export function ChartConfigPanel({ - {/* ์„ค์ • ๋ฏธ๋ฆฌ๋ณด๊ธฐ */} - -
- - ์„ค์ • ๋ฏธ๋ฆฌ๋ณด๊ธฐ -
-
-
- X์ถ•: - {currentConfig.xAxis || "๋ฏธ์„ค์ •"} -
-
- Y์ถ•: - - {Array.isArray(currentConfig.yAxis) && currentConfig.yAxis.length > 0 - ? `${currentConfig.yAxis.length}๊ฐœ (${currentConfig.yAxis.join(", ")})` - : currentConfig.yAxis || "๋ฏธ์„ค์ •"} - -
-
- ์ง‘๊ณ„: - {currentConfig.aggregation || "์—†์Œ"} -
- {currentConfig.groupBy && ( -
- ๊ทธ๋ฃนํ•‘: - {currentConfig.groupBy} -
- )} -
- ๋ฐ์ดํ„ฐ ํ–‰ ์ˆ˜: - {queryResult.rows.length}๊ฐœ -
- {Array.isArray(currentConfig.yAxis) && currentConfig.yAxis.length > 1 && ( -
โœจ ๋‹ค์ค‘ ์‹œ๋ฆฌ์ฆˆ ์ฐจํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค!
- )} -
-
- {/* ๋‚ ์งœ ํ•„ํ„ฐ */} {dateColumns.length > 0 && ( diff --git a/frontend/components/admin/dashboard/ElementConfigModal.tsx b/frontend/components/admin/dashboard/ElementConfigModal.tsx index 1060332d..1c8921eb 100644 --- a/frontend/components/admin/dashboard/ElementConfigModal.tsx +++ b/frontend/components/admin/dashboard/ElementConfigModal.tsx @@ -10,7 +10,6 @@ import { DatabaseConfig } from "./data-sources/DatabaseConfig"; import { ApiConfig } from "./data-sources/ApiConfig"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; -import { Progress } from "@/components/ui/progress"; import { X, ChevronLeft, ChevronRight, Save } from "lucide-react"; interface ElementConfigModalProps { @@ -110,10 +109,6 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element // ์ €์žฅ ์ฒ˜๋ฆฌ const handleSave = useCallback(() => { - console.log("๐Ÿ’พ ์ €์žฅ ๋ฒ„ํŠผ ํด๋ฆญ!"); - console.log(" ํ˜„์žฌ chartConfig:", chartConfig); - console.log(" dateFilter:", chartConfig?.dateFilter); - const updatedElement: DashboardElement = { ...element, dataSource, @@ -141,6 +136,11 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element const isPieChart = element.subtype === "pie" || element.subtype === "donut"; const isApiSource = dataSource.type === "api"; + // Y์ถ• ๊ฒ€์ฆ ํ—ฌํผ + const hasYAxis = + chartConfig.yAxis && + (typeof chartConfig.yAxis === "string" || (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0)); + const canSave = isSimpleWidget ? // ๊ฐ„๋‹จํ•œ ์œ„์ ฏ: 2๋‹จ๊ณ„์—์„œ ์ฟผ๋ฆฌ ํ…Œ์ŠคํŠธ ํ›„ ์ €์žฅ ๊ฐ€๋Šฅ currentStep === 2 && queryResult && queryResult.rows.length > 0 @@ -157,12 +157,12 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element queryResult.rows.length > 0 && chartConfig.xAxis && (isPieChart || isApiSource - ? // ํŒŒ์ด/๋„๋„› ์ฐจํŠธ ๋˜๋Š” REST API: Y์ถ• ๋˜๋Š” ์ง‘๊ณ„ ํ•จ์ˆ˜ ํ•„์š” - chartConfig.yAxis || - (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0) || + ? // ํŒŒ์ด/๋„๋„› ์ฐจํŠธ ๋˜๋Š” REST API chartConfig.aggregation === "count" + ? true // count๋Š” Y์ถ• ์—†์–ด๋„ ๋จ + : hasYAxis // ๋‹ค๋ฅธ ์ง‘๊ณ„(sum, avg, max, min) ๋˜๋Š” ์ง‘๊ณ„ ์—†์Œ โ†’ Y์ถ• ํ•„์ˆ˜ : // ์ผ๋ฐ˜ ์ฐจํŠธ (DB): Y์ถ• ํ•„์ˆ˜ - chartConfig.yAxis || (Array.isArray(chartConfig.yAxis) && chartConfig.yAxis.length > 0)); + hasYAxis); return (
@@ -191,13 +191,11 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element {/* ์ง„ํ–‰ ์ƒํ™ฉ ํ‘œ์‹œ - ๊ฐ„๋‹จํ•œ ์œ„์ ฏ์€ ํ‘œ์‹œ ์•ˆ ํ•จ */} {!isSimpleWidget && (
-
+
๋‹จ๊ณ„ {currentStep} / 2: {currentStep === 1 ? "๋ฐ์ดํ„ฐ ์†Œ์Šค ์„ ํƒ" : "๋ฐ์ดํ„ฐ ์„ค์ • ๋ฐ ์ฐจํŠธ ์„ค์ •"}
- {Math.round((currentStep / 2) * 100)}% ์™„๋ฃŒ
-
)} @@ -268,13 +266,7 @@ export function ElementConfigModal({ element, isOpen, onClose, onSave }: Element {/* ๋ชจ๋‹ฌ ํ‘ธํ„ฐ */}
-
- {queryResult && ( - - ๐Ÿ“Š {queryResult.rows.length}๊ฐœ ๋ฐ์ดํ„ฐ ๋กœ๋“œ๋จ - - )} -
+
{queryResult && {queryResult.rows.length}๊ฐœ ๋ฐ์ดํ„ฐ ๋กœ๋“œ๋จ}
{!isSimpleWidget && currentStep > 1 && ( diff --git a/frontend/components/admin/dashboard/data-sources/ApiConfig.tsx b/frontend/components/admin/dashboard/data-sources/ApiConfig.tsx index 26e4b588..09f45411 100644 --- a/frontend/components/admin/dashboard/data-sources/ApiConfig.tsx +++ b/frontend/components/admin/dashboard/data-sources/ApiConfig.tsx @@ -299,7 +299,7 @@ export function ApiConfig({ dataSource, onChange, onTestResult }: ApiConfigProps onClick={() => { const headers = normalizeHeaders(); onChange({ - headers: [...headers, { id: `header_${Date.now()}`, key: "Authorization", value: "Bearer YOUR_TOKEN" }], + headers: [...headers, { id: `header_${Date.now()}`, key: "Authorization", value: "" }], }); }} > @@ -398,7 +398,7 @@ export function ApiConfig({ dataSource, onChange, onTestResult }: ApiConfigProps {/* ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ */} {testResult && ( -
โœ… API ํ˜ธ์ถœ ์„ฑ๊ณต
+
API ํ˜ธ์ถœ ์„ฑ๊ณต
์ด {testResult.rows.length}๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค
์ปฌ๋Ÿผ: {testResult.columns.join(", ")}