sanguu516
3 months ago
9 changed files with 1872 additions and 70 deletions
@ -0,0 +1,105 @@ |
|||||||
|
import { useState } from 'react'; |
||||||
|
import Flatpickr from 'react-flatpickr'; |
||||||
|
import { Button, Input, CustomInput, Col, Row } from '@component/ui'; |
||||||
|
import { Search, Calendar } from 'react-feather'; |
||||||
|
import dayjs from 'dayjs'; |
||||||
|
|
||||||
|
export default function NewFlightApprovalsReport(props) { |
||||||
|
// 식별번호
|
||||||
|
const [filterId, setFilterId] = useState(''); |
||||||
|
|
||||||
|
// 지역
|
||||||
|
const [filterArea, setFilterArea] = useState(''); |
||||||
|
// 달력
|
||||||
|
const [searchDate, setSearchDate] = useState({ |
||||||
|
startDate: dayjs().format('YYYY-MM-DD'), |
||||||
|
endDate: dayjs().format('YYYY-MM-DD') |
||||||
|
}); |
||||||
|
|
||||||
|
const handleKeyDown = e => { |
||||||
|
if (e.key === 'Enter') { |
||||||
|
props.handlerSearch(filterId, searchDate, filterArea); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className='layer-content'> |
||||||
|
<div className='layer-ti'> |
||||||
|
<h4>비행승인 신청 검토결과 현황</h4> |
||||||
|
</div> |
||||||
|
<div className='layer-ti-sub'> |
||||||
|
검색일자 또는 신청번호/검토결과를 입력해주세요. |
||||||
|
</div> |
||||||
|
<div className='layer-search layer-search-form'> |
||||||
|
<div className='calendar-flat'> |
||||||
|
<Flatpickr |
||||||
|
placeholder='날짜를 선택해주세요' |
||||||
|
id='searchDate' |
||||||
|
options={{ |
||||||
|
mode: 'range', |
||||||
|
defaultDate: [searchDate.startDate, searchDate.endDate] |
||||||
|
}} |
||||||
|
onChange={date => { |
||||||
|
setSearchDate({ |
||||||
|
startDate: dayjs(date[0]).format('YYYY-MM-DD'), |
||||||
|
endDate: dayjs(date[1]).format('YYYY-MM-DD') |
||||||
|
}); |
||||||
|
}} |
||||||
|
className='form-control flat-picker bg-transparent border-0 shadow-none' |
||||||
|
/> |
||||||
|
<Calendar size={14} /> |
||||||
|
</div> |
||||||
|
<div className='list-input'> |
||||||
|
<Input |
||||||
|
type='text' |
||||||
|
bsSize='sm' |
||||||
|
placeholder='신청번호 또는 검토결과를 입력해주세요.' |
||||||
|
value={filterId} |
||||||
|
onChange={e => setFilterId(`${e.target.value}`)} |
||||||
|
onKeyPress={handleKeyDown} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div className='search-box'> |
||||||
|
<div |
||||||
|
className='search-list-ti' |
||||||
|
style={{ |
||||||
|
color: '#555', |
||||||
|
border: '1px solid #ddd', |
||||||
|
minWidth: '50px', |
||||||
|
width: '60px' |
||||||
|
}} |
||||||
|
> |
||||||
|
지역 |
||||||
|
</div> |
||||||
|
<div className='search-list'> |
||||||
|
<div className='search-list-cont'> |
||||||
|
<CustomInput |
||||||
|
inline |
||||||
|
type='select' |
||||||
|
id='' |
||||||
|
bsSize='sm' |
||||||
|
value={filterArea} |
||||||
|
onChange={e => setFilterArea(e.target.value)} |
||||||
|
> |
||||||
|
<option value='' selected> |
||||||
|
전체 |
||||||
|
</option> |
||||||
|
<option value='gimpo'>김포공항 관제권</option> |
||||||
|
</CustomInput> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<Button |
||||||
|
color='primary' |
||||||
|
onClick={() => |
||||||
|
props.handlerSearch(filterId, searchDate, filterArea) |
||||||
|
} |
||||||
|
size='sm' |
||||||
|
> |
||||||
|
검색 |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,444 @@ |
|||||||
|
import { useEffect, useState } from 'react'; |
||||||
|
import { useDispatch, useSelector } from '@src/redux/store'; |
||||||
|
import { Button, Card } from '@component/ui'; |
||||||
|
import dayjs from 'dayjs'; |
||||||
|
import { openModal } from '@src/redux/features/comn/message/messageSlice'; |
||||||
|
import { Table } from 'antd'; |
||||||
|
import { FaAngleDown, FaAngleUp } from 'react-icons/fa'; |
||||||
|
|
||||||
|
export default function NewFlightApprovalsTable(props) { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
|
||||||
|
// 비행승인 목록
|
||||||
|
const { laancAprvList, laancElev } = useSelector(state => state.laancState); |
||||||
|
|
||||||
|
// 승인, 미승인, 비대상 건수
|
||||||
|
const [approvalCdValue, setApprovalCdValue] = useState({ |
||||||
|
S: 0, |
||||||
|
F: 0, |
||||||
|
U: 0 |
||||||
|
}); |
||||||
|
|
||||||
|
// 확장된 행 키
|
||||||
|
const [expandedRowKeys, setExpandedRowKeys] = useState([]); |
||||||
|
|
||||||
|
// 승인, 미승인, 비대상 건수 계산
|
||||||
|
useEffect(() => { |
||||||
|
resApprovalCd(); |
||||||
|
}, [laancAprvList]); |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
신청 |
||||||
|
<br /> |
||||||
|
번호 |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'applyNo', |
||||||
|
align: 'center', |
||||||
|
width: '40px', |
||||||
|
key: 'applyNo', |
||||||
|
editable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
신청 <br /> |
||||||
|
일자 |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'applyDt', |
||||||
|
width: '60px', |
||||||
|
align: 'center', |
||||||
|
key: 'applyDt', |
||||||
|
editable: true, |
||||||
|
render: text => dayjs(text).format('YYYY-MM-DD') |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
신청 <br /> |
||||||
|
구역 수 |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'areaList', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'areaList', |
||||||
|
editable: true, |
||||||
|
render: areaList => <>총{areaList.length}건</> |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: <>신청자</>, |
||||||
|
dataIndex: 'applyDt', |
||||||
|
width: '78px', |
||||||
|
align: 'center', |
||||||
|
key: 'applyDt', |
||||||
|
editable: true, |
||||||
|
render: text => '홍*동' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
비행 <br /> |
||||||
|
구역 |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'applyDt', |
||||||
|
width: '75px', |
||||||
|
align: 'center', |
||||||
|
key: 'applyDt', |
||||||
|
editable: true, |
||||||
|
render: text => '서울시 마포구상암동 1674 (원추)' |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
증심좌표 <br /> |
||||||
|
(위도/경도) |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'areaList', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'latLon', |
||||||
|
editable: true, |
||||||
|
render: areaList => ( |
||||||
|
<> |
||||||
|
{areaList[0].lat.toFixed(5)}, |
||||||
|
<br /> |
||||||
|
{areaList[0].lon.toFixed(5)} |
||||||
|
</> |
||||||
|
) |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
반경 <br /> |
||||||
|
(M) |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'areaList', |
||||||
|
align: 'center', |
||||||
|
width: '70px', |
||||||
|
key: 'bufferZone', |
||||||
|
editable: true, |
||||||
|
render: areaList => <>{areaList[0].bufferZone}</> |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
고도 <br /> |
||||||
|
(M) |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'areaList', |
||||||
|
key: 'fltElev', |
||||||
|
align: 'center', |
||||||
|
width: '70px', |
||||||
|
editable: true, |
||||||
|
render: areaList => <>{areaList[0].fltElev}</> |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: ( |
||||||
|
<> |
||||||
|
검토 <br /> |
||||||
|
결과 |
||||||
|
</> |
||||||
|
), |
||||||
|
dataIndex: 'areaList', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'approvalCd', |
||||||
|
editable: true, |
||||||
|
render: areaList => ( |
||||||
|
<> |
||||||
|
{areaList[0].approvalCd === 'U' |
||||||
|
? '비대상' |
||||||
|
: areaList[0].approvalCd === 'S' |
||||||
|
? '승인' |
||||||
|
: '미승인'} |
||||||
|
</> |
||||||
|
) |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: <>더보기</>, |
||||||
|
dataIndex: 'areaList', |
||||||
|
align: 'center', |
||||||
|
width: '80px', |
||||||
|
key: 'more', |
||||||
|
editable: true, |
||||||
|
render: (areaList, record) => |
||||||
|
areaList.length > 2 ? ( |
||||||
|
<Button color='flat-dark' onClick={() => handleExpand(record.key)}> |
||||||
|
{expandedRowKeys.includes(record.key) ? ( |
||||||
|
<> |
||||||
|
더보기 |
||||||
|
<FaAngleUp /> |
||||||
|
</> |
||||||
|
) : ( |
||||||
|
<> |
||||||
|
더보기 |
||||||
|
<FaAngleDown /> |
||||||
|
</> |
||||||
|
)} |
||||||
|
</Button> |
||||||
|
) : ( |
||||||
|
<>-</> |
||||||
|
) |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
const expandedRowRender = record => { |
||||||
|
const childColumns = [ |
||||||
|
{ |
||||||
|
dataIndex: 'applyNo', |
||||||
|
width: '30px', |
||||||
|
align: 'center', |
||||||
|
key: 'applyNo' |
||||||
|
}, |
||||||
|
{ |
||||||
|
dataIndex: 'applyDt', |
||||||
|
width: '85px', |
||||||
|
align: 'center', |
||||||
|
key: 'applyDt' |
||||||
|
}, |
||||||
|
{ |
||||||
|
dataIndex: 'zoneNo', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'zoneNo', |
||||||
|
editable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'latLon', |
||||||
|
dataIndex: ['lat', 'lon'], |
||||||
|
render: (text, record) => { |
||||||
|
const lat = record.lat; |
||||||
|
const lon = record.lon; |
||||||
|
return ( |
||||||
|
<> |
||||||
|
{lat.toFixed(5)} /<br /> |
||||||
|
{lon.toFixed(5)} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
dataIndex: 'bufferZone', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'bufferZone' |
||||||
|
}, |
||||||
|
{ |
||||||
|
dataIndex: 'fltElev', |
||||||
|
align: 'center', |
||||||
|
width: '85px', |
||||||
|
key: 'fltElev' |
||||||
|
}, |
||||||
|
{ |
||||||
|
dataIndex: 'approvalCd', |
||||||
|
align: 'center', |
||||||
|
key: 'approvalCd', |
||||||
|
render: text => ( |
||||||
|
<>{text === 'U' ? '비대상' : text === 'S' ? '승인' : '미승인'}</> |
||||||
|
) |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
const data = []; |
||||||
|
record.areaList.map((item, index) => { |
||||||
|
if (index < 1) return; |
||||||
|
data.push({ |
||||||
|
key: `${record.applyNo}-${index}`, |
||||||
|
applyNo: item.applyNo, |
||||||
|
applyDt: item.applyDt, |
||||||
|
zoneNo: item.zoneNo, |
||||||
|
lat: item.lat, |
||||||
|
lon: item.lon, |
||||||
|
bufferZone: item.bufferZone, |
||||||
|
fltElev: item.fltElev, |
||||||
|
approvalCd: item.approvalCd |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
return ( |
||||||
|
<Table |
||||||
|
rowClassName={record => { |
||||||
|
let className = ''; |
||||||
|
if (record.approvalCd === 'S') { |
||||||
|
className += 'flight-approval-row'; |
||||||
|
} else if (record.approvalCd === 'F') { |
||||||
|
className += 'flight-not-approval-row'; |
||||||
|
} else className; |
||||||
|
|
||||||
|
return className; |
||||||
|
}} |
||||||
|
size='small' |
||||||
|
bordered |
||||||
|
columns={childColumns} |
||||||
|
dataSource={data} |
||||||
|
pagination={false} |
||||||
|
showHeader={false} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
// 모달 오픈 핸들러
|
||||||
|
const handlerOpenModal = (approval, fltElev, fltElevMax) => { |
||||||
|
if (approval === 'F') { |
||||||
|
dispatch( |
||||||
|
openModal({ |
||||||
|
header: '미승인 사유', |
||||||
|
body: `관제권 내 제한고도(신청고도${fltElev}m/허용고도${fltElevMax}m) 입니다.`, |
||||||
|
type: 'error' |
||||||
|
}) |
||||||
|
); |
||||||
|
} else if (approval === 'S') { |
||||||
|
dispatch( |
||||||
|
openModal({ |
||||||
|
header: '승인 사유', |
||||||
|
body: `관제권 내 허용고도(신청고도${fltElev}m/허용고도${fltElevMax}m) 입니다.`, |
||||||
|
type: 'success' |
||||||
|
}) |
||||||
|
); |
||||||
|
} else { |
||||||
|
dispatch( |
||||||
|
openModal({ |
||||||
|
header: '비대상', |
||||||
|
body: `해당 구역은 비 대상(신청고도${fltElev}m/허용고도${ |
||||||
|
fltElevMax === undefined ? 150 : null |
||||||
|
}m) 지역 입니다.`,
|
||||||
|
type: 'error' |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// 테이블 내부 행 클릭 이벤트
|
||||||
|
const handleInRowClick = row => { |
||||||
|
console.log('>>', row); |
||||||
|
|
||||||
|
handlerOpenModal(row.approvalCd, row.fltElev, row.fltElevMax); |
||||||
|
props.handlerDetail(row); |
||||||
|
}; |
||||||
|
|
||||||
|
// 날짜 포맷 변경
|
||||||
|
const formatDate = dateString => { |
||||||
|
const date = new Date(dateString); |
||||||
|
const year = date.getFullYear(); |
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); |
||||||
|
const day = String(date.getDate()).padStart(2, '0'); |
||||||
|
return `${year} 년 ${month} 월 ${day} 일`; |
||||||
|
}; |
||||||
|
|
||||||
|
// 승인, 미승인, 비대상 건수 계산
|
||||||
|
const resApprovalCd = () => { |
||||||
|
let approvalCdValue = { S: 0, F: 0, U: 0 }; |
||||||
|
|
||||||
|
laancAprvList?.map(item => { |
||||||
|
item.areaList.map(area => { |
||||||
|
if (area.approvalCd === 'S') { |
||||||
|
approvalCdValue.S += 1; |
||||||
|
} else if (area.approvalCd === 'F') { |
||||||
|
approvalCdValue.F += 1; |
||||||
|
} else { |
||||||
|
approvalCdValue.U += 1; |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
setApprovalCdValue({ |
||||||
|
F: approvalCdValue.F, |
||||||
|
S: approvalCdValue.S, |
||||||
|
U: approvalCdValue.U |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
const handleExpand = key => { |
||||||
|
const expanded = expandedRowKeys.includes(key); |
||||||
|
const keys = expanded |
||||||
|
? expandedRowKeys.filter(k => k !== key) |
||||||
|
: [...expandedRowKeys, key]; |
||||||
|
setExpandedRowKeys(keys); |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className='layer-content'> |
||||||
|
<div className='layer-ti d-flex justify-content-between align-items-center'> |
||||||
|
<h4>비행승인 신청 검토결과 목록</h4> |
||||||
|
<span className='search-case'> |
||||||
|
{formatDate(props.startDate)} |
||||||
|
{props.endDate && props.startDate != props.endDate |
||||||
|
? '~' + formatDate(props.endDate) + ' ' |
||||||
|
: null} |
||||||
|
총 {approvalCdValue.S + approvalCdValue.F + approvalCdValue.U} 건 |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<div className='search-case-list'> |
||||||
|
<div> |
||||||
|
<ul> |
||||||
|
<li className='approval' style={{ cursor: 'pointer' }}> |
||||||
|
승인 {approvalCdValue.S}건 |
||||||
|
</li> |
||||||
|
<li className='not-approved' style={{ cursor: 'pointer' }}> |
||||||
|
미승인 {approvalCdValue.F}건 |
||||||
|
</li> |
||||||
|
<li className='non-target' style={{ cursor: 'pointer' }}> |
||||||
|
비대상 {approvalCdValue.U}건 |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className='invoice-list-wrapper'> |
||||||
|
<Card> |
||||||
|
<div |
||||||
|
className='invoice-list-dataTable flight-approval' |
||||||
|
style={{ width: '100%' }} |
||||||
|
> |
||||||
|
{laancAprvList?.length > 0 ? ( |
||||||
|
<Table |
||||||
|
dataSource={laancAprvList.map((item, index) => ({ |
||||||
|
...item, |
||||||
|
key: index |
||||||
|
}))} |
||||||
|
columns={columns} |
||||||
|
size='small' |
||||||
|
rowClassName={record => { |
||||||
|
let className = ''; |
||||||
|
if (record.areaList[0].approvalCd === 'S') { |
||||||
|
className += 'flight-approval-row editable-row'; |
||||||
|
} else if (record.areaList[0].approvalCd === 'F') { |
||||||
|
className += 'flight-not-approval-row editable-row'; |
||||||
|
} else className += 'editable-row'; |
||||||
|
|
||||||
|
return className; |
||||||
|
}} |
||||||
|
expandable={{ |
||||||
|
expandedRowRender, |
||||||
|
expandedRowKeys: expandedRowKeys, |
||||||
|
onExpand: handleExpand, |
||||||
|
rowExpandable: record => record.areaList.length > 1 // areaList가 1개 이상인 경우에만 확장 가능
|
||||||
|
}} |
||||||
|
tableLayout='auto' |
||||||
|
rowHoverable={false} |
||||||
|
expandIconColumnIndex={-1} // 기본 확장 아이콘을 숨김
|
||||||
|
/> |
||||||
|
) : ( |
||||||
|
<div |
||||||
|
className='d-flex justify-content-center align-items-center ' |
||||||
|
style={{ height: '100px', color: '#000' }} |
||||||
|
> |
||||||
|
<p>비행승인 신청 건수가 없습니다.</p> |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,207 @@ |
|||||||
|
import { useEffect, useRef, useState, lazy, Suspense } from 'react'; |
||||||
|
import { useDispatch, useSelector } from '@src/redux/store'; |
||||||
|
import NewFlightApprovalsReport from '../../components/flight/NewFlightApprovalsReport'; |
||||||
|
import { |
||||||
|
InitFeature, |
||||||
|
handlerFitBounds, |
||||||
|
handlerGetCircleCoord, |
||||||
|
flightlayerWayPoint, |
||||||
|
flightlayerPolyline, |
||||||
|
flightlayerPolygon, |
||||||
|
flightlayerBuffer |
||||||
|
} from '../../utility/MapUtils'; |
||||||
|
import { useHistory } from 'react-router-dom'; |
||||||
|
import { clientSaveAreaCoordinateList } from '@src/redux/features/laanc/laancSlice'; |
||||||
|
import { MapControl } from '../../components/map/MapControl'; |
||||||
|
import { clientSetIsMapLoading } from '@src/redux/features/laanc/laancSlice'; |
||||||
|
import { clientMapInit } from '@src/redux/features/control/map/mapSlice'; |
||||||
|
import NewFlightApprovalsTable from '@src/components/flight/NewFlightApprovalsTable'; |
||||||
|
import { getLaancAprvList } from '@src/redux/features/laanc/laancThunk'; |
||||||
|
import dayjs from 'dayjs'; |
||||||
|
import { setLogout } from '@src/redux/features/account/auth/authThunk'; |
||||||
|
|
||||||
|
export default function NewFlightApprovalsContainer() { |
||||||
|
const dispatch = useDispatch(); |
||||||
|
const history = useHistory(); |
||||||
|
|
||||||
|
const [selected, setSelected] = useState(null); |
||||||
|
const [isMapLoading, setIsMapLoading] = useState(false); |
||||||
|
// 비행구역 그리기
|
||||||
|
|
||||||
|
const [filter, setFilter] = useState(''); |
||||||
|
// 지도
|
||||||
|
const [mapObject, setMapObject] = useState(); |
||||||
|
|
||||||
|
const { areaCoordList, isOpenModal } = useSelector(state => state.laancState); |
||||||
|
|
||||||
|
//
|
||||||
|
const [startDate, setStartDate] = useState(dayjs().format('YYYY-MM-DD')); |
||||||
|
const [endDate, setEndDate] = useState(); |
||||||
|
// 미니맵 레이어
|
||||||
|
const [previewLayer, setPreviewLayer] = useState(); |
||||||
|
|
||||||
|
const { laancAprvList } = useSelector(state => state.laancState); |
||||||
|
|
||||||
|
const map = useSelector(state => state.mapState.map); |
||||||
|
|
||||||
|
const previewGeo2 = { |
||||||
|
type: 'FeatureCollection', |
||||||
|
features: [] |
||||||
|
}; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const searchStDt = dayjs().format('YYYY-MM-DD'); |
||||||
|
const searchEndDt = dayjs().format('YYYY-MM-DD'); |
||||||
|
dispatch( |
||||||
|
getLaancAprvList({ |
||||||
|
searchStDt, |
||||||
|
searchEndDt |
||||||
|
}) |
||||||
|
); |
||||||
|
}, []); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (areaCoordList.length != 0) { |
||||||
|
handlerPreviewDraw(); |
||||||
|
} |
||||||
|
}, [areaCoordList]); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (map) { |
||||||
|
setMapObject(map); |
||||||
|
} |
||||||
|
}, [map]); |
||||||
|
|
||||||
|
useEffect(async () => { |
||||||
|
if (areaCoordList.length === 0) return; |
||||||
|
}, [areaCoordList]); |
||||||
|
|
||||||
|
const handlerSearch = (search, searchDate, filterArea) => { |
||||||
|
setStartDate(searchDate.startDate); |
||||||
|
setEndDate(searchDate.endDate); |
||||||
|
|
||||||
|
if ( |
||||||
|
search != '' && |
||||||
|
(search === '승인' || search === '미승인' || search === '비대상') |
||||||
|
) { |
||||||
|
dispatch( |
||||||
|
getLaancAprvList({ |
||||||
|
searchStDt: searchDate.startDate, |
||||||
|
searchEndDt: searchDate.endDate, |
||||||
|
selectZone: filterArea, |
||||||
|
approvalCd: search === '승인' ? 'S' : search === '미승인' ? 'F' : 'U' |
||||||
|
}) |
||||||
|
); |
||||||
|
} else if (search != '') { |
||||||
|
dispatch( |
||||||
|
getLaancAprvList({ |
||||||
|
searchStDt: searchDate.startDate, |
||||||
|
searchEndDt: searchDate.endDate, |
||||||
|
selectZone: filterArea, |
||||||
|
applyNo: search |
||||||
|
}) |
||||||
|
); |
||||||
|
} else { |
||||||
|
dispatch( |
||||||
|
getLaancAprvList({ |
||||||
|
searchStDt: searchDate.startDate, |
||||||
|
searchEndDt: searchDate.endDate, |
||||||
|
selectZone: filterArea |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
// );
|
||||||
|
setFilter(search); |
||||||
|
}; |
||||||
|
|
||||||
|
const handlerDetail = area => { |
||||||
|
setSelected(area.planAreaSno); |
||||||
|
|
||||||
|
dispatch(clientSaveAreaCoordinateList([area])); |
||||||
|
|
||||||
|
handlerMapInit(); |
||||||
|
}; |
||||||
|
|
||||||
|
const handlerMapInit = () => { |
||||||
|
if (map.getSource('preview')) { |
||||||
|
} else { |
||||||
|
map.addSource('preview', { |
||||||
|
type: 'geojson', |
||||||
|
data: previewGeo2 |
||||||
|
}); |
||||||
|
map.addLayer(flightlayerWayPoint('preview')); |
||||||
|
map.addLayer(flightlayerBuffer('preview')); |
||||||
|
map.addLayer(flightlayerPolygon('preview')); |
||||||
|
map.addLayer(flightlayerPolyline('preview')); |
||||||
|
} |
||||||
|
|
||||||
|
dispatch(clientSetIsMapLoading(true)); |
||||||
|
const preview = map.getSource('preview'); |
||||||
|
|
||||||
|
if (preview) setPreviewLayer(preview); |
||||||
|
|
||||||
|
setIsMapLoading(true); |
||||||
|
|
||||||
|
setMapObject(map); |
||||||
|
dispatch(clientMapInit(map)); |
||||||
|
}; |
||||||
|
const handlerPreviewDraw = () => { |
||||||
|
if (areaCoordList.length > 0) { |
||||||
|
const areas = areaCoordList[0]; |
||||||
|
|
||||||
|
previewGeo2.features = []; |
||||||
|
|
||||||
|
let fitZoomPaths = []; |
||||||
|
const radius = areas.bufferZone; |
||||||
|
const circleCoords = handlerGetCircleCoord( |
||||||
|
[areas.lon, areas.lat], |
||||||
|
radius |
||||||
|
); |
||||||
|
|
||||||
|
const circle = InitFeature('Polygon', 'CIRCLE'); |
||||||
|
circle.properties.center = [areas.lon, areas.lat]; |
||||||
|
circle.geometry.coordinates = circleCoords; |
||||||
|
|
||||||
|
previewGeo2.features.push(circle); |
||||||
|
|
||||||
|
mapObject.setCenter(circle.properties.center); |
||||||
|
|
||||||
|
fitZoomPaths = circleCoords[0]; |
||||||
|
|
||||||
|
handlerFitBounds(mapObject, fitZoomPaths, 400, 'CIRCLE', 'flight'); |
||||||
|
|
||||||
|
// mapObject.setPaintProperty('waypoint', 'circle-radius', 10);
|
||||||
|
mapObject.getSource('preview').setData(previewGeo2); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const handlerLogout = async () => { |
||||||
|
const { payload } = await dispatch(setLogout()); |
||||||
|
|
||||||
|
if (payload === 'SUCCESS') { |
||||||
|
history.replace('/account/login'); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<div className='map' style={{ width: '100%' }}> |
||||||
|
<MapControl /> |
||||||
|
</div> |
||||||
|
<div className='right-menu active'> |
||||||
|
<div className='right-layer active flight-approval-layer'> |
||||||
|
<div className='layer-content'> |
||||||
|
<NewFlightApprovalsReport handlerSearch={handlerSearch} /> |
||||||
|
<NewFlightApprovalsTable |
||||||
|
filter={filter} |
||||||
|
startDate={startDate} |
||||||
|
endDate={endDate} |
||||||
|
selected={selected} |
||||||
|
handlerDetail={handlerDetail} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
import '@styles/react/libs/flatpickr/flatpickr.scss'; |
||||||
|
import '@styles/react/libs/tables/react-dataTable-component.scss'; |
||||||
|
import '../../assets/css/custom.css'; |
||||||
|
import NewFlightApprovalsContainer from '../../containers/flight/NewFlightApprovalsContainer'; |
||||||
|
|
||||||
|
export default function NewFlightView() { |
||||||
|
return ( |
||||||
|
<div className='pal-container'> |
||||||
|
{/* <Helmet> |
||||||
|
<title>관제시스템</title> |
||||||
|
</Helmet> */} |
||||||
|
<NewFlightApprovalsContainer />; |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue