chpark-sync #425
|
|
@ -7,6 +7,7 @@ import { transformQueryResultToChartData } from "../utils/chartDataTransform";
|
||||||
import { ExternalDbConnectionAPI } from "@/lib/api/externalDbConnection";
|
import { ExternalDbConnectionAPI } from "@/lib/api/externalDbConnection";
|
||||||
import { dashboardApi } from "@/lib/api/dashboard";
|
import { dashboardApi } from "@/lib/api/dashboard";
|
||||||
import { applyQueryFilters } from "../utils/queryHelpers";
|
import { applyQueryFilters } from "../utils/queryHelpers";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
interface ChartRendererProps {
|
interface ChartRendererProps {
|
||||||
element: DashboardElement;
|
element: DashboardElement;
|
||||||
|
|
@ -84,7 +85,7 @@ export function ChartRenderer({ element, data, width, height = 200 }: ChartRende
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
|
||||||
import { Plus, X, Play, AlertCircle } from "lucide-react";
|
import { Plus, X, Play, AlertCircle } from "lucide-react";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { ExternalDbConnectionAPI, ExternalApiConnection } from "@/lib/api/externalDbConnection";
|
import { ExternalDbConnectionAPI, ExternalApiConnection } from "@/lib/api/externalDbConnection";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
// 개별 API 소스 인터페이스
|
// 개별 API 소스 인터페이스
|
||||||
interface ApiSource {
|
interface ApiSource {
|
||||||
|
|
@ -254,7 +255,7 @@ export function ApiConfig({ dataSource, onChange, onTestResult }: ApiConfigProps
|
||||||
});
|
});
|
||||||
|
|
||||||
// 백엔드 프록시를 통한 외부 API 호출 (CORS 우회)
|
// 백엔드 프록시를 통한 외부 API 호출 (CORS 우회)
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Label } from "@/components/ui/label";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Plus, Trash2, Loader2, CheckCircle, XCircle } from "lucide-react";
|
import { Plus, Trash2, Loader2, CheckCircle, XCircle } from "lucide-react";
|
||||||
import { ExternalDbConnectionAPI, ExternalApiConnection } from "@/lib/api/externalDbConnection";
|
import { ExternalDbConnectionAPI, ExternalApiConnection } from "@/lib/api/externalDbConnection";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
interface MultiApiConfigProps {
|
interface MultiApiConfigProps {
|
||||||
dataSource: ChartDataSource;
|
dataSource: ChartDataSource;
|
||||||
|
|
@ -220,7 +221,7 @@ export default function MultiApiConfig({ dataSource, onChange, onTestResult }: M
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await fetch("/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { DashboardElement, QueryResult, ListWidgetConfig } from "../types";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
interface ListWidgetProps {
|
interface ListWidgetProps {
|
||||||
element: DashboardElement;
|
element: DashboardElement;
|
||||||
|
|
@ -58,7 +59,7 @@ export function ListWidget({ element, onConfigUpdate }: ListWidgetProps) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { DashboardElement, ChartDataSource, ChartData } from "@/components/admin
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Loader2, RefreshCw } from "lucide-react";
|
import { Loader2, RefreshCw } from "lucide-react";
|
||||||
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
import { Chart } from "@/components/admin/dashboard/charts/Chart";
|
import { Chart } from "@/components/admin/dashboard/charts/Chart";
|
||||||
|
|
||||||
interface ChartTestWidgetProps {
|
interface ChartTestWidgetProps {
|
||||||
|
|
@ -127,7 +128,7 @@ export default function ChartTestWidget({ element }: ChartTestWidgetProps) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch("/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { DashboardElement, ChartDataSource } from "@/components/admin/dashboard/
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Loader2, RefreshCw } from "lucide-react";
|
import { Loader2, RefreshCw } from "lucide-react";
|
||||||
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
|
|
||||||
|
|
@ -242,7 +243,7 @@ export default function CustomMetricTestWidget({ element }: CustomMetricTestWidg
|
||||||
|
|
||||||
// 🆕 자동 집계 로직: 집계 컬럼 이름으로 판단 (count, 개수, sum, avg 등)
|
// 🆕 자동 집계 로직: 집계 컬럼 이름으로 판단 (count, 개수, sum, avg 등)
|
||||||
const isAggregated = numericColumns.some((col) =>
|
const isAggregated = numericColumns.some((col) =>
|
||||||
/count|개수|sum|합계|avg|평균|min|최소|max|최대|total|전체/i.test(col)
|
/count|개수|sum|합계|avg|평균|min|최소|max|최대|total|전체/i.test(col),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isAggregated && numericColumns.length > 0) {
|
if (isAggregated && numericColumns.length > 0) {
|
||||||
|
|
@ -553,7 +554,7 @@ export default function CustomMetricTestWidget({ element }: CustomMetricTestWidg
|
||||||
|
|
||||||
console.log("🌐 API 호출:", source.endpoint, "파라미터:", Object.fromEntries(params));
|
console.log("🌐 API 호출:", source.endpoint, "파라미터:", Object.fromEntries(params));
|
||||||
|
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
@ -746,7 +747,10 @@ export default function CustomMetricTestWidget({ element }: CustomMetricTestWidg
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full w-full flex-col bg-white p-2">
|
<div className="flex h-full w-full flex-col bg-white p-2">
|
||||||
{/* 콘텐츠 영역 - 스크롤 가능하도록 개선 */}
|
{/* 콘텐츠 영역 - 스크롤 가능하도록 개선 */}
|
||||||
<div className="grid w-full gap-2 overflow-y-auto" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(140px, 1fr))" }}>
|
<div
|
||||||
|
className="grid w-full gap-2 overflow-y-auto"
|
||||||
|
style={{ gridTemplateColumns: "repeat(auto-fit, minmax(140px, 1fr))" }}
|
||||||
|
>
|
||||||
{/* 그룹별 카드 (활성화 시) */}
|
{/* 그룹별 카드 (활성화 시) */}
|
||||||
{isGroupByMode &&
|
{isGroupByMode &&
|
||||||
groupedCards.map((card, index) => {
|
groupedCards.map((card, index) => {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import { Loader2, RefreshCw } from "lucide-react";
|
import { Loader2, RefreshCw } from "lucide-react";
|
||||||
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
interface ListTestWidgetProps {
|
interface ListTestWidgetProps {
|
||||||
element: DashboardElement;
|
element: DashboardElement;
|
||||||
|
|
@ -155,7 +156,7 @@ export function ListTestWidget({ element }: ListTestWidgetProps) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { DashboardElement } from "@/components/admin/dashboard/types";
|
import { DashboardElement } from "@/components/admin/dashboard/types";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
// Leaflet 아이콘 경로 설정 (엑박 방지)
|
// Leaflet 아이콘 경로 설정 (엑박 방지)
|
||||||
|
|
@ -105,7 +106,7 @@ export default function MapSummaryWidget({ element }: MapSummaryWidgetProps) {
|
||||||
setTableName(extractedTableName);
|
setTableName(extractedTableName);
|
||||||
|
|
||||||
const token = localStorage.getItem("authToken");
|
const token = localStorage.getItem("authToken");
|
||||||
const response = await fetch("/api/dashboards/execute-query", {
|
const response = await fetch(getApiUrl("/api/dashboards/execute-query"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { DashboardElement, ChartDataSource } from "@/components/admin/dashboard/
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Loader2, RefreshCw } from "lucide-react";
|
import { Loader2, RefreshCw } from "lucide-react";
|
||||||
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
import { applyColumnMapping } from "@/lib/utils/columnMapping";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
// Leaflet 아이콘 경로 설정 (엑박 방지)
|
// Leaflet 아이콘 경로 설정 (엑박 방지)
|
||||||
|
|
@ -185,7 +186,7 @@ export default function MapTestWidgetV2({ element }: MapTestWidgetV2Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 백엔드 프록시를 통해 API 호출
|
// 백엔드 프록시를 통해 API 호출
|
||||||
const response = await fetch("/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { RefreshCw, AlertTriangle, Cloud, Construction, Database as DatabaseIcon } from "lucide-react";
|
import { RefreshCw, AlertTriangle, Cloud, Construction, Database as DatabaseIcon } from "lucide-react";
|
||||||
import { DashboardElement, ChartDataSource } from "@/components/admin/dashboard/types";
|
import { DashboardElement, ChartDataSource } from "@/components/admin/dashboard/types";
|
||||||
|
import { getApiUrl } from "@/lib/utils/apiUrl";
|
||||||
|
|
||||||
type AlertType = "accident" | "weather" | "construction" | "system" | "security" | "other";
|
type AlertType = "accident" | "weather" | "construction" | "system" | "security" | "other";
|
||||||
|
|
||||||
|
|
@ -138,7 +139,7 @@ export default function RiskAlertTestWidget({ element }: RiskAlertTestWidgetProp
|
||||||
console.log("🔍 원본 source.queryParams:", source.queryParams);
|
console.log("🔍 원본 source.queryParams:", source.queryParams);
|
||||||
console.log("🔍 원본 source.headers:", source.headers);
|
console.log("🔍 원본 source.headers:", source.headers);
|
||||||
|
|
||||||
const response = await fetch("http://localhost:8080/api/dashboards/fetch-external-api", {
|
const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue