From 661b7450a6f835604f6519320d28cd12d03f7e68 Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 11:21:52 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[feat]=20widget=20validation=20=EB=AA=85?= =?UTF-8?q?=EC=B9=AD=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend-web/public/data/dummyDashboardInfo.json | 4 ++-- frontend-web/public/data/dummyWidgetList.json | 4 ++-- .../src/widget/{validation/index.ts => utils/validation.ts} | 0 3 files changed, 4 insertions(+), 4 deletions(-) rename frontend-web/src/widget/{validation/index.ts => utils/validation.ts} (100%) diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index 3b3f17f..30b7507 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -8,7 +8,7 @@ "title": "라인차트 위젯", "date": "2022-04-11T18:27:45+09:00", "dataSetId": "", - "type": "lineChart", + "type": "CHART_LINE", "option": { "xField": "name", "series": [ @@ -29,7 +29,7 @@ "aggregation": "" } ], - "legendPosition": "left" + "legendPosition": "top" } } ] diff --git a/frontend-web/public/data/dummyWidgetList.json b/frontend-web/public/data/dummyWidgetList.json index e199336..b6507c1 100644 --- a/frontend-web/public/data/dummyWidgetList.json +++ b/frontend-web/public/data/dummyWidgetList.json @@ -4,7 +4,7 @@ "title": "위젯1", "createDate": "2022-04-11T18:27:45+09:00", "dataId": "", - "type": "LINECHART", + "type": "CHART_LINE", "option": { "xField": "title", "series": [ @@ -33,7 +33,7 @@ "title": "위젯2", "createDate": "2022-01-20T13:51:43+09:00", "dataId": "", - "type": "PIECHART", + "type": "CHART_PIE", "option": {} } ] diff --git a/frontend-web/src/widget/validation/index.ts b/frontend-web/src/widget/utils/validation.ts similarity index 100% rename from frontend-web/src/widget/validation/index.ts rename to frontend-web/src/widget/utils/validation.ts From 9e08e1679c7b500ffce7e962309a193d86707aba Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 12:07:02 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[feat]=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?data=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/data/dummyDashboardInfo.json | 2 +- .../pages/Dashboard/DashboardView/index.tsx | 36 +++++++++++++------ .../src/widget/wrapper/WidgetWrapper.tsx | 8 ++--- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index 30b7507..869a8ff 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -4,7 +4,7 @@ "templateId": null, "widgets": [ { - "id": "000001", + "widgetId": "000001", "title": "라인차트 위젯", "date": "2022-04-11T18:27:45+09:00", "dataSetId": "", diff --git a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx index 2554dbe..286e8f6 100644 --- a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx @@ -1,23 +1,35 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { Box, IconButton, Stack } from '@mui/material'; -import { Link as RouterLink, useLocation, useSearchParams } from 'react-router-dom'; +import { Link as RouterLink, useLocation, useMatch, useSearchParams } from 'react-router-dom'; import AutorenewIcon from '@mui/icons-material/Autorenew'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import PageTitleBox from '@/components/PageTitleBox'; import TitleBox from '@/components/TitleBox'; import { DialogAlertIconButton } from '@/components/button/DialogAlertButton'; +import WidgetWrapper from '@/widget/wrapper/WidgetWrapper'; +import { get } from '@/helpers/apiHelper'; +import BoardListItem from '@/components/BoardListItem'; const DashboardView = props => { const location = useLocation(); - const dashboardId = '222'; - const dashboardName = '111'; + const match = useMatch('/dashboard/:dashboard_id'); + const [dashboardInfo, setDashboardInfo] = useState({ title: '', widgets: [] }); + + const [dashboardId, setDashboardId] = useState(null); useEffect(() => { - console.log('location : ', location); - console.log('props.match : ', props); + // console.log('dashboardId : ', match.params.dashboard_id); + setDashboardId(match.params.dashboard_id); + getDashboardInfo(match.params.dashboard_id); }, []); + const getDashboardInfo = id => { + get('/data/dummyDashboardInfo.json').then(response => { + setDashboardInfo(response.data); + }); + }; + const handleRenewClick = () => { console.log('renew'); }; @@ -25,7 +37,7 @@ const DashboardView = props => { return ( @@ -33,18 +45,22 @@ const DashboardView = props => { }> - {`<${dashboardName}>을 삭제하시겠습니까?`} + {`<${dashboardInfo.title}>을 삭제하시겠습니까?`} } > - + + {dashboardInfo.widgets.map(item => ( + + ))} + ); diff --git a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx index 1e0795a..634c41a 100644 --- a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx +++ b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx @@ -2,12 +2,12 @@ import React, { useEffect } from 'react'; import { Box } from '@mui/material'; const WidgetWrapper = props => { - const { widgetId } = props; + const { data } = props; useEffect(() => { - if (widgetId) { - console.log('widgetId : ', widgetId); + if (data) { + console.log('widgetId : ', data); } - }, [widgetId]); + }, [data]); return ; }; From 4bf31c19b8c7e36a3194b24e241c577069c94348 Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 15:03:55 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[feat]=20react=2018=20version=20StrictMode?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/data/dummyDashboardInfo.json | 29 ++++ frontend-web/src/App.tsx | 2 +- .../src/components/widget/WidgetWrapper.tsx | 33 ---- frontend-web/src/index.tsx | 12 +- .../pages/Dashboard/DashboardModify/index.tsx | 2 +- .../pages/Dashboard/DashboardView/index.tsx | 55 +++++- frontend-web/src/pages/Dashboard/index.tsx | 8 +- frontend-web/src/pages/Widget/index.tsx | 6 +- frontend-web/src/serviceWorker.ts | 157 ++++++++++++++++++ .../src/widget/wrapper/WidgetWrapper.tsx | 25 ++- 10 files changed, 268 insertions(+), 61 deletions(-) delete mode 100644 frontend-web/src/components/widget/WidgetWrapper.tsx create mode 100644 frontend-web/src/serviceWorker.ts diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index 869a8ff..8c09e5f 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -31,6 +31,35 @@ ], "legendPosition": "top" } + }, + { + "widgetId": "000002", + "title": "라인차트 위젯2", + "date": "2022-04-11T18:27:45+09:00", + "dataSetId": "", + "type": "CHART_LINE", + "option": { + "xField": "name", + "series": [ + { + "field": "high", + "color": "#43afef", + "aggregation": "" + }, + { + "field": "low", + "color": "#b9e7ff", + "aggregation": "" + } + , + { + "field": "avg", + "color": "#d9d9d9", + "aggregation": "" + } + ], + "legendPosition": "top" + } } ] } diff --git a/frontend-web/src/App.tsx b/frontend-web/src/App.tsx index cca5f12..273854a 100644 --- a/frontend-web/src/App.tsx +++ b/frontend-web/src/App.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { CssBaseline } from '@mui/material'; import Layout from './layouts/Layout'; import Router from './router'; diff --git a/frontend-web/src/components/widget/WidgetWrapper.tsx b/frontend-web/src/components/widget/WidgetWrapper.tsx deleted file mode 100644 index 23e7539..0000000 --- a/frontend-web/src/components/widget/WidgetWrapper.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import { Divider, Box, Stack, Typography } from '@mui/material'; - -function WidgetWrapper(props) { - const { title, width, button } = props; - - return ( - - - - {title} - - {button} - - - {props.children} - - ); -} - -WidgetWrapper.defaultProps = { - title: '', - width: '100%', - menuList: false, - naviUrl: false, - button: false, -}; - -export default WidgetWrapper; diff --git a/frontend-web/src/index.tsx b/frontend-web/src/index.tsx index 7708756..177af70 100644 --- a/frontend-web/src/index.tsx +++ b/frontend-web/src/index.tsx @@ -9,11 +9,9 @@ import './index.css'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - - - - - - , + + + + + , ); diff --git a/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx b/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx index 6be12be..c1f83bd 100644 --- a/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx @@ -23,7 +23,7 @@ function DashboardModify(props) { useEffect(() => { // 여기서 처리 if (selectedWidgets.length > 0) { - console.log(selectedWidgets); + // console.log(selectedWidgets); } }, [selectedWidgets]); diff --git a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx index 286e8f6..a53292f 100644 --- a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Box, IconButton, Stack } from '@mui/material'; +import { Box, Card, IconButton, Stack } from '@mui/material'; import { Link as RouterLink, useLocation, useMatch, useSearchParams } from 'react-router-dom'; import AutorenewIcon from '@mui/icons-material/Autorenew'; import EditIcon from '@mui/icons-material/Edit'; @@ -10,6 +10,7 @@ import { DialogAlertIconButton } from '@/components/button/DialogAlertButton'; import WidgetWrapper from '@/widget/wrapper/WidgetWrapper'; import { get } from '@/helpers/apiHelper'; import BoardListItem from '@/components/BoardListItem'; +import RGL, { Responsive, WidthProvider } from 'react-grid-layout'; const DashboardView = props => { const location = useLocation(); @@ -18,8 +19,26 @@ const DashboardView = props => { const [dashboardId, setDashboardId] = useState(null); + const ReactGridLayout = WidthProvider(RGL); + const layout = [ + { + x: 0, + y: 0, + w: 6, + h: 2, + i: '0', + static: true, + }, + { + x: 6, + y: 0, + w: 6, + h: 3, + i: '1', + static: true, + }, + ]; useEffect(() => { - // console.log('dashboardId : ', match.params.dashboard_id); setDashboardId(match.params.dashboard_id); getDashboardInfo(match.params.dashboard_id); }, []); @@ -34,6 +53,17 @@ const DashboardView = props => { console.log('renew'); }; + const generateWidget = () => { + console.log('generateWidget', dashboardInfo.widgets); + return dashboardInfo.widgets.map((item, index) => { + return ( + + + + ); + }); + }; + return ( { } > - - {dashboardInfo.widgets.map(item => ( - - ))} + + + {dashboardInfo.widgets.map((item, index) => { + return ( + + + + ); + })} + diff --git a/frontend-web/src/pages/Dashboard/index.tsx b/frontend-web/src/pages/Dashboard/index.tsx index 76dc36c..21f8832 100644 --- a/frontend-web/src/pages/Dashboard/index.tsx +++ b/frontend-web/src/pages/Dashboard/index.tsx @@ -1,11 +1,10 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import PageContainer from '@/components/PageContainer'; import PageTitleBox from '@/components/PageTitleBox'; import BoardList from '@/components/BoardList'; import { Outlet, useParams } from 'react-router-dom'; import AddIconButton from '@/components/button/AddIconButton'; -// import { get } from '@/helpers/apiHelper'; -import axios from 'axios'; +import { get } from '@/helpers/apiHelper'; const title = '대시보드'; @@ -17,8 +16,7 @@ function Dashboard(props) { const [loadedCount, setLoadedCount] = useState(1); useEffect(() => { - axios - .get('/data/dummyDashboardList.json') + get('/data/dummyDashboardList.json') .then(response => response.data) .then(data => setLoadedWidgetData(data.filter((list, idx) => idx <= 10 * loadedCount))); setIsLoading(true); diff --git a/frontend-web/src/pages/Widget/index.tsx b/frontend-web/src/pages/Widget/index.tsx index 8bc35e5..9860d25 100644 --- a/frontend-web/src/pages/Widget/index.tsx +++ b/frontend-web/src/pages/Widget/index.tsx @@ -4,8 +4,7 @@ import PageContainer from '@/components/PageContainer'; import PageTitleBox from '@/components/PageTitleBox'; import BoardList from '@/components/BoardList'; import AddIconButton from '@/components/button/AddIconButton'; -// import { get } from '@/helpers/apiHelper'; -import axios from 'axios'; +import { get } from '@/helpers/apiHelper'; const title = '위젯'; @@ -17,8 +16,7 @@ function Widget() { const [loadedCount, setLoadedCount] = useState(1); useEffect(() => { - axios - .get('/data/dummyWidgetList.json') + get('/data/dummyWidgetList.json') .then(response => response.data) .then(data => setLoadedWidgetData(data.filter((list, idx) => idx <= 10 * loadedCount))); setIsLoading(true); diff --git a/frontend-web/src/serviceWorker.ts b/frontend-web/src/serviceWorker.ts new file mode 100644 index 0000000..957f1ff --- /dev/null +++ b/frontend-web/src/serviceWorker.ts @@ -0,0 +1,157 @@ +/* eslint-disable */ +/* @ts-nocheck */ + +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://bit.ly/CRA-PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL( + process.env.PUBLIC_URL, + window.location.href + ); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA' + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator + .serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' } + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + ( + contentType != null && contentType.indexOf('javascript') === -1 + ) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator + .serviceWorker + .ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx index 634c41a..10fedf9 100644 --- a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx +++ b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx @@ -1,14 +1,31 @@ import React, { useEffect } from 'react'; -import { Box } from '@mui/material'; +import { Box, Divider, Stack, Typography } from '@mui/material'; const WidgetWrapper = props => { const { data } = props; useEffect(() => { + console.log('WidgetWrapper'); if (data) { - console.log('widgetId : ', data); + console.log('widget data : ', data); } - }, [data]); - return ; + }, []); + return ( + + + + {data.title} + + + + {props.children} + + ); }; export default WidgetWrapper; From 32c858b83dc36b4f23abdcc886655ea6cfcc5b20 Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 15:05:10 +0900 Subject: [PATCH 4/9] [feat] remove serviceWorker.ts --- frontend-web/src/serviceWorker.ts | 157 ------------------------------ 1 file changed, 157 deletions(-) delete mode 100644 frontend-web/src/serviceWorker.ts diff --git a/frontend-web/src/serviceWorker.ts b/frontend-web/src/serviceWorker.ts deleted file mode 100644 index 957f1ff..0000000 --- a/frontend-web/src/serviceWorker.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* eslint-disable */ -/* @ts-nocheck */ - -// This optional code is used to register a service worker. -// register() is not called by default. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on subsequent visits to a page, after all the -// existing tabs open on the page have been closed, since previously cached -// resources are updated in the background. - -// To learn more about the benefits of this model and instructions on how to -// opt-in, read https://bit.ly/CRA-PWA - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -type Config = { - onSuccess?: (registration: ServiceWorkerRegistration) => void; - onUpdate?: (registration: ServiceWorkerRegistration) => void; -}; - -export function register(config?: Config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL( - process.env.PUBLIC_URL, - window.location.href - ); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' - ); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - -function registerValidSW(swUrl: string, config?: Config) { - navigator - .serviceWorker - .register(swUrl) - .then((registration) => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' - ); - - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } - } - } - }; - }; - }) - .catch((error) => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl: string, config?: Config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl, { - headers: { 'Service-Worker': 'script' } - }) - .then((response) => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - ( - contentType != null && contentType.indexOf('javascript') === -1 - ) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then((registration) => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator - .serviceWorker - .ready - .then((registration) => { - registration.unregister(); - }) - .catch((error) => { - console.error(error.message); - }); - } -} From d2d4aed176fde8e1a94e7d74c14bde4ab2804937 Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 15:50:02 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[feat]=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20=ED=99=94=EB=A9=B4=20=EC=9C=84?= =?UTF-8?q?=EC=A0=AF=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=20=EC=83=98=ED=94=8C=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/data/dummyDashboardInfo.json | 2 +- frontend-web/public/data/sample/chart.json | 98 ++++++++++++ frontend-web/public/data/sample/chart1.json | 142 ++++++++++++++++++ frontend-web/public/data/sample/chart2.json | 126 ++++++++++++++++ .../src/modules/linechart/LineChart.tsx | 18 ++- .../pages/Dashboard/DashboardView/index.tsx | 19 +-- .../src/pages/Widget/WidgetModify/index.tsx | 2 +- .../src/widget/wrapper/WidgetWrapper.tsx | 46 +++++- 8 files changed, 428 insertions(+), 25 deletions(-) create mode 100644 frontend-web/public/data/sample/chart.json create mode 100644 frontend-web/public/data/sample/chart1.json create mode 100644 frontend-web/public/data/sample/chart2.json diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index 8c09e5f..a127d83 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -7,7 +7,7 @@ "widgetId": "000001", "title": "라인차트 위젯", "date": "2022-04-11T18:27:45+09:00", - "dataSetId": "", + "dataSetId": "000001", "type": "CHART_LINE", "option": { "xField": "name", diff --git a/frontend-web/public/data/sample/chart.json b/frontend-web/public/data/sample/chart.json new file mode 100644 index 0000000..2136549 --- /dev/null +++ b/frontend-web/public/data/sample/chart.json @@ -0,0 +1,98 @@ +[ + { + "id": 1, + "name": "january", + "color": "#00BFFF", + "high": 18, + "low": 2, + "avg": 8.9 + }, + { + "id": 2, + "name": "february", + "color": "#4682B4", + "high": 23, + "low": -2, + "avg": 9.9 + }, + { + "id": 3, + "name": "march", + "color": "#00CED1", + "high": 25, + "low": -1, + "avg": 11.3 + }, + { + "id": 4, + "name": "april", + "color": "#3CB371", + "high": 23, + "low": 1, + "avg": 13 + }, + { + "id": 5, + "name": "may", + "color": "#9ACD32", + "high": 26, + "low": 5, + "avg": 16.2 + }, + { + "id": 6, + "name": "june", + "color": "#BDB76B", + "high": 32, + "low": 7, + "avg": 19.9 + }, + { + "id": 7, + "name": "july", + "color": "#FFD700", + "high": 33, + "low": 12, + "avg": 23 + }, + { + "id": 8, + "name": "august", + "color": "#FF8C00", + "high": 33, + "low": 12, + "avg": 23.6 + }, + { + "id": 9, + "name": "september", + "color": "#FF7F50", + "high": 32, + "low": 7, + "avg": 21.1 + }, + { + "id": 10, + "name": "october", + "color": "#F4A460", + "high": 28, + "low": 2, + "avg": 17 + }, + { + "id": 11, + "name": "november", + "color": "#8B4513", + "high": 25, + "low": -2, + "avg": 12.5 + }, + { + "id": 12, + "name": "december", + "color": "#778899", + "high": 22, + "low": -2, + "avg": 10 + } +] \ No newline at end of file diff --git a/frontend-web/public/data/sample/chart1.json b/frontend-web/public/data/sample/chart1.json new file mode 100644 index 0000000..aed84bd --- /dev/null +++ b/frontend-web/public/data/sample/chart1.json @@ -0,0 +1,142 @@ +[ + { + "year": 1970, + "country": "Saudi Arabia", + "oil": 192.2 + }, + { + "year": 1970, + "country": "USA", + "oil": 533.5 + }, + { + "year": 1970, + "country": "Iran", + "oil": 192.6 + }, + { + "year": 1970, + "country": "Mexico", + "oil": 24.2 + }, + { + "year": 1980, + "country": "Saudi Arabia", + "oil": 509.8 + }, + { + "year": 1980, + "country": "USA", + "oil": 480.2 + }, + { + "year": 1980, + "country": "Iran", + "oil": 74.3 + }, + { + "year": 1980, + "country": "Mexico", + "oil": 107.2 + }, + { + "year": 1990, + "country": "Saudi Arabia", + "oil": 342.6 + }, + { + "year": 1990, + "country": "USA", + "oil": 416.6 + }, + { + "year": 1990, + "country": "Iran", + "oil": 162.8 + }, + { + "year": 1990, + "country": "Mexico", + "oil": 146.3 + }, + { + "year": 1990, + "country": "Russia", + "oil": 515.9 + }, + { + "year": 2000, + "country": "Saudi Arabia", + "oil": 456.3 + }, + { + "year": 2000, + "country": "USA", + "oil": 352.6 + }, + { + "year": 2000, + "country": "Iran", + "oil": 191.3 + }, + { + "year": 2000, + "country": "Mexico", + "oil": 171.2 + }, + { + "year": 2000, + "country": "Russia", + "oil": 323.3 + }, + { + "year": 2008, + "country": "Saudi Arabia", + "oil": 515.3 + }, + { + "year": 2008, + "country": "USA", + "oil": 304.9 + }, + { + "year": 2008, + "country": "Iran", + "oil": 209.9 + }, + { + "year": 2008, + "country": "Mexico", + "oil": 157.7 + }, + { + "year": 2008, + "country": "Russia", + "oil": 488.5 + }, + { + "year": 2009, + "country": "Saudi Arabia", + "oil": 459.5 + }, + { + "year": 2009, + "country": "USA", + "oil": 325.3 + }, + { + "year": 2009, + "country": "Iran", + "oil": 202.4 + }, + { + "year": 2009, + "country": "Mexico", + "oil": 147.5 + }, + { + "year": 2009, + "country": "Russia", + "oil": 494.2 + } +] \ No newline at end of file diff --git a/frontend-web/public/data/sample/chart2.json b/frontend-web/public/data/sample/chart2.json new file mode 100644 index 0000000..c3b53ef --- /dev/null +++ b/frontend-web/public/data/sample/chart2.json @@ -0,0 +1,126 @@ +[ + { + "day": "1", + "value": 11 + }, + { + "day": "2", + "value": 7 + }, + { + "day": "3", + "value": 6 + }, + { + "day": "4", + "value": 8 + }, + { + "day": "5", + "value": 7 + }, + { + "day": "6", + "value": 7 + }, + { + "day": "7", + "value": 11 + }, + { + "day": "8", + "value": 9 + }, + { + "day": "9", + "value": 5 + }, + { + "day": "10", + "value": 8 + }, + { + "day": "11", + "value": 6 + }, + { + "day": "12", + "value": 9 + }, + { + "day": "13", + "value": 8 + }, + { + "day": "14", + "value": 6 + }, + { + "day": "15", + "value": 6 + }, + { + "day": "16", + "value": 6 + }, + { + "day": "17", + "value": 10 + }, + { + "day": "18", + "value": 9 + }, + { + "day": "19", + "value": 12 + }, + { + "day": "20", + "value": 9 + }, + { + "day": "21", + "value": 8 + }, + { + "day": "22", + "value": 13 + }, + { + "day": "23", + "value": 9 + }, + { + "day": "24", + "value": 7 + }, + { + "day": "25", + "value": 6 + }, + { + "day": "26", + "value": 11 + }, + { + "day": "27", + "value": 8 + }, + { + "day": "28", + "value": 7 + }, + { + "day": "29", + "value": 9 + }, + { + "day": "30", + "value": 7 + }, + { + "day": "31", + "value": 3 + } +] \ No newline at end of file diff --git a/frontend-web/src/modules/linechart/LineChart.tsx b/frontend-web/src/modules/linechart/LineChart.tsx index 08bb5a8..2d9c1b3 100644 --- a/frontend-web/src/modules/linechart/LineChart.tsx +++ b/frontend-web/src/modules/linechart/LineChart.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import ReactECharts from 'echarts-for-react'; +import { Box } from '@mui/material'; const LineChart = props => { const { option, dataSet, ...rest } = props; @@ -25,8 +26,10 @@ const LineChart = props => { }; useEffect(() => { - const newOption = createComponentOption(); - setComponentOption(newOption); + if (option && dataSet) { + const newOption = createComponentOption(); + setComponentOption(newOption); + } }, [option, dataSet]); /** @@ -47,7 +50,7 @@ const LineChart = props => { const series = { name: item.field, data: dataSet.map(dataItem => dataItem[item.field]), - type: rest.componentType, + type: 'line', smooth: true, }; newSeries.push(series); @@ -72,7 +75,14 @@ const LineChart = props => { }; return ( - + + + ); }; diff --git a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx index a53292f..7afbcb6 100644 --- a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx @@ -56,9 +56,14 @@ const DashboardView = props => { const generateWidget = () => { console.log('generateWidget', dashboardInfo.widgets); return dashboardInfo.widgets.map((item, index) => { + console.log('data', item); return ( - - + + ); }); @@ -94,15 +99,7 @@ const DashboardView = props => { backgroundColor: '#eee', }} > - - {dashboardInfo.widgets.map((item, index) => { - return ( - - - - ); - })} - + {generateWidget()} diff --git a/frontend-web/src/pages/Widget/WidgetModify/index.tsx b/frontend-web/src/pages/Widget/WidgetModify/index.tsx index a6e4b60..d43581f 100644 --- a/frontend-web/src/pages/Widget/WidgetModify/index.tsx +++ b/frontend-web/src/pages/Widget/WidgetModify/index.tsx @@ -33,7 +33,7 @@ function WidgetModify(props) { // 위젯 속성 저장 const handleSubmit = event => { - // datasetId , componentId, widgetTitle, option + // dataSetId , componentId, widgetTitle, option event.preventDefault(); console.log('datesetId:', data.dataId); console.log('widgetType:', data.type); diff --git a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx index 10fedf9..e7e6fcb 100644 --- a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx +++ b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx @@ -1,16 +1,39 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { Box, Divider, Stack, Typography } from '@mui/material'; +import { WIDGET_TYPE } from '@/constant'; +import LineChart from '@/modules/linechart/LineChart'; +import { get } from '@/helpers/apiHelper'; const WidgetWrapper = props => { - const { data } = props; + const { widgetOption, dataSetId } = props; + + const [widget, setWidget] = useState(null); useEffect(() => { console.log('WidgetWrapper'); - if (data) { - console.log('widget data : ', data); + + if (dataSetId) { + getData(); } }, []); + + const getData = () => { + get('/data/sample/chart.json').then(response => { + console.log('res', response.data); + if (widgetOption) { + console.log('widget widgetOption : ', widgetOption); + const widgetType = widgetOption.type; + let module = null; + switch (widgetType) { + case WIDGET_TYPE.CHART_LINE: + module = ; + } + setWidget(module); + } + }); + }; + return ( - { > - {data.title} + {widgetOption && widgetOption.title} - {props.children} - + + {widget} + + ); }; From 3ee26f1ee45c53e0af041443c1b1d91cbd085154 Mon Sep 17 00:00:00 2001 From: jjy Date: Tue, 20 Sep 2022 16:11:44 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A8=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/Dashboard/DashboardModify/index.tsx | 47 ++++++++++--- .../pages/Dashboard/DashboardView/index.tsx | 70 ++++++++++++++++--- frontend-web/src/pages/Dashboard/index.tsx | 5 +- 3 files changed, 98 insertions(+), 24 deletions(-) diff --git a/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx b/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx index 6be12be..03297d5 100644 --- a/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardModify/index.tsx @@ -13,13 +13,16 @@ import '/node_modules/react-resizable/css/styles.css'; const ResponsiveGridLayout = WidthProvider(Responsive); function DashboardModify(props) { - const layout = [ - { i: 'a', x: 0, y: 0, w: 1, h: 2, static: true }, - { i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 }, - { i: 'c', x: 4, y: 0, w: 1, h: 2 }, - ]; - + // const layout = [ + // { i: 'a', x: 0, y: 0, w: 1, h: 2, static: true }, + // { i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 }, + // { i: 'c', x: 4, y: 0, w: 1, h: 2 }, + // ]; + // 현재 선택된 widget 목록 const [selectedWidgets, setSelectedWidgets] = useState([]); + // 화면에 그려질 widget 목록 + const [widgets, setWidgets] = useState([]); + useEffect(() => { // 여기서 처리 if (selectedWidgets.length > 0) { @@ -27,10 +30,34 @@ function DashboardModify(props) { } }, [selectedWidgets]); + useEffect(() => { + // 여기서 처리 + if (widgets.length > 0) { + console.log(widgets); + } + }, [widgets]); + + // 현재 위젯 선택창에서 선택된 위젯 목록 callback const handleWidgetSelect = items => { setSelectedWidgets(items); }; + const onAddItems = items => { + // console.log('adding', 'n' + this.state.newCounter); + // this.setState({ + // // Add a new item. It must have a unique key! + // items: this.state.items.concat({ + // i: "n" + this.state.newCounter, + // x: (this.state.items.length * 2) % (this.state.cols || 12), + // y: Infinity, // puts it at the bottom + // w: 2, + // h: 2 + // }), + // // Increment the counter to ensure key is always unique. + // newCounter: this.state.newCounter + 1 + // }); + }; + return ( - - a - b - c + + {/*a*/} + {/*b*/} + {/*c*/} diff --git a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx index 2554dbe..44ab845 100644 --- a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx @@ -1,25 +1,49 @@ -import React, { useEffect } from 'react'; -import { Box, IconButton, Stack } from '@mui/material'; +import React, { useEffect, useState } from 'react'; +import { Box, IconButton, Stack, Card } from '@mui/material'; import { Link as RouterLink, useLocation, useSearchParams } from 'react-router-dom'; import AutorenewIcon from '@mui/icons-material/Autorenew'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import PageTitleBox from '@/components/PageTitleBox'; import TitleBox from '@/components/TitleBox'; +import { Outlet, useParams } from 'react-router-dom'; import { DialogAlertIconButton } from '@/components/button/DialogAlertButton'; +import { get } from '@/helpers/apiHelper'; +import GridLayout, { Responsive, WidthProvider } from 'react-grid-layout'; +import '/node_modules/react-grid-layout/css/styles.css'; +import '/node_modules/react-resizable/css/styles.css'; + +const ResponsiveGridLayout = WidthProvider(Responsive); const DashboardView = props => { + const [dashboardInfo, setDashboardInfo] = useState({}); + const [dashboardName, setDashboardName] = useState(''); + const { dashboard_id } = useParams(); const location = useLocation(); - const dashboardId = '222'; - const dashboardName = '111'; + + console.log('대시보드 view 호출 ', dashboard_id); useEffect(() => { - console.log('location : ', location); - console.log('props.match : ', props); + // dashboard 호출 + // todo 서비스 연결시 dashboard_id 값을 이용하여 호출 + getDashboardInfo(dashboard_id); }, []); - const handleRenewClick = () => { - console.log('renew'); + useEffect(() => { + console.log(dashboardInfo); + setDashboardName(dashboardInfo['title']); + }, [dashboardInfo]); + + // dashboard 조회 + const getDashboardInfo = dashboardId => { + get('/data/dummyDashboardInfo.json') + .then(response => response.data) + .then(data => setDashboardInfo(data)); + }; + + // 대시보드 재조회 + const handleRefreshClick = dashboardId => { + getDashboardInfo(dashboard_id); }; return ( @@ -28,12 +52,12 @@ const DashboardView = props => { title={dashboardName} button={ - + @@ -44,10 +68,34 @@ const DashboardView = props => { } > - + {/**/} + + + {/*a*/} + {/*b*/} + {/*c*/} + + ); }; +// widget 생성 +const createWidgetElement = props => { + console.log('위젯을 생성한다.'); + return ( + <> + a + + ); +}; + export default DashboardView; diff --git a/frontend-web/src/pages/Dashboard/index.tsx b/frontend-web/src/pages/Dashboard/index.tsx index 76dc36c..b65ea21 100644 --- a/frontend-web/src/pages/Dashboard/index.tsx +++ b/frontend-web/src/pages/Dashboard/index.tsx @@ -4,7 +4,7 @@ import PageTitleBox from '@/components/PageTitleBox'; import BoardList from '@/components/BoardList'; import { Outlet, useParams } from 'react-router-dom'; import AddIconButton from '@/components/button/AddIconButton'; -// import { get } from '@/helpers/apiHelper'; +import { get } from '@/helpers/apiHelper'; import axios from 'axios'; const title = '대시보드'; @@ -17,8 +17,7 @@ function Dashboard(props) { const [loadedCount, setLoadedCount] = useState(1); useEffect(() => { - axios - .get('/data/dummyDashboardList.json') + get('/data/dummyDashboardList.json') .then(response => response.data) .then(data => setLoadedWidgetData(data.filter((list, idx) => idx <= 10 * loadedCount))); setIsLoading(true); From 57a560212bcd70e8f5fde78d36e6bc25cadf98fc Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 16:54:17 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[feat]=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20=ED=99=94=EB=A9=B4=20=EC=9C=84?= =?UTF-8?q?=EC=A0=AF=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=20=EC=83=98=ED=94=8C=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/data/dummyDashboardInfo.json | 47 ++++++++++--------- .../src/pages/Widget/WidgetCreate/index.tsx | 2 +- .../src/widget/wrapper/WidgetWrapper.tsx | 11 +++++ 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index a127d83..4bcc4bf 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -29,36 +29,37 @@ "aggregation": "" } ], - "legendPosition": "top" + "legendPosition": "left" } }, { "widgetId": "000002", - "title": "라인차트 위젯2", + "title": "파이차트 위젯", "date": "2022-04-11T18:27:45+09:00", - "dataSetId": "", - "type": "CHART_LINE", + "dataSetId": "00001", + "type": "CHART_PIE", "option": { "xField": "name", - "series": [ - { - "field": "high", - "color": "#43afef", - "aggregation": "" - }, - { - "field": "low", - "color": "#b9e7ff", - "aggregation": "" - } - , - { - "field": "avg", - "color": "#d9d9d9", - "aggregation": "" - } - ], - "legendPosition": "top" + "series": { + "field": "high", + "color": [ + "#5470c6", + "#91cc75", + "#fac858", + "#ee6666", + "#73c0de", + "#3ba272", + "#fc8452", + "#9a60b4", + "#ea7ccc", + "#5470c6", + "#91cc75", + "#fac858" + ], + "aggregation": "", + "label": "name" + }, + "legendPosition": "right" } } ] diff --git a/frontend-web/src/pages/Widget/WidgetCreate/index.tsx b/frontend-web/src/pages/Widget/WidgetCreate/index.tsx index 03e9708..de79a20 100644 --- a/frontend-web/src/pages/Widget/WidgetCreate/index.tsx +++ b/frontend-web/src/pages/Widget/WidgetCreate/index.tsx @@ -72,7 +72,7 @@ function WidgetCreate(props) { const handleSubmit = event => { event.preventDefault(); setIsSubmit(true); - + console.log('widgetOption:', widgetOption); if (!isWidgetValueValid) { return; } diff --git a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx index e7e6fcb..f353d2c 100644 --- a/frontend-web/src/widget/wrapper/WidgetWrapper.tsx +++ b/frontend-web/src/widget/wrapper/WidgetWrapper.tsx @@ -3,6 +3,9 @@ import { Box, Divider, Stack, Typography } from '@mui/material'; import { WIDGET_TYPE } from '@/constant'; import LineChart from '@/modules/linechart/LineChart'; import { get } from '@/helpers/apiHelper'; +import LineChartSetting from '@/widget/settings/LineChartSetting'; +import PieChart from '@/modules/piechart/PieChart'; +import PieChartSetting from '@/widget/settings/PieChartSetting'; const WidgetWrapper = props => { const { widgetOption, dataSetId } = props; @@ -26,6 +29,14 @@ const WidgetWrapper = props => { switch (widgetType) { case WIDGET_TYPE.CHART_LINE: module = ; + break; + case WIDGET_TYPE.CHART_BAR: + break; + case WIDGET_TYPE.CHART_PIE: + module = ; + break; + + default: } setWidget(module); } From a5d4b84b29ce4a3e14b31e777456ff654b9e0f3a Mon Sep 17 00:00:00 2001 From: ivy Date: Tue, 20 Sep 2022 17:52:59 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[feat]=20piechart=20color=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/linechart/LineChart.tsx | 3 +-- .../src/modules/piechart/PieChart.tsx | 21 +++++-------------- .../WidgetCreate/WidgetAttributeSelect.tsx | 2 ++ 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/frontend-web/src/modules/linechart/LineChart.tsx b/frontend-web/src/modules/linechart/LineChart.tsx index 2d9c1b3..7b413b1 100644 --- a/frontend-web/src/modules/linechart/LineChart.tsx +++ b/frontend-web/src/modules/linechart/LineChart.tsx @@ -44,8 +44,7 @@ const LineChart = props => { // series option에서 가져오기 const newSeries = []; const newColors = []; - option.series.forEach((item, index) => { - // console.log(item, index); + option.series.forEach(item => { if (item.field) { const series = { name: item.field, diff --git a/frontend-web/src/modules/piechart/PieChart.tsx b/frontend-web/src/modules/piechart/PieChart.tsx index efc3007..7103a1f 100644 --- a/frontend-web/src/modules/piechart/PieChart.tsx +++ b/frontend-web/src/modules/piechart/PieChart.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import ReactECharts from 'echarts-for-react'; const PieChart = props => { @@ -15,16 +15,7 @@ const PieChart = props => { orient: 'vertical', left: 'left', }, - series: [ - { - type: 'pie', - smooth: true, - }, - { - type: 'pie', - smooth: true, - }, - ], + series: [], emphasis: { itemStyle: { shadowBlur: 10, @@ -35,7 +26,7 @@ const PieChart = props => { }; useEffect(() => { - // console.log('PieChart ', option, dataSet); + setComponentOption(defaultComponentOption); setComponentOption(createComponentOption()); }, [option, dataSet]); @@ -45,30 +36,28 @@ const PieChart = props => { * 컴포넌트에 맞는 형태로 생성 */ const createComponentOption = () => { - let newOption = defaultComponentOption; + let newOption = { ...defaultComponentOption }; const getData = () => dataSet.map(item => ({ value: item[option.series.field], name: item[option.series.label], })); - if (dataSet) { const op = { type: 'pie', smooth: true, + color: [...option.series.color], series: [ { type: 'pie', smooth: true, data: getData(), - color: option.series.color, // 옵션값은 바뀌는데 색은 왜 제때 안 바뀔까요.. }, ], }; newOption = { ...defaultComponentOption, ...op }; } - return newOption; }; diff --git a/frontend-web/src/pages/Widget/WidgetCreate/WidgetAttributeSelect.tsx b/frontend-web/src/pages/Widget/WidgetCreate/WidgetAttributeSelect.tsx index a9b1e51..3185509 100644 --- a/frontend-web/src/pages/Widget/WidgetCreate/WidgetAttributeSelect.tsx +++ b/frontend-web/src/pages/Widget/WidgetCreate/WidgetAttributeSelect.tsx @@ -24,6 +24,8 @@ function WidgetAttributeSelect(props) { const [switchChart, setSwitchChart] = useState(defaultChart); useEffect(() => { + console.log('option changed', option); + const ChartProps = { option: option, dataSet: chartData, From f4ebe177bc995ef220cde4ff2de5bcc70f8fd38e Mon Sep 17 00:00:00 2001 From: jjy Date: Tue, 20 Sep 2022 17:55:36 +0900 Subject: [PATCH 9/9] =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A8=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/data/dummyDashboardInfo.json | 16 ++++++++ .../pages/Dashboard/DashboardView/index.tsx | 40 ++++--------------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/frontend-web/public/data/dummyDashboardInfo.json b/frontend-web/public/data/dummyDashboardInfo.json index 8c09e5f..409b710 100644 --- a/frontend-web/public/data/dummyDashboardInfo.json +++ b/frontend-web/public/data/dummyDashboardInfo.json @@ -2,6 +2,22 @@ "dashboardId": "0001", "title": "대시보드 1", "templateId": null, + "layout": [ + { + "x": 0, + "y": 0, + "w": 3, + "h": 1, + "i": "000001" + }, + { + "x": 0, + "y": 10, + "w": 5, + "h": 2, + "i": "000002" + } + ], "widgets": [ { "widgetId": "000001", diff --git a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx index a34bfc6..8521367 100644 --- a/frontend-web/src/pages/Dashboard/DashboardView/index.tsx +++ b/frontend-web/src/pages/Dashboard/DashboardView/index.tsx @@ -11,33 +11,20 @@ import WidgetWrapper from '@/widget/wrapper/WidgetWrapper'; import { get } from '@/helpers/apiHelper'; import BoardListItem from '@/components/BoardListItem'; import RGL, { Responsive, WidthProvider } from 'react-grid-layout'; +import '/node_modules/react-grid-layout/css/styles.css'; +import '/node_modules/react-resizable/css/styles.css'; + +const ResponsiveGridLayout = WidthProvider(Responsive); const DashboardView = props => { const location = useLocation(); const match = useMatch('/dashboard/:dashboard_id'); - const [dashboardInfo, setDashboardInfo] = useState({ title: '', widgets: [] }); + const [dashboardInfo, setDashboardInfo] = useState({ title: '', widgets: [], layout: [] }); const [dashboardId, setDashboardId] = useState(null); const ReactGridLayout = WidthProvider(RGL); - const layout = [ - { - x: 0, - y: 0, - w: 6, - h: 2, - i: '0', - static: true, - }, - { - x: 6, - y: 0, - w: 6, - h: 3, - i: '1', - static: true, - }, - ]; + useEffect(() => { setDashboardId(match.params.dashboard_id); getDashboardInfo(match.params.dashboard_id); @@ -53,17 +40,6 @@ const DashboardView = props => { getDashboardInfo(match.params.dashboard_id); }; - const generateWidget = () => { - console.log('generateWidget', dashboardInfo.widgets); - return dashboardInfo.widgets.map((item, index) => { - return ( - - - - ); - }); - }; - return ( { backgroundColor: '#eee', }} > - + {dashboardInfo.widgets.map((item, index) => { return ( @@ -102,7 +78,7 @@ const DashboardView = props => { ); })} - +