박상현
10 months ago
33 changed files with 912 additions and 914 deletions
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 33 KiB |
@ -0,0 +1,73 @@ |
|||||||
|
import { useSelector } from 'react-redux'; |
||||||
|
import geoJson from '../../map/geojson/airArea.json'; |
||||||
|
import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json'; |
||||||
|
|
||||||
|
// 공역 생성
|
||||||
|
export const handlerCreateAirSpace = ( |
||||||
|
map, |
||||||
|
mapControl, |
||||||
|
useGeoJson = { |
||||||
|
...geoJson, |
||||||
|
...flatGimpo, |
||||||
|
features: [...geoJson.features, ...flatGimpo.features] |
||||||
|
} |
||||||
|
) => { |
||||||
|
if (map.getLayer('maine')) { |
||||||
|
map.removeLayer('maine'); |
||||||
|
map.removeSource('maine'); |
||||||
|
} |
||||||
|
let arrGeoJson = []; |
||||||
|
useGeoJson.features.map(item => { |
||||||
|
if (item.properties.type === '0001' && mapControl.area0001) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#FF3648' } |
||||||
|
}); |
||||||
|
} else if (item.properties.type === '0002' && mapControl.area0002) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#FFA1AA' } |
||||||
|
}); |
||||||
|
} else if (item.properties.type === '0003' && mapControl.area0003) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#FFA800' } |
||||||
|
}); |
||||||
|
} else if (item.properties.type === '0004' && mapControl.area0004) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#A16B00' } |
||||||
|
}); |
||||||
|
} else if (item.properties.type === '0005' && mapControl.area0005) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#AB40FF' } |
||||||
|
}); |
||||||
|
} else if (item.properties.type === '0006' && mapControl.area0006) { |
||||||
|
arrGeoJson.push({ |
||||||
|
...item, |
||||||
|
properties: { ...item.properties, color: '#009cad' } |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
useGeoJson.features = arrGeoJson.filter(i => i.geometry.type === 'Polygon'); |
||||||
|
|
||||||
|
// 공역 생성 start
|
||||||
|
map.addSource('maine', { |
||||||
|
type: 'geojson', |
||||||
|
data: { |
||||||
|
...useGeoJson |
||||||
|
} |
||||||
|
}); |
||||||
|
map.addLayer({ |
||||||
|
id: 'maine', |
||||||
|
type: 'fill', |
||||||
|
source: 'maine', |
||||||
|
layout: {}, |
||||||
|
paint: { |
||||||
|
'fill-color': ['get', 'color'], |
||||||
|
// 'fill-extrusion-height': 3000,
|
||||||
|
'fill-opacity': 0.5 |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
@ -1,56 +1,56 @@ |
|||||||
import { useState, useEffect } from 'react'; |
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Card } from 'reactstrap' |
|
||||||
|
|
||||||
const ControlAlarmDetail = ({ historyModal, setHistoryModal, controlGpWarnLog }) => { |
const ControlAlarmDetail = ({ |
||||||
return ( |
historyModal, |
||||||
<Modal |
setHistoryModal, |
||||||
isOpen={historyModal} |
controlGpWarnLog |
||||||
toggle={() => setHistoryModal(!historyModal)} |
}) => { |
||||||
className='modal-dialog-centered historyModal' |
return ( |
||||||
> |
<Modal |
||||||
<ModalHeader toggle={() => setHistoryModal(!historyModal)}> |
isOpen={historyModal} |
||||||
<div className='drone-ti'> |
toggle={() => setHistoryModal(!historyModal)} |
||||||
<span className="drone-name">{controlGpWarnLog?.idntfNum}</span> |
className='modal-dialog-centered historyModal' |
||||||
<span>알림내역</span> |
> |
||||||
</div> |
<ModalHeader toggle={() => setHistoryModal(!historyModal)}> |
||||||
</ModalHeader> |
<div className='drone-ti'> |
||||||
|
<span className='drone-name'>{controlGpWarnLog?.idntfNum}</span> |
||||||
|
<span>알림내역</span> |
||||||
|
</div> |
||||||
|
</ModalHeader> |
||||||
|
|
||||||
<ModalBody> |
<ModalBody> |
||||||
<table className='table pal-table'> |
<table className='table pal-table'> |
||||||
<tr> |
<tr> |
||||||
<th>번호</th> |
<th>번호</th> |
||||||
<th>식별번호</th> |
<th>식별번호</th> |
||||||
<th>날짜</th> |
<th>날짜</th> |
||||||
<th>내용</th> |
<th>내용</th> |
||||||
</tr> |
</tr> |
||||||
{controlGpWarnLog ? |
{controlGpWarnLog ? ( |
||||||
controlGpWarnLog.map((p, i) => { |
controlGpWarnLog.map((p, i) => { |
||||||
return ( |
return ( |
||||||
<tr key={i}> |
<tr key={i}> |
||||||
<th>{i + 1}</th> |
<th>{i + 1}</th> |
||||||
<th>{p.idntfNum}</th> |
<th>{p.idntfNum}</th> |
||||||
<th>{p.createDt}</th> |
<th>{p.createDt}</th> |
||||||
<th>{p.warnType}</th> |
<th>{p.warnType}</th> |
||||||
</tr> |
</tr> |
||||||
) |
); |
||||||
}) |
}) |
||||||
: |
) : ( |
||||||
<tr> |
<tr> |
||||||
<th colSpan={3}>데이터가 없습니다.</th> |
<th colSpan={3}>데이터가 없습니다.</th> |
||||||
</tr> |
</tr> |
||||||
} |
)} |
||||||
</table> |
</table> |
||||||
</ModalBody> |
</ModalBody> |
||||||
<ModalFooter> |
<ModalFooter> |
||||||
<Button |
<Button color='info' onClick={() => setHistoryModal(!historyModal)}> |
||||||
color='info' |
확인 |
||||||
onClick={() => setHistoryModal(!historyModal)} |
</Button> |
||||||
> |
</ModalFooter> |
||||||
확인 |
</Modal> |
||||||
</Button> |
); |
||||||
</ModalFooter> |
}; |
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
export default ControlAlarmDetail; |
export default ControlAlarmDetail; |
@ -1,175 +1,151 @@ |
|||||||
import { useEffect, useState } from 'react'; |
import { useEffect, useState } from 'react'; |
||||||
import { X } from 'react-feather'; |
import { X } from 'react-feather'; |
||||||
import { useDispatch, useSelector } from 'react-redux'; |
import { useDispatch, useSelector } from 'react-redux'; |
||||||
import { controlGpArcrftWarnAction, controlGpLogAction } from '../../../modules/control/gp/actions/controlGpAction'; |
import { controlGpLogAction } from '../../../modules/control/gp/actions/controlGpAction'; |
||||||
import ControlAlarmDetail from './ControlAlarmDetail'; |
import ControlAlarmDetail from './ControlAlarmDetail'; |
||||||
import { Badge } from 'reactstrap'; |
import { Badge } from 'reactstrap'; |
||||||
|
|
||||||
const ControlAlarmList = props => { |
const ControlAlarmList = props => { |
||||||
const dispatch = useDispatch(); |
const dispatch = useDispatch(); |
||||||
|
// 비정상상황 상세 히스토리 모달
|
||||||
const [historyModal, setHistoryModal] = useState(false); |
const [historyModal, setHistoryModal] = useState(false); |
||||||
|
|
||||||
const { controlGpList } = useSelector(state => state.controlGpState); |
// 비정상상황 상세 히스토리
|
||||||
const { controlGpArcrftWarnList } = useSelector(state => state.controlGpLogState);
|
const { controlGpWarnLog } = useSelector(state => state.controlGpLogState); |
||||||
const { controlGpWarnLog } = useSelector(state => state.controlGpLogState); |
|
||||||
const { objectId, isClickObject } = useSelector(state => state.controlMapReducer); |
// 비정상상황 기체 목록
|
||||||
|
const { controlGpArcrftWarnList } = useSelector( |
||||||
|
state => state.controlGpLogState |
||||||
const [total, setTotal] = useState({ |
); |
||||||
totalDroneCnt: 0, |
|
||||||
totalWarnCnt: 0, |
// 클릭한 기체 Id, 비행중인 기체 클릭 여부
|
||||||
warnList: [] |
const { objectId, isClickObject } = useSelector( |
||||||
});
|
state => state.controlMapReducer |
||||||
|
); |
||||||
const handleWarnDetail = (cntrlId) => { |
|
||||||
setHistoryModal(prev => !prev); |
// 전체 드론, 비정상 드론 개수
|
||||||
|
const [total, setTotal] = useState({ |
||||||
dispatch(controlGpLogAction.request({id : cntrlId})); |
totalDroneCnt: 0, |
||||||
|
totalWarnCnt: 0, |
||||||
|
warnList: [] |
||||||
|
}); |
||||||
|
|
||||||
|
// 비정상상황 상세 히스토리 모달 표출
|
||||||
|
const handleWarnDetail = cntrlId => { |
||||||
|
setHistoryModal(prev => !prev); |
||||||
|
dispatch(controlGpLogAction.request({ id: cntrlId })); |
||||||
|
}; |
||||||
|
|
||||||
|
// 비행중인 기체 클릭 시 비정상상황 사이드메뉴 닫힘
|
||||||
|
useEffect(() => { |
||||||
|
if (isClickObject) { |
||||||
|
props.setOpenAlarmList(false); |
||||||
} |
} |
||||||
|
}, [objectId, isClickObject]); |
||||||
useEffect(() => { |
|
||||||
if(isClickObject) {
|
// 비정상상황 기체 개수 계산
|
||||||
props.setOpenAlarmList(false); |
useEffect(() => { |
||||||
} |
if (controlGpArcrftWarnList) { |
||||||
|
let totalWarnCnt = 0; |
||||||
}, [objectId, isClickObject]) |
|
||||||
|
if (controlGpArcrftWarnList.length > 0) { |
||||||
useEffect(() => { |
controlGpArcrftWarnList.forEach(warn => { |
||||||
if(controlGpArcrftWarnList) { |
totalWarnCnt += warn.warnCount; |
||||||
let totalWarnCnt = 0; |
}); |
||||||
|
} |
||||||
if(controlGpArcrftWarnList.length > 0) { |
|
||||||
controlGpArcrftWarnList.forEach(warn => { |
setTotal(total => { |
||||||
totalWarnCnt += warn.warnCount; |
return { |
||||||
}); |
totalDroneCnt: controlGpArcrftWarnList.length, |
||||||
}
|
totalWarnCnt: totalWarnCnt, |
||||||
|
warnList: controlGpArcrftWarnList |
||||||
setTotal(total => { |
}; |
||||||
return { |
}); |
||||||
totalDroneCnt : controlGpArcrftWarnList.length, |
} |
||||||
totalWarnCnt : totalWarnCnt, |
}, [controlGpArcrftWarnList]); |
||||||
warnList : controlGpArcrftWarnList |
|
||||||
}
|
return ( |
||||||
}) |
<div className='left-layer'> |
||||||
} |
<div className='layer-content'> |
||||||
|
<div className='layer-ti'> |
||||||
}, [controlGpArcrftWarnList]); |
<h4>실시간 비정상 알림 정보</h4> |
||||||
|
<button |
||||||
return ( |
className='btn-icon' |
||||||
<div className='left-layer'> |
color='primary' |
||||||
<div className='layer-content'> |
onClick={() => props.setOpenAlarmList(false)} |
||||||
<div className='layer-ti'> |
> |
||||||
<h4>실시간 비정상 알림 정보</h4> |
<X size={20} /> |
||||||
<button |
</button> |
||||||
className='btn-icon' |
</div> |
||||||
// outline
|
<div className='layer-content-list'> |
||||||
color='primary' |
<dl className='notice-list'> |
||||||
onClick={() => props.setOpenAlarmList(false)} |
<dt> |
||||||
> |
<div className='list-ti'> |
||||||
<X size={20} /> |
<div className='list-left-txt'>드론 현황</div> |
||||||
</button> |
<div className='list-right-txt'> |
||||||
</div> |
<Badge color='light-primary'> |
||||||
<div className='layer-content-list'> |
{total ? total.totalDroneCnt : 0}대 비행 중 |
||||||
<dl className='notice-list'> |
</Badge> |
||||||
<dt> |
|
||||||
<div className='list-ti'> |
|
||||||
<div className='list-left-txt'>드론 현황</div> |
|
||||||
<div className='list-right-txt'>
|
|
||||||
<Badge color='light-primary'> |
|
||||||
{total? total.totalDroneCnt: 0}대 비행 중 |
|
||||||
</Badge> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
<dt> |
|
||||||
<div className='list-ti'>
|
|
||||||
<div className='list-left-txt'>비정상 알림 전체</div> |
|
||||||
<div className='list-right-txt'> |
|
||||||
<Badge color='light-primary'> |
|
||||||
{total? total.totalWarnCnt : 0}건 |
|
||||||
</Badge> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div className='layer-content'> |
|
||||||
<div className='layer-ti'> |
|
||||||
<h4>알림 목록</h4> |
|
||||||
</div> |
|
||||||
{total?.warnList.map((warn, i) => { |
|
||||||
const warnContent = warn.warnType === 'PLAN' ? '비행 경로 이탈' : '비정상 상황 발생' |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className='layer-content-list' key={i} onClick={() => handleWarnDetail(warn.cntrlId)}> |
|
||||||
<dl className='notice-list'> |
|
||||||
<dt> |
|
||||||
<div className='list-ti'> |
|
||||||
<div className='list-left-txt'>{warn.idntfNum}</div> |
|
||||||
<div className='list-right-txt'>{warn.occurDt ? warn.occurDt : '-'}</div> |
|
||||||
</div> |
|
||||||
<div className='list-ti'> |
|
||||||
<div className='list-left-txt'>{warnContent ? warnContent : '-'}</div> |
|
||||||
<div className='list-right-txt'>{warn.warnCount ? warn.warnCount : '-'}건</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> |
|
||||||
) |
|
||||||
})} |
|
||||||
{/* <div className='layer-content-list'> |
|
||||||
<dl className='notice-list'> |
|
||||||
<dt> |
|
||||||
<div className='list-ti'> |
|
||||||
<div className='list-left-txt'>PAV-001</div> |
|
||||||
<div className='list-right-txt'>2022. 09. 02 10:00:30</div> |
|
||||||
</div> |
|
||||||
<div className='list-ti'> |
|
||||||
<div className='list-left-txt'>비행 경로 이탈</div> |
|
||||||
<div className='list-right-txt'>22건</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> |
</div> |
||||||
<div className='layer-content-list'> |
</div> |
||||||
<dl className='notice-list'> |
</dt> |
||||||
<dt> |
<dt> |
||||||
<div className='list-ti'> |
<div className='list-ti'> |
||||||
<div className='list-left-txt'>PAV-002</div> |
<div className='list-left-txt'>비정상 알림 전체</div> |
||||||
<div className='list-right-txt'>2022. 09. 02 11:23:52</div> |
<div className='list-right-txt'> |
||||||
</div> |
<Badge color='light-primary'> |
||||||
<div className='list-ti'> |
{total ? total.totalWarnCnt : 0}건 |
||||||
<div className='list-left-txt'>비행 경로 이탈</div> |
</Badge> |
||||||
<div className='list-right-txt'>10건</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> |
</div> |
||||||
<div className='layer-content-list'> |
</div> |
||||||
<dl className='notice-list'> |
</dt> |
||||||
<dt> |
</dl> |
||||||
<div className='list-ti'> |
</div> |
||||||
<div className='list-left-txt'>PAV-003</div> |
</div> |
||||||
<div className='list-right-txt'>-</div> |
<div className='layer-content'> |
||||||
</div> |
<div className='layer-ti'> |
||||||
<div className='list-ti'> |
<h4>알림 목록</h4> |
||||||
<div className='list-left-txt'>-</div> |
|
||||||
<div className='list-right-txt'>0건</div> |
|
||||||
</div> |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> */} |
|
||||||
</div> |
|
||||||
|
|
||||||
<ControlAlarmDetail
|
|
||||||
historyModal={historyModal} |
|
||||||
setHistoryModal={setHistoryModal} |
|
||||||
controlGpWarnLog={controlGpWarnLog} |
|
||||||
/> |
|
||||||
</div> |
</div> |
||||||
); |
{total?.warnList.map((warn, i) => { |
||||||
|
const warnContent = |
||||||
|
warn.warnType === 'PLAN' ? '비행 경로 이탈' : '비정상 상황 발생'; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className='layer-content-list' |
||||||
|
key={i} |
||||||
|
onClick={() => handleWarnDetail(warn.cntrlId)} |
||||||
|
> |
||||||
|
<dl className='notice-list'> |
||||||
|
<dt> |
||||||
|
<div className='list-ti'> |
||||||
|
<div className='list-left-txt'>{warn.idntfNum}</div> |
||||||
|
<div className='list-right-txt'> |
||||||
|
{warn.occurDt ? warn.occurDt : '-'} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className='list-ti'> |
||||||
|
<div className='list-left-txt'> |
||||||
|
{warnContent ? warnContent : '-'} |
||||||
|
</div> |
||||||
|
<div className='list-right-txt'> |
||||||
|
{warn.warnCount ? warn.warnCount : '-'}건 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</dt> |
||||||
|
</dl> |
||||||
|
</div> |
||||||
|
); |
||||||
|
})} |
||||||
|
</div> |
||||||
|
|
||||||
|
<ControlAlarmDetail |
||||||
|
historyModal={historyModal} |
||||||
|
setHistoryModal={setHistoryModal} |
||||||
|
controlGpWarnLog={controlGpWarnLog} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
}; |
}; |
||||||
|
|
||||||
export default ControlAlarmList; |
export default ControlAlarmList; |
||||||
|
@ -1,45 +0,0 @@ |
|||||||
import { Bell, ChevronDown, ChevronUp } from "react-feather"; |
|
||||||
import { ReactComponent as DroneMenuIcon } from '../../../assets/images/drone_menu_icon.svg'; |
|
||||||
|
|
||||||
const ControlAlarmNotice = () => { |
|
||||||
{} |
|
||||||
return( |
|
||||||
|
|
||||||
<div> |
|
||||||
{/* <div className='notice'> |
|
||||||
<div className='notice-icon'> |
|
||||||
<Bell size={20} /> |
|
||||||
</div> |
|
||||||
<div className='notice-txt'> |
|
||||||
<dl> |
|
||||||
<dt> |
|
||||||
<span className='time'>2021-06-17 12:00:00</span>AVSF123 장애물 |
|
||||||
지역에 접근하였습니다111. |
|
||||||
</dt> |
|
||||||
<dt> |
|
||||||
<span className='time'>2021-06-30 13:00:00</span>AVSF123 |
|
||||||
비행금지구역에 접근하였습니다. |
|
||||||
</dt> |
|
||||||
<dt> |
|
||||||
<span className='time'>2021-08-20 14:00:00</span>AVSF123 |
|
||||||
국립공원구역에 접근하였습니다. |
|
||||||
</dt> |
|
||||||
</dl> |
|
||||||
</div> |
|
||||||
<div className='notice-btn'> |
|
||||||
<button> |
|
||||||
<ChevronUp size={15} /> |
|
||||||
</button> |
|
||||||
<button> |
|
||||||
<ChevronDown size={15} /> |
|
||||||
</button> |
|
||||||
</div> |
|
||||||
</div> */} |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
|
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
export default ControlAlarmNotice; |
|
Loading…
Reference in new issue