Browse Source

feat/운항과 관제과 재검토 화면 기능 추가

master
sanguu516 1 month ago
parent
commit
6b598e7321
  1. 14
      src/components/flight/ControlApprovalsTable.js
  2. 32
      src/components/flight/OperationApprovalsTable.js
  3. 178
      src/components/flight/OperationCheckBoxModal.js
  4. 1
      src/containers/flight/ControlApprovalsContainer.js
  5. 4
      src/containers/flight/OperationApprovalsContainer.js

14
src/components/flight/ControlApprovalsTable.js

@ -553,7 +553,7 @@ export default function ControlApprovalsTable(props) {
dispatch(
openModal({
header: '재검토 사유',
body: record,
body: record.reviewedReason,
type: 'review'
})
);
@ -1208,11 +1208,13 @@ export default function ControlApprovalsTable(props) {
dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'R' })
).then(() => {
dispatch(
getLaancAprvList({
searchStDt: props.startDate,
searchEndDt: props.endDate
})
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
});
setCheckList([]);

32
src/components/flight/OperationApprovalsTable.js

@ -1218,32 +1218,6 @@ export default function OperationApprovalsTable(props) {
setCheckData(res);
setIsCheckBoxModal(true);
// try {
// const planAreaSnoList = [
// ...new Set(
// checkList
// .filter(item => item.startsWith('child_')) // 'child_'로 시작하는 항목 필터링
// .map(item => item.split('_').pop()) // 마지막 언더바 이후의 숫자 추출
// )
// ];
// dispatch(
// updateLaancAprvReview({ planAreaSnoList, reviewedType: 'R' })
// ).then(() => {
// dispatch(
// getLaancAprvList({
// searchStDt: props.startDate,
// searchEndDt: props.endDate
// })
// );
// });
// setCheckList([]);
// } catch (error) {
// return handlerErrorModal(
// '재검토 요청 실패',
// '재검토 요청을 실패하였습니다. 다시 시도해주세요.',
// false
// );
// }
};
return (
@ -1266,6 +1240,12 @@ export default function OperationApprovalsTable(props) {
setCheckData={setCheckData}
isCheckBoxModal={isCheckBoxModal}
setIsCheckBoxModal={setIsCheckBoxModal}
handlerErrorModal={handlerErrorModal}
handlerSearch={props.handlerSearch}
filterArea={props.filterArea}
filterId={props.filterId}
startDate={props.startDate}
endDate={props.endDate}
/>
)}
<div className='search-download'>

178
src/components/flight/OperationCheckBoxModal.js

@ -6,25 +6,41 @@ import {
ModalFooter
} from '@component/ui';
import React, { useEffect, useState, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table, Form, Input } from 'antd';
import ScrollContainer from 'react-indiana-drag-scroll';
import {
updateLaancAprv,
updateLaancAprvReview
} from '@src/redux/features/laanc/laancThunk';
export default function OperationCheckBoxModal(props) {
console.log('>>', props.checkData);
const scrollContainerRef = useRef(null);
const [dataSource, setDataSource] = useState(props.checkData);
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<tr {...props} />
</Form>
const [dataSource, setDataSource] = useState(
props.checkData.map((item, index) => ({
...item,
key: `parent_${item.planSno}_${index}`,
reviewedReason: item.reviewedReason || ''
}))
);
const [tempDataSource, setTempDataSource] = useState(
dataSource.map(item => {
return {
planAreaSno: item.planAreaSno,
reviewedReason: item.reviewedReason || '',
reqRadius: item.reqRadius || '',
fltElev: item.fltElev || '',
dtl: item.dtl || '',
era: item.era || '',
rm: item.rm || ''
};
})
); // 임시 데이터 소스 추가
const dispatch = useDispatch();
const [form] = Form.useForm();
const EditableCell = ({
title,
editable,
children,
dataIndex,
@ -32,50 +48,34 @@ export default function OperationCheckBoxModal(props) {
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const [form] = Form.useForm();
useEffect(() => {
if (editing) {
inputRef.current?.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({ [dataIndex]: record[dataIndex] });
form.setFieldsValue({
[dataIndex]: record[dataIndex]
});
};
const save = async () => {
try {
const values = await form.validateFields();
setEditing(false);
handleSave({ ...record, ...values });
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
} catch (errInfo) {}
};
let childNode = children;
if (editable) {
childNode = editing ? (
childNode = (
<Form.Item
style={{ margin: 0 }}
name={dataIndex}
rules={[{ required: true, message: `${title} is required.` }]}
className='editable-input'
name={`${record.planAreaSno}`} // 고유한 이름 설정
initialValue={record[dataIndex]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
<Input
onPressEnter={save}
onBlur={save}
placeholder='재검토 사유를 작성해주세요'
/>
</Form.Item>
) : (
<div
className='editable-cell-value-wrap'
style={{ paddingRight: 24 }}
onClick={toggleEdit}
>
{children}
</div>
);
}
@ -83,13 +83,62 @@ export default function OperationCheckBoxModal(props) {
};
const handleSave = row => {
const newData = [...dataSource];
const index = newData.findIndex(item => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
setDataSource(newData);
const newData = [...tempDataSource];
newData.map(item => {
if (row.hasOwnProperty(item.planAreaSno)) {
item.reviewedReason = row[item.planAreaSno];
}
});
setTempDataSource(newData);
};
const components = {
body: {
cell: EditableCell
}
};
const handleConfirm = async () => {
if (tempDataSource.filter(item => !item.reviewedReason).length > 0) {
return props.handlerErrorModal(
'필수값 입력 오류',
'재검토 항목을 입력 해 주세요.',
false
);
}
const planAreaSnoList = tempDataSource.map(item => item.planAreaSno);
dispatch(updateLaancAprv(tempDataSource))
.then(updateRes => {
if (updateRes.meta.requestStatus === 'fulfilled') {
return dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'A' })
);
} else {
throw new Error('요청 처리에 실패했습니다.');
}
})
.then(() => {
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
props.handlerErrorModal('성공', '재검토 요청이 완료되었습니다.', false);
props.setIsCheckBoxModal(false);
})
.catch(err => {
props.handlerErrorModal(
'실패',
'재검토 요청을 실패하였습니다. 다시 시도해주세요.',
true
);
});
};
const defaultColumns = [
{
title: (
@ -101,7 +150,7 @@ export default function OperationCheckBoxModal(props) {
),
dataIndex: 'applyNo',
align: 'center',
width: '20px'
width: '40px'
},
{
title: (
@ -231,7 +280,7 @@ export default function OperationCheckBoxModal(props) {
),
dataIndex: 'approvalCd',
align: 'center',
width: '10px',
width: '50px',
render: approvalCd => {
return (
<>
@ -256,7 +305,7 @@ export default function OperationCheckBoxModal(props) {
),
dataIndex: 'reviewedType',
align: 'center',
width: '30px',
width: '20px',
render: reviewedType => {
return (
<>
@ -283,7 +332,7 @@ export default function OperationCheckBoxModal(props) {
align: 'center',
editable: true,
render: reviewedReason => {
return reviewedReason ?? '재검토 사유를 작성해주세요';
return reviewedReason ?? '-';
}
}
];
@ -304,13 +353,6 @@ export default function OperationCheckBoxModal(props) {
};
});
const components = {
body: {
row: EditableRow,
cell: EditableCell
}
};
return (
<Modal
isOpen={props.isCheckBoxModal}
@ -331,15 +373,18 @@ export default function OperationCheckBoxModal(props) {
vertical={true}
horizontal={true}
activationDistance={10}
ignoreElements='.editable-input' // 이 클래스의 요소는 드래그 이벤트에서 제외
ignoreElements='.editable-input'
>
<div style={{ width: '2000px' }}>
<Form form={form}>
<Table
dataSource={dataSource.map((item, index) => ({
...item,
key: `parent_${item.planSno}`
}))}
dataSource={dataSource}
components={components}
columns={columns}
scroll={{ x: 1700 }}
pagination={false}
rowHoverable={false}
expandIconColumnIndex={-1}
rowClassName={record => {
let className = '';
if (record.approvalCd === 'S') {
@ -352,21 +397,14 @@ export default function OperationCheckBoxModal(props) {
return className;
}}
columns={columns}
scroll={{ x: 1700 }}
pagination={false}
rowHoverable={false}
expandIconColumnIndex={-1}
/>
</Form>
</div>
</ScrollContainer>
</div>
</ModalBody>
<ModalFooter>
<Button
color='primary'
// onClick={() => props.setIsModal(!props.setIsModal)}
>
<Button color='primary' onClick={handleConfirm}>
확인
</Button>
</ModalFooter>

1
src/containers/flight/ControlApprovalsContainer.js

@ -736,6 +736,7 @@ export default function ControlApprovalsContainer({ mode }) {
startDate={startDate}
endDate={endDate}
selected={selected}
handlerSearch={handlerSearch}
handlerDetail={handlerDetail}
/>
</div>

4
src/containers/flight/OperationApprovalsContainer.js

@ -123,9 +123,7 @@ export default function OperationApprovalsContainer({ mode }) {
const features = map
.queryRenderedFeatures(e.point)
.find(feature => feature.source === 'operationLayer');
console.log(features);
if (features) {
console.log(popupRef.current);
if (popupRef.current) {
popupRef.current.postMessage({
type: 'matchingRow',
@ -167,7 +165,6 @@ export default function OperationApprovalsContainer({ mode }) {
if (e.data.type) {
const { type } = e.data;
const { payload } = e.data;
// console.log(payload);
switch (type) {
case 'search':
const { search, searchDate, filterArea } = payload;
@ -889,6 +886,7 @@ export default function OperationApprovalsContainer({ mode }) {
endDate={endDate}
selected={selected}
selectedPlanSno={selectedPlanSno}
handlerSearch={handlerSearch}
handlerDetail={handlerDetail}
/>
</div>

Loading…
Cancel
Save