diff --git a/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js b/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js index 65aeff3..9bbd989 100644 --- a/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js +++ b/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js @@ -15,192 +15,175 @@ import { FlightPlanDraw } from '../../../map/naver/draw/FlightPlanDraw'; import { drawTypeChangeAction, drawCheckAction } from '../../../../modules/control/map/actions/controlMapActions'; import { FlightPlanDrawTest } from '../../../map/naver/draw/FlightPlanDrawTest'; -const FlightPlanAreaDetailForm = ({ handleClose }) => { - const dispatch = useDispatch(); - const naver = window.naver; - // const airArea = props.airArea; +const FlightPlanAreaDetailForm = ({ handleSave, handleClose, handleChange, data }) => { - const mapControl = useSelector(state => state.controlMapReducer); + const coordList = data ? data[0].coordList : null; - const [map, setMap] = useState(); - const [isMapLoad, setIsMapLoad] = useState(false); - const [mode, setMode] = useState(); + return ( + + + + + + +
+
+
+

비행 구역 상세 정보

+
+
- // useEffect(() => { - // setIsMapLoad(true); - // }, [airArea]); +
+
+
+

좌표 정보

+
- // useEffect(() => { - // ModeInit(); - // }, [mapControl.drawType]) +
+ + {coordList ? + coordList.map((coord, idx) => { + const latlon = coord.lat + ' / ' + coord.lon; - // const ModeInit = () => { - // setMode(mapControl.drawType) - // } - - return ( - // - - - - - - - - -
- {/*
-
-

비행 구역 상세 정보

-
-
*/} - -
-
-
-

좌표 정보

-
- -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - -
-
- -
-
-

기타 정보

-
- -
- - - -
- + return ( + + + -
-
- -
-
- - - - - - - -
-
-
-
-
+ + + ) + }) + : + + + + + + + } + +
+
+
+ +
+
+

기타 정보

+
+ +
+ + + + + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> + + + +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> + + + +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> + + + +
+
+
+
-
- - 등록 - - handleClose()} - > - 닫기 - -
-
-
- -
-
-
- - +
+ handleSave()} + > + 등록 + + handleClose()} + > + 닫기 + +
+ + + + + + ) } diff --git a/src/components/basis/flight/plan/FlightPlanAreaDetailModal.js b/src/components/basis/flight/plan/FlightPlanAreaDetailModal.js deleted file mode 100644 index 188b20c..0000000 --- a/src/components/basis/flight/plan/FlightPlanAreaDetailModal.js +++ /dev/null @@ -1,31 +0,0 @@ -import { useEffect, useState } from 'react'; -import { Modal, ModalHeader, ModalBody } from 'reactstrap'; -import FlightPlanAreaDetailContainer from '../../../../containers/basis/flight/plan/FlightPlanAreaDetailContainer'; - -export const FlightPlanAreaDetailModal = ({modal, handleModal}) => { - return ( -
- - handleModal({isOpen: false, title: ''}) - } - className='modal-dialog-centered modal-xl' - > - - handleModal({isOpen: false, title: ''}) - } - > - {modal.title} - - - - - -
- ); -}; diff --git a/src/components/basis/flight/plan/FlightPlanAreaMap.js b/src/components/basis/flight/plan/FlightPlanAreaMap.js index 0a632a1..3a2f1ca 100644 --- a/src/components/basis/flight/plan/FlightPlanAreaMap.js +++ b/src/components/basis/flight/plan/FlightPlanAreaMap.js @@ -13,21 +13,23 @@ import { useDispatch, useSelector } from 'react-redux'; import { FeatureAirZone } from '../../../map/naver/feature/FeatureAirZone'; import { drawTypeChangeAction, drawCheckAction } from '../../../../modules/control/map/actions/controlMapActions'; import { FlightPlanDrawTest } from '../../../map/naver/draw/FlightPlanDrawTest'; +import { initFlight, initFlightBas } from '../../../../modules/basis/flight/models/basisFlightModel'; +import { AREA_COORDINATE_LIST_SAVE } from '../../../../modules/basis/flight/actions/basisFlightAction'; +import { VscDebugBreakpointLogUnverified } from 'react-icons/vsc'; const FlightPlanAreaMap = (props) => { const dispatch = useDispatch(); const naver = window.naver; - const airArea = props.airArea; - const openModal = props.openModal; + const airArea = props.airArea; const mapControl = useSelector(state => state.controlMapReducer); const [map, setMap] = useState(); const [isMapLoad, setIsMapLoad] = useState(false); const [mode, setMode] = useState(); + const [areaCoordList, setAreaCoordList] = useState(initFlightBas.initDetail.areaList); - useEffect(() => { - + useEffect(() => { NaverMapInit(); }, []); @@ -67,6 +69,31 @@ const FlightPlanAreaMap = (props) => { const handlerDrawCheck = val => { dispatch(drawCheckAction(val)); }; + + const handleCoordinates = (coords, radius) => { + const initAreaList = Object.assign([], initFlightBas.initDetail.areaList); + const coordList = []; + + // radius = 10; + coords.forEach((c, i) => { + const coord = Object.assign({}, initFlightBas['coord']); + + coord.lat = c._lat; + coord.lon = c._lng; + + coordList.push(coord); + }); + + const areaList = initAreaList.map((area, i) => { + return { + ...area, + coordList : coordList + } + }) + + // dispatch(AREA_COORDINATE_LIST_SAVE(areaList)) + setAreaCoordList(areaList); + } return ( @@ -84,14 +111,14 @@ const FlightPlanAreaMap = (props) => { props.handleModal({isOpen: true, title: '비행 구역 상세 정보'})} + onClick = {e => props.handleConfirm(areaCoordList)} > 확인 @@ -138,37 +165,7 @@ const FlightPlanAreaMap = (props) => { > Polygon - - - {mapControl.drawType === 'LINE' ? -
- - - - - - - handlerDrawType('POLYGON')} - > - 적용 - - - -
- : - null - } - +
) diff --git a/src/components/basis/flight/plan/FlightPlanForm.js b/src/components/basis/flight/plan/FlightPlanForm.js index 1ee9f07..60a04fc 100644 --- a/src/components/basis/flight/plan/FlightPlanForm.js +++ b/src/components/basis/flight/plan/FlightPlanForm.js @@ -21,6 +21,7 @@ import FlightPlanAreaContainer from '../../../../containers/basis/flight/plan/Fl const FlightPlanForm = ({data, handleModal, handleChange, handleSave, handleDelete, modal}) => { const {areaList, pilotList, arcrftList} = data; + return ( @@ -390,7 +391,7 @@ const AreaForm = ({data, handleChange, index}) => { {data && data.coordList && data.coordList.length > 0 ? data.coordList.map((item, i) => { return { value={(item.lat && item.lon) ? `${item.lat} / ${item.lon}` : ''} bsSize='sm' placeholder='-' - onChange={(e) => { - const {name, value} = e.target; - handleChange({ - type: 'coord', - name, - value, - index: i, - pIndex: index - }) - }} - style={{marginBottom: 5}} - // readOnly + // onChange={(e) => { + // const {name, value} = e.target; + // handleChange({ + // type: 'coord', + // name, + // value, + // index: i, + // pIndex: index + // }) + // }} + // style={{marginBottom: 5}} + readOnly /> }) : { pIndex: index }) }} - // readOnly + readOnly />} @@ -456,7 +457,7 @@ const AreaForm = ({data, handleChange, index}) => { index }) }} - + readOnly />
@@ -477,7 +478,7 @@ const AreaForm = ({data, handleChange, index}) => { index }) }} - + readOnly />
@@ -504,6 +505,7 @@ const AreaForm = ({data, handleChange, index}) => { index }) }} + readOnly /> diff --git a/src/components/map/naver/draw/FlightPlanDrawTest.js b/src/components/map/naver/draw/FlightPlanDrawTest.js index c63d059..95e19e0 100644 --- a/src/components/map/naver/draw/FlightPlanDrawTest.js +++ b/src/components/map/naver/draw/FlightPlanDrawTest.js @@ -205,19 +205,20 @@ export const FlightPlanDrawTest = props => { setDragCircle(dragCircle); //파싱 - let polypathJSON = new Array(); - for(let i = 0; i< polypaths.length; i++) { - let obj = new Object(); + // let polypathJSON = new Array(); + // for(let i = 0; i< polypaths.length; i++) { + // let obj = new Object(); - obj.x = '' + polypaths[i]._lng + ''; - obj.y = '' + polypaths[i]._lat + ''; + // obj.x = '' + polypaths[i]._lng + ''; + // obj.y = '' + polypaths[i]._lat + ''; - obj = JSON.stringify(obj); - polypathJSON.push(JSON.parse(obj)); - } + // obj = JSON.stringify(obj); + // polypathJSON.push(JSON.parse(obj)); + // } // console.log(polypathJSON, 'json polyline path'); // bufferMove(); - bufferTest(); + // bufferTest(); + props.handleCoordinates(polypaths); } else { polyline.setMap(null); polyline = ''; @@ -496,11 +497,13 @@ export const FlightPlanDrawTest = props => { check = false; } - const setAreaInfo = (path, bufferpath) => { + const setAreaInfo = (path, bufferpath) => { areaInfo = ''; - let prePath = []; - path.forEach(prev=> prePath.push([prev.x, prev.y])) + if(path) { + let prePath = []; + path.forEach(prev=> prePath.push([prev.x, prev.y])) + } if(polyline) { areaInfo = { diff --git a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js index b2d1c8b..992c423 100644 --- a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js @@ -8,53 +8,52 @@ import FlightPlanAreaMap from '../../../../components/basis/flight/plan/FlightPl import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; -import { FlightPlanAreaDetailModal } from '../../../../components/basis/flight/plan/FlightPlanAreaDetailModal'; +import FlightPlanAreaDetailContainer from './FlightPlanAreaDetailContainer'; -const FlightPlanAreaContainer = () => { +const FlightPlanAreaContainer = ({handleModal}) => { const dispatch = useDispatch(); - const { areaList } = useSelector(state => state.flightState); - const [airArea, setAirArea] = useState(null); - const [modal, setModal] = useState({isOpen: false, title: ''}); - + const { publicAreaList} = useSelector(state => state.flightState); + const [airArea, setAirArea] = useState(null); const getAirAreaList = () => { - dispatch(Actions.AREA_LIST.request()); - } - - const handleModal = ({isOpen, title}) => { - setModal({ - isOpen: isOpen, - title: title - }); + dispatch(Actions.PUBLIC_AREA_LIST.request()); + } + + const handleConfirm = (areaList) => { + if(areaList === undefined) { + alert('영역을 설정해주세요.') + return false; + } + + dispatch(Actions.AREA_COORDINATE_LIST_SAVE(areaList)) } useEffect(() => { - dispatch(drawTypeChangeAction('RESET')); + dispatch(drawTypeChangeAction('RESET')); getAirAreaList(); }, []); useEffect(() => { - setAirArea(areaList); - }, [areaList]) + setAirArea(publicAreaList); + }, [publicAreaList]) return ( - + {airArea != null ? ( - ) : null} - {modal.isOpen ? ( - - ) : null} - + ) : null} + + + + ) diff --git a/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js index 1e3d598..150f5e1 100644 --- a/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js @@ -1,24 +1,77 @@ import React, { useEffect, useState } from 'react'; -import { useForm } from 'react-hook-form'; -import { useHistory } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Col, Row, Form } from 'reactstrap'; import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; import FlightPlanAreaDetailForm from '../../../../components/basis/flight/plan/FlightPlanAreaDetailForm'; +import {initFlightBas} from '../../../../modules/basis/flight/models/basisFlightModel'; -const FlightPlanAreaDetailContainer = ({ modal, handleModal }) => { - const handleClose = () => { - handleModal({isOpen : false, title: ''}); + +const FlightPlanAreaDetailContainer = ({ handleModal }) => { + const dispatch = useDispatch(); + + const { areaCoordList, areaList, detail } = useSelector(state => state.flightState); + const [areaDetail, setAreaDetail] = useState(initFlightBas.initDetail.areaList); + + const handleClose = (status) => { + handleModal({ type: 'area', isOpne: false}); + } + + const handleSave = () => { + + if(areaDetail[0].coordList.length <= 1) { + alert('영역을 생성해주세요.'); + return false; + } + + const resultAreaDetail = areaDetail.map((area, i) => { + return { + ...area, + coordList : areaDetail[0].coordList + } + }); + + dispatch(Actions.AREA_DETAIL_LIST_SAVE(resultAreaDetail)); + + handleModal({ type: 'area', isOpne: false}); + } + + const handleChange = ({ name, value }) => { + setAreaDetail(prevState => { + const areaList = prevState.map((area, i) => { + return { + ...area, + [name] : value + } + }); + + return areaList; + }) } + useEffect(() => { + // 좌표등록 (등록 시 데이터 초기화) + if(areaCoordList !== undefined) { + setAreaDetail(areaCoordList); // 새로 만든 영역 + } + }, [areaCoordList]); + + useEffect(() => { + // detail의 area 정보가 존재하면 detail 정보로 매핑 + if(detail.areaList[0].planAreaSno !== 0) { + setAreaDetail(detail.areaList); + } + }, []) + return ( diff --git a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js index 7b7903c..d1e9ecb 100644 --- a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js @@ -19,7 +19,7 @@ const FlightPlanDetailContainer = () => { const location = useLocation(); const urlParams = useParams(); const flightState = useSelector(state => state.flightState); - const { detail, pilotSelect, arcrftSelect } = flightState; + const { detail, pilotSelect, arcrftSelect, areaList } = flightState; const [modal, setModal] = useState(initModal); const [detailData, setDetailData] = useState(initFlightBas.initDetail); @@ -64,7 +64,7 @@ const FlightPlanDetailContainer = () => { }, [pilotSelect]) - useEffect(() => { + useEffect(() => { if(arcrftSelect !== undefined) { const arcrftList = detailData.arcrftList.concat(); const arcrft = Object.assign({}, initFlightBas['arcrft']); @@ -97,9 +97,39 @@ const FlightPlanDetailContainer = () => { } }, [arcrftSelect]) + useEffect(() => { + if(areaList !== undefined) { + const detailAreaList = detailData.areaList.concat(); + const area = Object.assign({}, initFlightBas['area']); + + area.bufferZone = areaList[0].bufferZone; + area.fltElev = areaList[0].fltElev; + area.fltMethod = areaList[0].fltMethod; + area.coordList = areaList[0].coordList; + + detailAreaList.forEach((a, i) => { + detailAreaList[i] = area; + + // if(a.planAreaSno === 0) { // create + // areaList[i] = area; + // } else { // update + + // } + }); + + setDetailData(prevState => { + return { + ...prevState, + ['areaList']: detailAreaList + } + }) + } + + }, [areaList]); + useEffect(() => { // 조종사, 기체 정보 Redux 초기화 - dispatch(Actions.PILOT_ARCRFT_SELECT_INIT()); + // dispatch(Actions.PILOT_ARCRFT_SELECT_INIT()); }) const handleModal = (modal) => { diff --git a/src/modules/basis/flight/actions/basisFlightAction.ts b/src/modules/basis/flight/actions/basisFlightAction.ts index bb51e31..6d629c5 100644 --- a/src/modules/basis/flight/actions/basisFlightAction.ts +++ b/src/modules/basis/flight/actions/basisFlightAction.ts @@ -1,9 +1,10 @@ import { AxiosError } from 'axios'; import { createAsyncAction, ActionType, createAction } from 'typesafe-actions'; import { - FlightAreaData, + PublicAreaData, FlightPlanArcrftData, FlightPlanArcrftDataList, + FlightPlanAreaDataList, // FlightPlanArea, FlightPlanData, FlightPlanListRqData, FlightPlanPilotDataList, PilotSelectData @@ -11,9 +12,9 @@ import { // 공역 조회 -const AREA_LIST_REQUEST = 'basis/flight/area/LIST_REQUEST'; -const AREA_LIST_SUCCESS = 'basis/flight/area/LIST_SUCCESS'; -const AREA_LIST_FAILURE = 'basis/flight/area/LIST_FAILURE'; +const PUBLIC_AREA_LIST_REQUEST = 'basis/flight/public_area/LIST_REQUEST'; +const PUBLIC_AREA_LIST_SUCCESS = 'basis/flight/public_area/LIST_SUCCESS'; +const PUBLIC_AREA_LIST_FAILURE = 'basis/flight/public_area/LIST_FAILURE'; // 비행 구역 설정 // const FLIGHT_PLAN_AREA_REQUEST = 'basis/flight/plan/area/LIST_REQUEST'; @@ -65,12 +66,17 @@ const FLIGHT_PLAN_ARCRFT_SELECT = 'basis/flight/plan/arcrft_list/ARCRFT_SELECT'; // 조종사, 기체 선택 초기화 const PILOT_ARCRFT_SELECT_INITIAL = 'basis/flight/plan/detail/SELECT_INIT'; +// 비행 구역 좌표 저장 +const AREA_COORDINATE_LIST = 'basis/flight/plan/area/COORDINATE_LIST'; -export const AREA_LIST = createAsyncAction( - AREA_LIST_REQUEST, - AREA_LIST_SUCCESS, - AREA_LIST_FAILURE -)(); +// 비행 구역 상세 저장 +const AREA_DETAIL_LIST = 'basis/flight/plan/area/DETAIL_LIST'; + +export const PUBLIC_AREA_LIST = createAsyncAction( + PUBLIC_AREA_LIST_REQUEST, + PUBLIC_AREA_LIST_SUCCESS, + PUBLIC_AREA_LIST_FAILURE +)(); // export const FLIGHT_PLAN_AREA = createAsyncAction( // FLIGHT_PLAN_AREA_REQUEST, @@ -137,9 +143,14 @@ export const ARCRFT_SELECT = createAction(FLIGHT_PLAN_ARCRFT_SELECT)(); + +// 비행 구역 상세 저장 +export const AREA_DETAIL_LIST_SAVE = createAction(AREA_DETAIL_LIST)(); const actions = { - AREA_LIST, + PUBLIC_AREA_LIST, // FLIGHT_PLAN_AREA, FLIGHT_PLAN_LIST, FLIGHT_PLAN_DETAIL, @@ -151,7 +162,9 @@ const actions = { FLIGHT_PLAN_ARCRFT_LIST, PILOT_SELECT, ARCRFT_SELECT, - PILOT_ARCRFT_SELECT_INIT + PILOT_ARCRFT_SELECT_INIT, + AREA_COORDINATE_LIST_SAVE, + AREA_DETAIL_LIST_SAVE }; export type FlightAction = ActionType; diff --git a/src/modules/basis/flight/models/basisFlightModel.ts b/src/modules/basis/flight/models/basisFlightModel.ts index 401562f..6ba38bc 100644 --- a/src/modules/basis/flight/models/basisFlightModel.ts +++ b/src/modules/basis/flight/models/basisFlightModel.ts @@ -1,7 +1,7 @@ import moment from "moment"; export interface FlightState { - areaList: FlightAreaData | undefined + publicAreaList: PublicAreaData | undefined flightPlanArea: FlightPlanArea | undefined list: [FlightPlanData] | undefined detail: FlightPlanData | undefined @@ -9,10 +9,12 @@ export interface FlightState { arcrftList: FlightPlanArcrftDataList | undefined pilotSelect: PilotSelectData | undefined arcrftSelect: FlightPlanArcrftData | undefined + areaCoordList: FlightPlanAreaData[] | undefined + areaList: FlightPlanAreaData[] | undefined } -export interface FlightAreaData { - areaList: [] +export interface PublicAreaData { + publicAreaList: [] } export interface FlightPlanArea { @@ -156,9 +158,16 @@ export interface PilotSelectData { zip: string } +export interface AreaCoordinateCreateData { + lat: number, + lon: number, + bufferZone: string, + radius: number +} + export const initFlight = { - areaList: undefined, + publicAreaList: undefined, flightPlanArea: undefined, list: undefined, detail: { @@ -251,7 +260,9 @@ export const initFlight = { pilotList: undefined, arcrftList: undefined, pilotSelect: undefined, - arcrftSelect: undefined + arcrftSelect: undefined, + areaCoordList: undefined, + areaList: undefined }; diff --git a/src/modules/basis/flight/reducers/basisFlightReducer.ts b/src/modules/basis/flight/reducers/basisFlightReducer.ts index d1bf3f1..deab581 100644 --- a/src/modules/basis/flight/reducers/basisFlightReducer.ts +++ b/src/modules/basis/flight/reducers/basisFlightReducer.ts @@ -7,10 +7,10 @@ import { any } from 'prop-types'; export const flightReducer = createReducer(initFlight) - .handleAction(Actions.AREA_LIST.success, (state, action) => + .handleAction(Actions.PUBLIC_AREA_LIST.success, (state, action) => produce(state, draft => { const {data} = action.payload; - draft.areaList = data; + draft.publicAreaList = data; }) ) // .handleAction(Actions.FLIGHT_PLAN_AREA.request, (state, action) => @@ -71,5 +71,21 @@ export const flightReducer = createReducer(in produce(state, draft => { draft.arcrftSelect = undefined; draft.pilotSelect = undefined; + draft.areaList = undefined; + draft.areaCoordList = undefined; }) ) + // 비행 구역 좌표 저장 + .handleAction(Actions.AREA_COORDINATE_LIST_SAVE, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.areaCoordList = data; + }) + ) + // 비행 구역 상세 저장 + .handleAction(Actions.AREA_DETAIL_LIST_SAVE, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.areaList = data; + }) + ) diff --git a/src/modules/basis/flight/sagas/basisFlightSaga.ts b/src/modules/basis/flight/sagas/basisFlightSaga.ts index 77c4d1f..6a55d41 100644 --- a/src/modules/basis/flight/sagas/basisFlightSaga.ts +++ b/src/modules/basis/flight/sagas/basisFlightSaga.ts @@ -17,7 +17,7 @@ import { FLIGHT_PLAN_PILOT_LIST, FLIGHT_PLAN_UPDATE } from "../actions/basisFlightAction"; -function* listAreaSaga(action: ActionType) { +function* listAreaSaga(action: ActionType) { try { const response = yield call(Apis.flightPlanAPI.area); @@ -34,13 +34,13 @@ function* listAreaSaga(action: ActionType) { } yield put( - Actions.AREA_LIST.success({ + Actions.PUBLIC_AREA_LIST.success({ data: response }) ); } catch (error: any) { yield put( - Actions.AREA_LIST.failure(error) + Actions.PUBLIC_AREA_LIST.failure(error) ); } } @@ -288,7 +288,7 @@ function* listArcrftSaga(action: ActionType