Browse Source

Merge branch 'master' of http://gitea.palntour.com/pav/pav-home

pull/2/head
sanguu 2 years ago
parent
commit
2bd1ca6877
  1. 8
      src/App.js
  2. 395
      src/components/basis/flight/plan/FlightPlanForm.js
  3. 74
      src/components/basis/group/BaisGroupForm.js
  4. 39
      src/components/map/naver/dron/DronToast.js
  5. 143
      src/containers/analysis/history/AnalysisHistoryContainer.js
  6. 62
      src/containers/basis/group/BasisGroupDetailContainer.js
  7. 7
      src/modules/analysis/history/actions/analysisHistoryAction.ts
  8. 6
      src/modules/analysis/history/reducers/analysisHitoryReducer.ts
  9. 16
      src/modules/control/gp/sagas/controlGpSaga.ts
  10. 25
      src/views/control/alarm/ControlAlarmList.js

8
src/App.js

@ -1,6 +1,6 @@
// ** Router Import
import Router from './router/Router'
import Router from './router/Router';
if (process.env.NODE_ENV === 'production') console.log = function () {};
const App = props => <Router />;
const App = props => <Router />
export default App
export default App;

395
src/components/basis/flight/plan/FlightPlanForm.js

@ -12,7 +12,10 @@ import {
import Flatpickr from 'react-flatpickr';
import '@styles/react/libs/flatpickr/flatpickr.scss';
import moment from 'moment';
import { initFlight, initFlightBas } from '../../../../modules/basis/flight/models/basisFlightModel';
import {
initFlight,
initFlightBas
} from '../../../../modules/basis/flight/models/basisFlightModel';
import FlightPlanPilotContainer from '../../../../containers/basis/flight/plan/FlightPlanPilotContainer';
import { FlightPlanModal } from './FlightPlanModal';
import FlightPlanArcrftContainer from '../../../../containers/basis/flight/plan/FlightPlanArcrftContainer';
@ -21,11 +24,17 @@ import { X } from 'react-feather';
import { useSelector } from 'react-redux';
import { shallowEqual } from 'react-redux';
const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDelete, modal, handleDeleteArray }) => {
const FlightPlanForm = ({
data,
handleModal,
handleChange,
handleSave,
handleDelete,
modal,
handleDeleteArray
}) => {
const { areaList, pilotList, arcrftList } = data;
const [date, setDate] = useState();
const [isFlightDone, setIsFlightDone] = useState();
@ -33,7 +42,6 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
const { user } = useSelector(state => state.authState, shallowEqual);
const { detail } = useSelector(state => state.flightState);
useEffect(() => {
if (detail.createDt) {
setDate(detail.schFltStDt);
@ -41,28 +49,28 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
if (detail?.createUserId == user?.cstmrSno || !detail.createUserId) {
// console.log(true)
setTest(false)
setTest(false);
} else {
// console.log(false)
setTest(true)
setTest(true);
}
}, [detail])
}, [detail]);
useEffect(() => {
setDate('');
}, [])
}, []);
useEffect(() => {
if (date) {
let cTime = new Date();
let pTime = new Date(date)
let pTime = new Date(date);
if (cTime > pTime) {
setIsFlightDone(true);
} else {
setIsFlightDone(false);
}
}
}, [date])
}, [date]);
return (
<Row>
@ -74,10 +82,8 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<Card>
<CardBody className='pal-card-body'>
<div className='search-cont search-info pd-0'>
<div
className='cont-ti mb-1 d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'>
<div className='final'>
</div>
<div className='cont-ti mb-1 d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'>
<div className='final'></div>
</div>
<dl>
@ -86,12 +92,12 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<h4 className='ti'>신청인 정보</h4>
</div>
<div className='search-info-box'>
<Row>
<Col className='list-input' lg={4} md={3} sm={12}>
<FormGroup>
<Label for='test'><span
className='necessary'>*</span></Label>
<Label for='test'>
<span className='necessary'>*</span>
</Label>
<Input
readOnly={test}
type='text'
@ -99,26 +105,25 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
name='memberName'
// defaultValue={data.memberName}
value={data.memberName || ''}
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'plan',
name,
value,
})
value
});
}}
bsSize='sm'
placeholder=''
/>
</FormGroup>
</Col>
<Col className='list-input' lg={4} md={5} sm={12}>
<FormGroup className='m_ft'>
<div className='m_ft_box'>
<Label for='test'>
<span className='necessary'>*</span>
<span className='necessary'>*</span>{' '}
핸드폰 번호
</Label>
<Input
type='text'
@ -128,15 +133,16 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
value={data.clncd || '+81'}
bsSize='sm'
placeholder='+82'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'plan',
name,
value,
})
value
});
}}
readOnly />
readOnly
/>
</div>
<div className='m_ft_box'>
<Input
@ -147,13 +153,13 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
// defaultValue={data.hpno}
value={data.hpno || ''}
bsSize='sm'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'plan',
name,
value,
})
value
});
}}
placeholder='010-0000-0000'
/>
@ -162,8 +168,9 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
</Col>
<Col className='list-input' lg={4} md={4} sm={12}>
<FormGroup>
<Label for='test'><span
className='necessary'>*</span></Label>
<Label for='test'>
<span className='necessary'>*</span>
</Label>
<Input
readOnly={test}
type='text'
@ -172,13 +179,13 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
defaultValue={data.email || ''}
// value={data.email}
bsSize='sm'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'plan',
name,
value,
})
value
});
}}
// innerRef={props.data}
placeholder=''
@ -197,7 +204,8 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<Col className='list-input' lg={4} md={4} sm={12}>
<FormGroup>
<Label for='test'>
<span className='necessary'>*</span>
<span className='necessary'>*</span>
비행시작일자
</Label>
{/* {
(isFlightDone) ?
@ -246,13 +254,16 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
data-enable-time
// defaultValue={data.schFltStDt}
value={data.schFltStDt}
onChange={(date) => {
const value = moment(date[0]).format('YYYY-MM-DD HH:mm:ss') || '';
onChange={date => {
const value =
moment(date[0]).format(
'YYYY-MM-DD HH:mm:ss'
) || '';
handleChange({
type: 'plan',
name: 'schFltStDt',
value
})
});
}}
placeholder='비행 시작일자 선택(클릭)'
// {...{options:{minDate: "today"}}}
@ -262,7 +273,8 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<Col className='list-input' lg={4} md={4} sm={12}>
<FormGroup>
<Label for='test'>
<span className='necessary'>*</span>
<span className='necessary'>*</span>
비행종료일자
</Label>
{/* {
(isFlightDone) ?
@ -311,13 +323,16 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
data-enable-time
// defaultValue={data.schFltEndDt}
value={data.schFltEndDt}
onChange={(date) => {
const value = moment(date[0]).format('YYYY-MM-DD HH:mm:ss') || '';
onChange={date => {
const value =
moment(date[0]).format(
'YYYY-MM-DD HH:mm:ss'
) || '';
handleChange({
type: 'plan',
name: 'schFltEndDt',
value
})
});
}}
placeholder='비행 종료일자 선택(클릭)'
// {...{options:{minDate: "today"}}}
@ -327,7 +342,8 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<Col className='list-input' lg={4} md={4} sm={12}>
<FormGroup>
<Label for='test'>
<span className='necessary'>*</span>
<span className='necessary'>*</span>
목적
</Label>
<Input
disabled={test}
@ -336,13 +352,13 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
name='fltPurpose'
value={data.fltPurpose}
bsSize='sm'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'plan',
name,
value,
})
value
});
}}
// innerRef={props.data}
// className={classnames({
@ -351,12 +367,24 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
>
{/* TODO CDNOT 코드연동 필요 */}
<option value=''>= 선택 =</option>
<option value='시험비행'>= 시험비행 =</option>
<option value='교육비행'>= 교육비행 =</option>
<option value='사진/영상촬영'>= 사진/영상촬영 =</option>
<option value='비행훈련'>= 비행훈련 =</option>
<option value='비행교육'>= 비행교육 =</option>
<option value='비행실기시험'>= 비행실기시험 =</option>
<option value='시험비행'>
= 시험비행 =
</option>
<option value='교육비행'>
= 교육비행 =
</option>
<option value='사진/영상촬영'>
= 사진/영상촬영 =
</option>
<option value='비행훈련'>
= 비행훈련 =
</option>
<option value='비행교육'>
= 비행교육 =
</option>
<option value='비행실기시험'>
= 비행실기시험 =
</option>
</Input>
</FormGroup>
</Col>
@ -368,69 +396,89 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
<div className='search-info-ti d-flex justify-content-between'>
<h4 className='ti'>비행 구역 정보</h4>
<Button.Ripple
color="primary"
onClick={(e) => {
handleModal({ target: 'area', isOpen: true })
color='primary'
onClick={e => {
handleModal({ target: 'area', isOpen: true });
}}
>
비행 구역 설정
</Button.Ripple>
</div>
{areaList
? areaList.map((item, i) =>
<AreaForm key={i} index={i} data={item}
handleChange={handleChange} />)
: <AreaForm data={initFlightBas.area}
handleChange={handleChange} />}
{areaList ? (
areaList.map((item, i) => (
<AreaForm
key={i}
index={i}
data={item}
handleChange={handleChange}
/>
))
) : (
<AreaForm
data={initFlightBas.area}
handleChange={handleChange}
/>
)}
</dt>
<dt>
<div className='search-info-ti d-flex justify-content-between'>
<h4 className='ti'>조종사 정보</h4>
<Button.Ripple
disabled={test}
color="primary"
onClick={(e) => {
handleModal({ target: 'pilot', isOpen: true })
color='primary'
onClick={e => {
handleModal({ target: 'pilot', isOpen: true });
}}
>
조종사 조회
</Button.Ripple>
</div>
{pilotList
? pilotList.map((item, i) =>
<PilotForm key={i}
{pilotList ? (
pilotList.map((item, i) => (
<PilotForm
key={i}
index={i}
data={item}
handleChange={handleChange}
handleDeleteArray={handleDeleteArray}
/>)
: <PilotForm data={initFlightBas.pilot}
handleChange={handleChange} />}
/>
))
) : (
<PilotForm
data={initFlightBas.pilot}
handleChange={handleChange}
/>
)}
</dt>
<dt>
<div className='search-info-ti d-flex justify-content-between'>
<h4 className='ti'>기체 정보</h4>
<Button.Ripple
disabled={test}
color="primary"
onClick={(e) => {
color='primary'
onClick={e => {
handleModal({ target: 'arcrft', isOpen: true });
}}
>
기체 조회
</Button.Ripple>
</div>
{arcrftList
? arcrftList.map((item, i) =>
<ArcrftForm key={i}
{arcrftList ? (
arcrftList.map((item, i) => (
<ArcrftForm
key={i}
index={i}
data={item}
handleChange={handleChange}
handleDeleteArray={handleDeleteArray}
/>)
: <ArcrftForm data={initFlightBas.arcrft}
handleChange={handleChange} />}
/>
))
) : (
<ArcrftForm
data={initFlightBas.arcrft}
handleChange={handleChange}
/>
)}
</dt>
<div className='d-flex align-items-center'>
@ -443,6 +491,7 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
>
저장
</Button.Ripple>
{data.planSno ? (
<Button.Ripple
disabled={test}
color='danger'
@ -451,26 +500,21 @@ const FlightPlanForm = ({ data, handleModal, handleChange, handleSave, handleDel
>
삭제
</Button.Ripple>
) : null}
</div>
</dl>
</div>
</CardBody>
</Card>
</Col>
</Row>
</CardBody>
</Card>
</Col>
<SelectModal
modal={modal}
handleModal={handleModal}
test={test}
/>
<SelectModal modal={modal} handleModal={handleModal} test={test} />
</Row>
)
}
);
};
export default FlightPlanForm;
@ -484,21 +528,31 @@ const SelectModal = ({ handleModal, modal, test }) => {
isOpen = modal.pilot;
title = '조종사 조회';
type = 'pilot';
description = <FlightPlanPilotContainer handleModal={handleModal} type={type} />
description = (
<FlightPlanPilotContainer handleModal={handleModal} type={type} />
);
}
if (modal.arcrft) {
isOpen = modal.arcrft;
title = '기체 조회';
type = 'arcrft';
description = <FlightPlanArcrftContainer handleModal={handleModal} type={type} />;
description = (
<FlightPlanArcrftContainer handleModal={handleModal} type={type} />
);
}
if (modal.area) {
isOpen = modal.area;
title = '비행 구역 설정';
type = 'area';
description = <FlightPlanAreaContainer handleModal={handleModal} type={type} test={test} />;
description = (
<FlightPlanAreaContainer
handleModal={handleModal}
type={type}
test={test}
/>
);
}
return (
@ -509,29 +563,33 @@ const SelectModal = ({ handleModal, modal, test }) => {
isOpen={isOpen}
handleModal={handleModal}
/>
)
}
);
};
const AreaForm = ({ data, handleChange, index }) => {
return (<div className='search-info-box'>
return (
<div className='search-info-box'>
<Row>
<Col className='list-input' lg={4} md={12} sm={12}>
<FormGroup>
<Label for='test'>
<span rowSpan={3} className='necessary'>*</span>
<span rowSpan={3} className='necessary'>
*
</span>
좌표
</Label>
{data && data.coordList && data.coordList.length > 0
? data.coordList.map((item, i) => {
return <Input
{data && data.coordList && data.coordList.length > 0 ? (
data.coordList.map((item, i) => {
return (
<Input
key={i}
type='text'
id='lonlat'
name='lonlat'
// defaultValue={(item.lat && item.lon) ? `${item.lat} / ${item.lon}` : '-'}
value={(item.lat && item.lon) ? `${item.lat} / ${item.lon}` : ''}
value={
item.lat && item.lon ? `${item.lat} / ${item.lon}` : ''
}
bsSize='sm'
placeholder='-'
// onChange={(e) => {
@ -547,13 +605,16 @@ const AreaForm = ({ data, handleChange, index }) => {
// style={{marginBottom: 5}}
readOnly
/>
}) : <Input
);
})
) : (
<Input
type='text'
id='lonlat'
name='lonlat'
bsSize='sm'
placeholder='-!!'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'coord',
@ -561,12 +622,11 @@ const AreaForm = ({ data, handleChange, index }) => {
value,
index: 0,
pIndex: index
})
});
}}
readOnly
/>}
/>
)}
</FormGroup>
</Col>
<Col className='list-input' lg={4} md={6} sm={12}>
@ -583,14 +643,14 @@ const AreaForm = ({ data, handleChange, index }) => {
value={data.bufferZone}
bsSize='sm'
placeholder='반경'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'area',
name,
value,
index
})
});
}}
readOnly
/>
@ -604,14 +664,14 @@ const AreaForm = ({ data, handleChange, index }) => {
value={data.fltElev}
bsSize='sm'
placeholder='고도'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'area',
name,
value,
index
})
});
}}
readOnly
/>
@ -631,41 +691,40 @@ const AreaForm = ({ data, handleChange, index }) => {
value={data.fltMethod}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'area',
name,
value,
index
})
});
}}
readOnly
/>
</FormGroup>
</Col>
</Row>
</div>)
}
</div>
);
};
const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
const [test, setTest] = useState();
const { user } = useSelector(state => state.authState, shallowEqual);
const { detail } = useSelector(state => state.flightState);
useEffect(() => {
if (detail?.createUserId == user?.cstmrSno || !detail.createUserId) {
// console.log(true)
setTest(false)
setTest(false);
} else {
// console.log(false)
setTest(true)
setTest(true);
}
}, [detail]);
}, [detail])
return (<div className='search-info-box'>
return (
<div className='search-info-box'>
<Row>
<Col className='list-input' lg={4} md={6} sm={12}>
<FormGroup>
@ -673,7 +732,6 @@ const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
<span className='necessary'>*</span>
</Label>
<Input
type='text'
id='memberName'
name='memberName'
@ -681,14 +739,14 @@ const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.memberName}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'pilot',
name,
value,
index
})
});
}}
readOnly
/>
@ -708,14 +766,14 @@ const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.clncd}
bsSize='sm'
placeholder='+82'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'pilot',
name,
value,
index
})
});
}}
readOnly
/>
@ -729,17 +787,16 @@ const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.hpno}
bsSize='sm'
placeholder='010-0000-0000'
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'pilot',
name,
value,
index
})
});
}}
readOnly
/>
</div>
</FormGroup>
@ -757,45 +814,37 @@ const PilotForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.email}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'pilot',
name,
value,
index
})
});
}}
readOnly
/>
</FormGroup>
</Col>
<Col className='search-info-box-del-btn' lg={1} md={6} sm={12}>
{data.groupNm ?
(
{data.groupNm ? (
<Button.Ripple
disabled={test}
color='danger'
className='btn-icon'
onClick={() =>
handleDeleteArray({ type: 'pilot', index })
}
onClick={() => handleDeleteArray({ type: 'pilot', index })}
>
<X size={14} />
</Button.Ripple>
)
:
(
) : (
<></>
)
}
)}
</Col>
</Row>
</div>)
}
</div>
);
};
const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
const [test, setTest] = useState();
@ -803,18 +852,17 @@ const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
const { detail } = useSelector(state => state.flightState);
useEffect(() => {
if (detail?.createUserId == user?.cstmrSno || !detail.createUserId) {
// console.log(true)
setTest(false)
setTest(false);
} else {
// console.log(false)
setTest(true)
setTest(true);
}
}, [detail]);
}, [detail])
return (<div className='search-info-box'>
return (
<div className='search-info-box'>
<Row>
<Col className='list-input' lg={3} md={6} sm={12}>
<FormGroup>
@ -829,14 +877,14 @@ const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.idntfNum}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'arcrft',
name,
value,
index
})
});
}}
readOnly
/>
@ -855,14 +903,14 @@ const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.arcrftModelNm}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'arcrft',
name,
value,
index
})
});
}}
readOnly
/>
@ -881,14 +929,14 @@ const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.arcrftTypeCd}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'arcrft',
name,
value,
index
})
});
}}
readOnly
/>
@ -907,39 +955,34 @@ const ArcrftForm = ({ data, handleChange, index, handleDeleteArray }) => {
value={data.ownerNm}
bsSize='sm'
placeholder=''
onChange={(e) => {
onChange={e => {
const { name, value } = e.target;
handleChange({
type: 'arcrft',
name,
value,
index
})
});
}}
readOnly
/>
</FormGroup>
</Col>
{data.groupNm ?
(
{data.groupNm ? (
<Col className='search-info-box-del-btn' lg={1} md={6} sm={12}>
<Button.Ripple
disabled={test}
color='danger'
className='btn-icon'
onClick={() =>
handleDeleteArray({ type: 'arcrft', index })
}
onClick={() => handleDeleteArray({ type: 'arcrft', index })}
>
<X size={14} />
</Button.Ripple>
</Col>
)
:
(
) : (
<></>
)
}
)}
</Row>
</div>)
}
</div>
);
};

74
src/components/basis/group/BaisGroupForm.js

@ -1,33 +1,51 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import classnames from 'classnames';
import {
Row,
Col,
Table,
Badge,
UncontrolledDropdown,
DropdownMenu,
DropdownItem,
DropdownToggle,
Card,
CardHeader,
CardBody,
CardTitle,
CardSubtitle,
ButtonGroup,
Button,
Input,
CustomInput,
FormGroup,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Label
Label,
FormFeedback,
Form
} from 'reactstrap';
import { Link, useHistory } from 'react-router-dom';
import { yupResolver } from '@hookform/resolvers/yup';
export const BasisGroupForm = props => {
useEffect(() => {
if (props.groupData?.groupId) {
setValue('groupNm', props.groupData?.groupNm);
}
}, [props.groupData]);
const Schema = yup.object().shape({
groupNm: yup
.string()
.required('그룹명을 입력해 주세요')
.matches(
/^[ㄱ-힣A-Za-z0-9]{2,12}$/,
'2 자 이상, 12 자 이하 영문자/숫자만 입력 가능합니다.'
)
});
const { register, getValues, setValue, errors, handleSubmit } = useForm({
defaultValues: {
groupNm: ''
},
resolver: yupResolver(Schema)
});
const onSumbit = async data => {
props.handlerSave(data);
};
return (
<Form onSubmit={handleSubmit(onSumbit)}>
<Row>
<Col>
<Card>
@ -50,7 +68,7 @@ export const BasisGroupForm = props => {
<Row>
<Col className='list-input' md='4' sm='12'>
<FormGroup>
<Label for='groupcode'>
<Label for='groupId'>
<span className='necessary'>*</span>
</Label>
<Input
@ -66,7 +84,7 @@ export const BasisGroupForm = props => {
</Col>
<Col className='list-input' md='4' sm='12'>
<FormGroup>
<Label for='groupname'>
<Label for='groupNm'>
<span className='necessary'>*</span>
</Label>
<Input
@ -74,10 +92,18 @@ export const BasisGroupForm = props => {
id='groupNm'
name='groupNm'
bsSize='sm'
onChange={props.handlerInput}
value={props.groupData.groupNm || ''}
innerRef={register}
// value={props.groupData.groupNm || ''}
placeholder=''
className={classnames({
'is-invalid': errors.groupNm
})}
/>
{errors && errors.groupNm && (
<FormFeedback>
{errors.groupNm.message}
</FormFeedback>
)}
</FormGroup>
</Col>
@ -105,7 +131,8 @@ export const BasisGroupForm = props => {
className='mr-1'
color='primary'
size='sm'
onClick={props.handlerSave}
// onClick={props.handlerSave}
type='submit'
>
저장
</Button.Ripple>
@ -129,5 +156,6 @@ export const BasisGroupForm = props => {
</Card>
</Col>
</Row>
</Form>
);
};

39
src/components/map/naver/dron/DronToast.js

@ -6,34 +6,41 @@ import Avatar from '../../../../@core/components/avatar';
import { Bell, Check, X, AlertTriangle, Info } from 'react-feather'
import { controlGpDtlAction, controlGpFlightPlanAction } from '../../../../modules/control/gp';
import { objectClickAction, objectUnClickAction } from '../../../../modules/control/map/actions/controlMapActions';
import 'react-toastify/dist/ReactToastify.css';
const DronToast = () => {
const dispatch = useDispatch();
const { controlGpList } = useSelector(state => state.controlGpState);
const { controlGpArcrftWarnList } = useSelector(state => state.controlGpLogState);
const [toastId, setToastId] = useState();
useEffect(() => {
if (controlGpList) {
if (controlGpArcrftWarnList) {
console.log("===================================")
console.log('tastID : ', toastId);
if (!toastId) {
controlGpList.forEach(gps => {
// console.log("===================================")
controlGpArcrftWarnList.forEach(warn => {
// console.log("Warn ==> ", gps.controlWarnCd);
// console.log("Noti ==> ", gps.controlWarnNotyCd);
if (gps.controlWarnCd && gps.controlWarnNotyCd) {
if (warn.controlWarnCd) {
console.log('warn CD : ', warn.controlWarnCd);
const id = toast.info(
toastRender(
`${gps.objectId} 비정상 상황 알림`,
`${warn.idntfNum} 비정상 상황 알림`,
`경로 상에 비행 구역을 이탈했습니다.`
),
{
autoClose: false,
hideProgressBar: true,
position: toast.POSITION.BOTTOM_RIGHT,
onClick: props => {
onClick: () => {
setToastId(null);
handleNotiClick(warn.controlId, warn.idntfNum);
},
onClose: () => {
setToastId(null);
handleNotiClick(gps.controlId, gps.objectId);
}
}
)
@ -43,7 +50,7 @@ const DronToast = () => {
})
}
}
}, [controlGpList]);
}, [controlGpArcrftWarnList]);
const handleNotiClick = (controlId, idntfNum) => {
dispatch(objectClickAction(controlId));
@ -74,22 +81,6 @@ const DronToast = () => {
}
return (
// <Fragment>
// <div className='toastify-header'>
// <div className='title-wrapper'>
// <Avatar size='sm' color='info' icon={<Info size={12} />} />
// <h6 className='text-info ml-50 mb-0'>
// {/* {title} */}
// </h6>
// </div>
// </div>
// <div className='toastify-body'>
// <span>
// {/* {message} */}
// </span>
// </div>
// </Fragment>
null
)

143
src/containers/analysis/history/AnalysisHistoryContainer.js

@ -8,12 +8,19 @@ import { CustomMainLayout } from '../../../components/layout/CustomMainLayout';
import * as Actions from '../../../modules/analysis/history/actions/analysisHistoryAction';
import FlightPlanGroupGrid from '../../../components/basis/flight/plan/FlightPlanGroupGrid';
import { JOIN_LIST } from '../../../modules/basis/group/actions/basisGroupAction';
import { Col, Row, Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import {
Col,
Row,
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter
} from 'reactstrap';
import * as FlightAction from '../../../modules/basis/flight/actions/basisFlightAction';
import { useHistory } from 'react-router-dom';
import { MessageErrorModal } from '../../../components/message/MessageErrorModal';
export const AnalysisHistoryContainer = props => {
const { data, count, searchParams } = useSelector(
state => state.analysisHistoryState
@ -23,12 +30,15 @@ export const AnalysisHistoryContainer = props => {
endDate: moment().subtract(0, 'day').format('YYYY-MM-DD'),
// stDate: moment().set({ 'date': 1, 'h': 0, 'm': 0, 's': 0 }).format('YYYY-MM-DD HH:mm:ss'),
// endDate: moment().set({ 'h': 23, 'm': 59, 's': 59 }).format('YYYY-MM-DD HH:mm:ss'),
groupId: '',
groupId: ''
};
const [searchData, setSearchData] = useState(initSearchData);
const { list: aprvList, aprvProc, selectGroup } = useSelector(state => state.flightState);
const {
list: aprvList,
aprvProc,
selectGroup
} = useSelector(state => state.flightState);
const { joinList, joinListCount } = useSelector(state => state.groupState);
const { user } = useSelector(state => state.authState, shallowEqual);
@ -42,6 +52,42 @@ export const AnalysisHistoryContainer = props => {
color: ''
});
useEffect(() => {
if (aprvProc && aprvProc.result > 0) {
handleSearch(searchData);
}
}, [aprvProc]);
useEffect(() => {
if (user?.cstmrSno) {
dispatch(
JOIN_LIST.request({
cstmrSno: user?.cstmrSno
})
);
}
}, [user]);
useEffect(() => {
setParams({
...params,
stDate: '',
endDate: '',
search1: '',
groupId: searchData.groupId
});
}, [searchData.groupId]);
useEffect(() => {
handlerGroupCancel();
}, []);
const onKeyPress = e => {
if (e.key == 'Enter') {
handlerSearch();
}
};
const handleGroupSelect = ({ groupId }) => {
// 권한 상관 없이 모두 조회 가능
const param = searchData;
@ -54,47 +100,33 @@ export const AnalysisHistoryContainer = props => {
sessionStorage.setItem('groupId', groupId);
sessionStorage.setItem('cstmrSno', user.cstmrSno);
setIsClick(0)
setIsClick(0);
setSearchData(prevState => {
return {
...prevState,
// cstmrSno: user.cstmrSno,
groupId: groupId
}
};
});
//dispatch(Actions.list.request({ searchParams: param }));
}
dispatch(Actions.LIST_INITAL());
};
const handlerGroupCancel = () => {
dispatch(FlightAction.FLIGHT_PLAN_GROUP_SELECT({ cstmrSno: 0, groupId: '', groupNm: '', endDate: '', stDate: '' }));
setIsClick(0)
}
useEffect(() => {
if (aprvProc && aprvProc.result > 0) {
handleSearch(searchData);
}
}, [aprvProc])
useEffect(() => {
if (user?.cstmrSno) {
dispatch(
JOIN_LIST.request({
cstmrSno: user?.cstmrSno
FlightAction.FLIGHT_PLAN_GROUP_SELECT({
cstmrSno: 0,
groupId: '',
groupNm: '',
endDate: '',
stDate: ''
})
);
}
}, [user])
setIsClick(0);
};
const dispatch = useDispatch();
const titleName = '비행이력 현황';
const excelHeaders = [
{ label: '일자', key: 'cntrlStDt' },
{ label: '식별번호', key: 'idntfNum' },
@ -207,31 +239,7 @@ export const AnalysisHistoryContainer = props => {
endDate: moment().subtract(-1, 'day').format('YYYY-MM-DD'),
search1: '',
groupId: searchData.groupId
});
useEffect(() => {
setParams({
...params,
stDate: '',
endDate: '',
search1: '',
groupId: searchData.groupId
});
}, [searchData.groupId]);
useEffect(() => {
if (data) return;
}, [searchParams]);
const onKeyPress = e => {
if (e.key == 'Enter') {
handlerSearch();
}
};
// useEffect(() => { }, [params]);
const handlerSearch = () => {
if (!params.stDate || !params.endDate) {
@ -240,18 +248,15 @@ export const AnalysisHistoryContainer = props => {
title: '필수값 입력 오류',
desc: '올바른 일자를 입력해 주세요.',
color: 'modal-danger'
})
}
else if (!params.groupId) {
});
} else if (!params.groupId) {
setModal({
isOpen: true,
title: '필수값 입력 오류',
desc: '그룹 선택 해주세요.',
color: 'modal-danger'
})
}
else
dispatch(Actions.list.request({ searchParams: params }));
});
} else dispatch(Actions.list.request({ searchParams: params }));
};
const handlerInput = (type, val) => {
@ -263,9 +268,9 @@ export const AnalysisHistoryContainer = props => {
setParams({
...params,
stDate: moment(val[0]).format('YYYY-MM-DD'),
endDate: moment(val[1]).format('YYYY-MM-DD'),
endDate: moment(val[1]).format('YYYY-MM-DD')
});
setIsClick(-1)
setIsClick(-1);
}
}
};
@ -274,7 +279,6 @@ export const AnalysisHistoryContainer = props => {
setIsClick(val);
};
return (
<CustomMainLayout title={titleName}>
<div className='pal-card-box'>
<Row>
@ -302,13 +306,11 @@ export const AnalysisHistoryContainer = props => {
searchData={searchData}
/>
</>
) : (
<div className='no-dataTable'>
나의 그룹 목록에서 상세보기를 클릭하세요.
</div>
)}
</Col>
<Col sm='12'>
{selectGroup.cstmrSno !== 0 ? (
@ -320,15 +322,11 @@ export const AnalysisHistoryContainer = props => {
excelHeaders={excelHeaders}
count={count}
pagination={true}
/>
</>
) : (
<div className='no-dataTable'>
</div>
<div className='no-dataTable'></div>
)}
</Col>
</Row>
</div>
@ -357,6 +355,5 @@ export const AnalysisHistoryContainer = props => {
</div>
<MessageErrorModal />
</CustomMainLayout>
);
};

62
src/containers/basis/group/BasisGroupDetailContainer.js

@ -61,12 +61,32 @@ export const BasisGroupDetailContainer = () => {
dispatch(Actions.GROUP_DETAIL.request(id));
};
const handlerCreate = () => {
dispatch(Actions.GROUP_CREATE.request(groupData));
const handlerCreate = data => {
const saveData = {
createDt: '',
cstmrSno: groupData.cstmrSno,
groupId: groupData.groupId,
groupNm: data.groupNm,
groupTypeCd: groupData.groupTypeCd,
type: groupData.type,
updateDt: ''
};
// dispatch(Actions.GROUP_CREATE.request(groupData));
dispatch(Actions.GROUP_CREATE.request(saveData));
};
const handlerUpdate = () => {
dispatch(Actions.GROUP_UPDATE.request(groupData));
const handlerUpdate = data => {
const saveData = {
createDt: groupData.createDt,
cstmrSno: groupData.cstmrSno,
groupId: groupData.groupId,
groupNm: data.groupNm,
groupTypeCd: groupData.groupTypeCd,
type: groupData.type,
updateDt: groupData.updateDt
};
// dispatch(Actions.GROUP_UPDATE.request(groupData));
dispatch(Actions.GROUP_UPDATE.request(saveData));
};
const handlerDelete = () => {
dispatch(Actions.GROUP_DELETE.request(groupData.groupId));
@ -81,29 +101,33 @@ export const BasisGroupDetailContainer = () => {
return;
};
const handlerInput = e => {
const { name, value } = e.target;
if (name == 'groupNm') {
const regex = /^[ㄱ-힣A-Za-z0-9]{0,11}$/;
if (regex.test(value)) {
setGroupData({
...groupData,
[name]: value
});
}
}
const handlerSave = data => {
groupData.type === 'create' ? handlerCreate(data) : handlerUpdate(data);
};
// const handlerInput = e => {
// const { name, innerRef } = e.target;
// if (name == 'groupNm') {
// // const regex = /^[ㄱ-힣A-Za-z0-9]{0,11}$/;
// // if (regex.test(innerRef)) {
// console.log(innerRef);
// setGroupData({
// ...groupData,
// [name]: innerRef
// });
// // }
// }
// };
return (
<CustomDetailLayout title={titleName}>
<BasisGroupForm
groupDetail={groupDetail}
groupData={groupData}
handlerSave={
groupData.type === 'create' ? handlerCreate : handlerUpdate
}
setGroupData={setGroupData}
handlerSave={handlerSave}
handlerDelete={handlerDelete}
handlerInput={handlerInput}
// handlerInput={handlerInput}
handlerWidthrow={handlerWidthrow}
/>

7
src/modules/analysis/history/actions/analysisHistoryAction.ts

@ -20,6 +20,8 @@ const DETAIL_FAILURE = 'anls/hstry/DETAIL_FAILURE';
const DISPATCH_SEARCH = 'amls/hstry/DISPATCH_SEARCH';
const LIST_INIT = 'anls/hstry/LIST_INIT';
export const dispatchSearch =
createAction(DISPATCH_SEARCH)<{ searchParams: string }>();
@ -41,11 +43,14 @@ export const detail = createAsyncAction(
DETAIL_FAILURE
)<string, { detail: AnalysisHistoryData }, AxiosError>();
export const LIST_INITAL = createAction(LIST_INIT)();
const actions = {
list,
detail,
log,
dispatchSearch
dispatchSearch,
LIST_INITAL
};
export type AnalysisHistoryAction = ActionType<typeof actions>;

6
src/modules/analysis/history/reducers/analysisHitoryReducer.ts

@ -44,4 +44,10 @@ export const analysisHistoryReducer = createReducer<
draft.log = log;
})
)
.handleAction(Actions.LIST_INITAL, (state, action) =>
produce(state, draft => {
draft.data = initResponseAnalysisHistoryData.data;
draft.count = initResponseAnalysisHistoryData.count;
})
);

16
src/modules/control/gp/sagas/controlGpSaga.ts

@ -44,13 +44,27 @@ function* getControlGpSaga(
// console.log('websocket data :: ', data);
yield put(
Actions.controlGpAction.success({
//*
controlGpList: data
})
);
if (data.length > 0) {
const controlIds: any = [];
data.forEach((gps) => {
controlIds.push(gps.controlId);
});
const param = controlIds.join(',');
const rs = yield call(controlGpApi.getArcrftWarnList, param);
yield put(Actions.controlGpArcrftWarnAction.success(rs));
}
if (objectId && isClickObject) {
let detailData;

25
src/views/control/alarm/ControlAlarmList.js

@ -56,31 +56,6 @@ const ControlAlarmList = props => {
}, [controlGpArcrftWarnList]);
useEffect(() => {
if(controlGpList) {
const controlIds = [];
if(controlGpList.length > 0) {
controlGpList.forEach(gps => {
controlIds.push(gps.controlId);
});
const param = controlIds.join(',');
dispatch(controlGpArcrftWarnAction.request(param));
} else {
setTotal(total => {
return {
totalDroneCnt: 0,
totalWarnCnt: 0,
warnList: []
}
})
}
}
}, [controlGpList]);
return (
<div className='left-layer'>
<div className='layer-content'>

Loading…
Cancel
Save