update recents and data
This commit is contained in:
parent
8b629de7d9
commit
747a564efe
@ -5,7 +5,7 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Tag } from 'antd';
|
||||
|
||||
const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => {
|
||||
const FileCard = ({ file, isSelected, onClick }) => {
|
||||
const fileName = file['File Name'];
|
||||
const extensionType = fileName.split('.').pop();
|
||||
let status = true;
|
||||
|
78
cope2n-fe/src/pages/reviews2/RecentRequest.tsx
Normal file
78
cope2n-fe/src/pages/reviews2/RecentRequest.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
// open modal show a list from local storage
|
||||
|
||||
import { DeleteOutlined, HistoryOutlined } from '@ant-design/icons';
|
||||
import { Button, Modal, Tag } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { useState } from 'react';
|
||||
import { RecentRequest } from './const';
|
||||
const RecentRequesModal = () => {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [listData, setListData] = useState<RecentRequest[]>([]);
|
||||
|
||||
const handleShowModal = () => {
|
||||
const data = localStorage.getItem('recent-request');
|
||||
if (data) {
|
||||
setListData(JSON.parse(data));
|
||||
}
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setShowModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={handleShowModal} icon={<HistoryOutlined />}>Recents </Button>
|
||||
<Modal
|
||||
style={{ overflow: 'auto' }}
|
||||
footer={
|
||||
<div style={{textAlign: 'left'}}>
|
||||
{listData.length > 0 ? (
|
||||
<Button
|
||||
danger
|
||||
style={{ marginTop: '16px' }}
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={() => {
|
||||
if (
|
||||
window.confirm(
|
||||
'Are you sure you want to remove all recent requests?',
|
||||
)
|
||||
) {
|
||||
localStorage.removeItem('recent-request');
|
||||
setListData([]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{' '}
|
||||
Remove all
|
||||
</Button>
|
||||
) : (
|
||||
<p>No recent requests</p>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
width={600}
|
||||
height={600}
|
||||
open={showModal}
|
||||
title='Recent Requests'
|
||||
onCancel={handleCloseModal}
|
||||
>
|
||||
{listData.map((item, index) => (
|
||||
<div style={{ marginBottom: '4px' }}>
|
||||
<a
|
||||
href={`?request_id=${item.request_id}`}
|
||||
target='_blank'
|
||||
key={index}
|
||||
>
|
||||
<Tag color='blue'>{dayjs(item.time).format('hh:mm - DD/MM')}</Tag>
|
||||
<span>{item.request_id}</span>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RecentRequesModal;
|
@ -1,4 +1,5 @@
|
||||
import { baseURL } from 'request/api';
|
||||
import { RecentRequest } from './const';
|
||||
|
||||
export const fetchAllRequests = async (
|
||||
filterDateRange,
|
||||
@ -7,7 +8,7 @@ export const fetchAllRequests = async (
|
||||
filterIncludeTests,
|
||||
page = 1,
|
||||
page_size = 20,
|
||||
max_accuracy = 100
|
||||
max_accuracy = 100,
|
||||
) => {
|
||||
const startDate =
|
||||
filterDateRange && filterDateRange[0] ? filterDateRange[0] : '';
|
||||
@ -27,7 +28,7 @@ export const fetchAllRequests = async (
|
||||
if (startDate && endDate) {
|
||||
filterStr += `start_date=${startDate}&end_date=${endDate}&`;
|
||||
}
|
||||
filterStr += `max_accuracy=${max_accuracy}`
|
||||
filterStr += `max_accuracy=${max_accuracy}`;
|
||||
const token = localStorage.getItem('sbt-token') || '';
|
||||
const data = await fetch(`${baseURL}/ctel/request_list/?${filterStr}`, {
|
||||
method: 'GET',
|
||||
@ -41,9 +42,7 @@ export const fetchAllRequests = async (
|
||||
return data;
|
||||
};
|
||||
|
||||
export const updateRevisedData = async (
|
||||
requestID: any,
|
||||
) => {
|
||||
export const updateRevisedData = async (requestID: any) => {
|
||||
// const requestID = ;
|
||||
const token = localStorage.getItem('sbt-token') || '';
|
||||
const result = await fetch(`${baseURL}/ctel/request/${requestID}/`, {
|
||||
@ -52,7 +51,7 @@ export const updateRevisedData = async (
|
||||
Authorization: `${JSON.parse(token)}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({"request_file_results": []}),
|
||||
body: JSON.stringify({ request_file_results: [] }),
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
throw error;
|
||||
@ -69,14 +68,17 @@ export const updateRevisedDataByFile = async (
|
||||
) => {
|
||||
// const requestID = ;
|
||||
const token = localStorage.getItem('sbt-token') || '';
|
||||
const result = await fetch(`${baseURL}/ctel/request_image/${requestID}/${fileID}/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `${JSON.parse(token)}`,
|
||||
'Content-Type': 'application/json',
|
||||
const result = await fetch(
|
||||
`${baseURL}/ctel/request_image/${requestID}/${fileID}/`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `${JSON.parse(token)}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(newRevisedData),
|
||||
},
|
||||
body: JSON.stringify(newRevisedData),
|
||||
}).catch((error) => {
|
||||
).catch((error) => {
|
||||
console.log(error);
|
||||
throw error;
|
||||
});
|
||||
@ -85,7 +87,6 @@ export const updateRevisedDataByFile = async (
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const fetchRequest = async (id) => {
|
||||
const token = localStorage.getItem('sbt-token') || '';
|
||||
const response = await fetch(`${baseURL}/ctel/request/${id}/`, {
|
||||
@ -98,3 +99,22 @@ export const fetchRequest = async (id) => {
|
||||
await response.json()
|
||||
).subscription_requests[0];
|
||||
};
|
||||
|
||||
export const addRecentRequest = (requestId: string) => {
|
||||
let data = localStorage.getItem('recent-request');
|
||||
let requests: RecentRequest[] = [];
|
||||
if (data) {
|
||||
requests = JSON.parse(data);
|
||||
} else {
|
||||
requests = [];
|
||||
}
|
||||
|
||||
// find and remove element in array that has request_id equal to requestId
|
||||
requests = requests.filter((request) => request.request_id !== requestId);
|
||||
requests.unshift({
|
||||
request_id: requestId,
|
||||
time: new Date
|
||||
})
|
||||
|
||||
localStorage.setItem('recent-request', JSON.stringify(requests))
|
||||
};
|
||||
|
@ -68,3 +68,8 @@ export const SOURCE_OBJECT_NAMES = [
|
||||
REVIEWED_ACCURACY,
|
||||
REVIEWED_RESULT
|
||||
];
|
||||
|
||||
export type RecentRequest = {
|
||||
request_id: string,
|
||||
time: Date
|
||||
}
|
@ -25,13 +25,15 @@ import {
|
||||
Spin,
|
||||
Tag,
|
||||
} from 'antd';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Lightbox from 'react-awesome-lightbox';
|
||||
import 'react-awesome-lightbox/build/style.css';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { badQualityReasonSubmit } from 'request';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { getErrorMessage } from 'utils/error-handler';
|
||||
import {
|
||||
addRecentRequest,
|
||||
fetchAllRequests,
|
||||
fetchRequest,
|
||||
updateRevisedData,
|
||||
@ -50,12 +52,11 @@ import {
|
||||
SUBSIDIARIES,
|
||||
} from './const';
|
||||
import FileCard from './FileCard';
|
||||
|
||||
import RecentRequest from './RecentRequest';
|
||||
const ReviewPage = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [fullscreen, setFullscreen] = useState(false);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isReasonModalOpen, setIsReasonModalOpen] = useState(false);
|
||||
const [selectedFileId, setSelectedFileId] = useState(0);
|
||||
const [selectedFileData, setSelectedFileData] = useState(null);
|
||||
const [selectedFileDataSource, setSelectedFileDataSource] = useState({});
|
||||
@ -82,6 +83,47 @@ const ReviewPage = () => {
|
||||
const [otherSolution, setOtherSolution] = useState('');
|
||||
const [imageLoading, setImageLoading] = useState(false);
|
||||
const defaultLayoutPluginInstance = defaultLayoutPlugin();
|
||||
let [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
const request_id = searchParams.get('request_id');
|
||||
if (request_id) {
|
||||
setLoading(true);
|
||||
setTotalPages(1);
|
||||
setHasNextRequest(false);
|
||||
const requestData = fetchRequest(request_id);
|
||||
requestData
|
||||
.then(async (data) => {
|
||||
if (data) setCurrentRequest(data);
|
||||
setAndLoadSelectedFile(data, 0);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
} else {
|
||||
setCurrentRequestIndex(1);
|
||||
fetchAllRequests(
|
||||
filterDateRange,
|
||||
filterSubsidiaries,
|
||||
filterReviewState,
|
||||
filterIncludeTests,
|
||||
1,
|
||||
1,
|
||||
filterAccuracy,
|
||||
).then((data) => {
|
||||
setTotalPages(data?.page?.total_requests);
|
||||
setHasNextRequest(1 < data?.page?.total_requests);
|
||||
const firstRequest = fetchRequest(
|
||||
data?.subscription_requests[0].RequestID,
|
||||
);
|
||||
firstRequest.then(async (data) => {
|
||||
if (data) setCurrentRequest(data);
|
||||
setAndLoadSelectedFile(data, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (reason) {
|
||||
setSolution(counter_measure_map[reason]);
|
||||
@ -95,6 +137,14 @@ const ReviewPage = () => {
|
||||
SOURCE_OBJECT_NAMES.forEach((name) => {
|
||||
tempData[k][name] = fileContent[name][k];
|
||||
});
|
||||
if (
|
||||
(isEmpty(tempData[k][REVIEWED_RESULT]) ||
|
||||
(tempData[k][REVIEWED_RESULT].length == 1 &&
|
||||
isEmpty(tempData[k][REVIEWED_RESULT][0]))) &&
|
||||
!isEmpty(tempData[k][PREDICTED_RESULT])
|
||||
) {
|
||||
tempData[k][REVIEWED_RESULT] = tempData[k][PREDICTED_RESULT];
|
||||
}
|
||||
});
|
||||
|
||||
setSelectedFileDataSource(tempData);
|
||||
@ -137,8 +187,8 @@ const ReviewPage = () => {
|
||||
setSelectedFileData(fileURL);
|
||||
} else {
|
||||
setSelectedFileData('FAILED_TO_LOAD_FILE');
|
||||
setImageLoading(false);
|
||||
}
|
||||
setImageLoading(false);
|
||||
};
|
||||
|
||||
const loadCurrentRequest = (requestIndex) => {
|
||||
@ -193,6 +243,10 @@ const ReviewPage = () => {
|
||||
|
||||
const reloadFilters = () => {
|
||||
setCurrentRequestIndex(1);
|
||||
if (searchParams.has('request_id')) {
|
||||
searchParams.delete('request_id');
|
||||
setSearchParams(searchParams);
|
||||
}
|
||||
fetchAllRequests(
|
||||
filterDateRange,
|
||||
filterSubsidiaries,
|
||||
@ -210,42 +264,20 @@ const ReviewPage = () => {
|
||||
firstRequest.then(async (data) => {
|
||||
if (data) setCurrentRequest(data);
|
||||
setAndLoadSelectedFile(data, 0);
|
||||
setTimeout(() => {
|
||||
loadCurrentRequest(1);
|
||||
}, 500);
|
||||
// setTimeout(() => {
|
||||
// loadCurrentRequest(1);
|
||||
// }, 500);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentRequestIndex(1);
|
||||
fetchAllRequests(
|
||||
filterDateRange,
|
||||
filterSubsidiaries,
|
||||
filterReviewState,
|
||||
filterIncludeTests,
|
||||
1,
|
||||
1,
|
||||
filterAccuracy,
|
||||
).then((data) => {
|
||||
setTotalPages(data?.page?.total_requests);
|
||||
setHasNextRequest(1 < data?.page?.total_requests);
|
||||
const firstRequest = fetchRequest(
|
||||
data?.subscription_requests[0].RequestID,
|
||||
);
|
||||
firstRequest.then(async (data) => {
|
||||
if (data) setCurrentRequest(data);
|
||||
setAndLoadSelectedFile(data, 0);
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleConfirmReview = async () => {
|
||||
const isConfirmed = window.confirm(
|
||||
'Are you sure you want to confirm this request is reviewed?',
|
||||
);
|
||||
if (isConfirmed) {
|
||||
try {
|
||||
addRecentRequest(currentRequest?.RequestID);
|
||||
await updateRevisedData(currentRequest?.RequestID);
|
||||
setCurrentRequest({
|
||||
...currentRequest,
|
||||
@ -465,7 +497,6 @@ const ReviewPage = () => {
|
||||
setAndLoadSelectedFile(currentRequest, index);
|
||||
setImageLoading(true);
|
||||
}}
|
||||
setIsReasonModalOpen={setIsReasonModalOpen}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@ -496,31 +527,32 @@ const ReviewPage = () => {
|
||||
overflowX: 'visible',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
maxHeight: '100%',
|
||||
maxWidth: '100%',
|
||||
height: 'auto',
|
||||
width: 'auto',
|
||||
cursor: 'zoom-in',
|
||||
}}
|
||||
src={selectedFileData}
|
||||
alt='file'
|
||||
onClick={() => setLightBox(true)}
|
||||
onLoad={() => {
|
||||
setImageLoading(false);
|
||||
}}
|
||||
/>
|
||||
<Spin spinning={imageLoading}>
|
||||
<img
|
||||
style={{
|
||||
maxHeight: '100%',
|
||||
maxWidth: '100%',
|
||||
height: 'auto',
|
||||
width: 'auto',
|
||||
cursor: 'zoom-in',
|
||||
}}
|
||||
src={selectedFileData}
|
||||
alt='file'
|
||||
onClick={() => setLightBox(true)}
|
||||
onLoad={() => {
|
||||
setImageLoading(false);
|
||||
}}
|
||||
/>
|
||||
|
||||
{lightBox && (
|
||||
<Lightbox
|
||||
image={selectedFileData}
|
||||
onClose={() => setLightBox(false)}
|
||||
></Lightbox>
|
||||
)}
|
||||
{lightBox && (
|
||||
<Lightbox
|
||||
image={selectedFileData}
|
||||
onClose={() => setLightBox(false)}
|
||||
></Lightbox>
|
||||
)}
|
||||
</Spin>
|
||||
</div>
|
||||
)}
|
||||
<Spin spinning={imageLoading}></Spin>
|
||||
|
||||
<div
|
||||
style={{
|
||||
@ -538,6 +570,7 @@ const ReviewPage = () => {
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<RecentRequest />
|
||||
<h3 style={{ margin: '0 8px ' }}>
|
||||
{totalRequests
|
||||
? 'No: ' + currentRequestIndex + '/' + totalRequests
|
||||
@ -630,7 +663,7 @@ const ReviewPage = () => {
|
||||
shape='default'
|
||||
size='middle'
|
||||
disabled={currentRequest && currentRequest['Is Reviewed']}
|
||||
style={{ minWidth: '120px', alignSelf: 'flex-end' }}
|
||||
style={{ minWidth: '120px' }}
|
||||
onClick={handleConfirmReview}
|
||||
>
|
||||
Confirm request
|
||||
@ -940,124 +973,6 @@ const ReviewPage = () => {
|
||||
</div>
|
||||
</Form>
|
||||
</Modal>
|
||||
<Modal
|
||||
title={t`Review`}
|
||||
open={isReasonModalOpen}
|
||||
width={700}
|
||||
onOk={async () => {
|
||||
// call submit api
|
||||
if (!reason || !solution) {
|
||||
notification.warning({
|
||||
message: 'Please select a reason or a solution',
|
||||
});
|
||||
} else {
|
||||
const params = {
|
||||
request_id: currentRequest?.RequestID,
|
||||
request_image_id: selectedFileName.replace(/\.[^/.]+$/, ''),
|
||||
};
|
||||
|
||||
let submitReason = reason;
|
||||
let submitSolution = solution;
|
||||
|
||||
if (reason === 'other') {
|
||||
if (!otherReason) {
|
||||
notification.warning({
|
||||
message: 'Please input other reason',
|
||||
});
|
||||
return;
|
||||
}
|
||||
submitReason = otherReason;
|
||||
}
|
||||
if (solution === 'other') {
|
||||
if (!otherSolution) {
|
||||
notification.warning({
|
||||
message: 'Please input other solution',
|
||||
});
|
||||
return;
|
||||
}
|
||||
submitSolution = otherSolution;
|
||||
}
|
||||
|
||||
const res = await badQualityReasonSubmit(
|
||||
params,
|
||||
submitReason,
|
||||
submitSolution,
|
||||
);
|
||||
|
||||
if (res.message) {
|
||||
notification.success({ message: 'Update reason success' });
|
||||
setIsReasonModalOpen(false);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onCancel={() => {
|
||||
setIsReasonModalOpen(false);
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||||
<Form
|
||||
style={{
|
||||
marginTop: 30,
|
||||
}}
|
||||
>
|
||||
<Form.Item name='reason' label={t`Reason for bad quality:`}>
|
||||
<Select
|
||||
placeholder='Select a reason'
|
||||
style={{ width: 200 }}
|
||||
options={REASON_BAD_QUALITY}
|
||||
onChange={setReason}
|
||||
value={reason}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{reason === 'other' && (
|
||||
<Input
|
||||
placeholder='Other reason'
|
||||
value={otherReason}
|
||||
onChange={(e) => {
|
||||
setOtherReason(e.target.value);
|
||||
}}
|
||||
style={{
|
||||
width: 200,
|
||||
marginTop: 30,
|
||||
marginBottom: 24,
|
||||
marginLeft: 10,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||||
<Form>
|
||||
<Form.Item name='reason' label={t`Solution:`}>
|
||||
<span style={{ display: 'none' }}>
|
||||
{counter_measure_map[reason]}
|
||||
</span>
|
||||
<Select
|
||||
placeholder='Select a solution'
|
||||
style={{ width: 200 }}
|
||||
options={SOLUTION_BAD_QUALITY}
|
||||
onChange={setSolution}
|
||||
value={solution}
|
||||
// defaultValue={solution}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{solution === 'other' && (
|
||||
<Input
|
||||
placeholder='Other solution'
|
||||
value={otherSolution}
|
||||
onChange={(e) => {
|
||||
setOtherSolution(e.target.value);
|
||||
}}
|
||||
style={{
|
||||
width: 200,
|
||||
marginBottom: 24,
|
||||
marginLeft: 10,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
7489
cope2n-fe/yarn.lock
Normal file
7489
cope2n-fe/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
6
node_modules/.package-lock.json
generated
vendored
6
node_modules/.package-lock.json
generated
vendored
@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "sbt-idp",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user