diff --git a/cope2n-fe/src/pages/reviews2/FileCard.tsx b/cope2n-fe/src/pages/reviews2/FileCard.tsx index 15678cf..7156e9d 100644 --- a/cope2n-fe/src/pages/reviews2/FileCard.tsx +++ b/cope2n-fe/src/pages/reviews2/FileCard.tsx @@ -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; diff --git a/cope2n-fe/src/pages/reviews2/RecentRequest.tsx b/cope2n-fe/src/pages/reviews2/RecentRequest.tsx new file mode 100644 index 0000000..492cc80 --- /dev/null +++ b/cope2n-fe/src/pages/reviews2/RecentRequest.tsx @@ -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([]); + + const handleShowModal = () => { + const data = localStorage.getItem('recent-request'); + if (data) { + setListData(JSON.parse(data)); + } + setShowModal(true); + }; + + const handleCloseModal = () => { + setShowModal(false); + }; + + return ( +
+ + + {listData.length > 0 ? ( + + ) : ( +

No recent requests

+ )} +
+ } + width={600} + height={600} + open={showModal} + title='Recent Requests' + onCancel={handleCloseModal} + > + {listData.map((item, index) => ( +
+ + {dayjs(item.time).format('hh:mm - DD/MM')} + {item.request_id} + +
+ ))} + + + ); +}; + +export default RecentRequesModal; diff --git a/cope2n-fe/src/pages/reviews2/api.ts b/cope2n-fe/src/pages/reviews2/api.ts index 75def5b..998dd20 100644 --- a/cope2n-fe/src/pages/reviews2/api.ts +++ b/cope2n-fe/src/pages/reviews2/api.ts @@ -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)) +}; diff --git a/cope2n-fe/src/pages/reviews2/const.ts b/cope2n-fe/src/pages/reviews2/const.ts index 0122ac5..bdb944a 100644 --- a/cope2n-fe/src/pages/reviews2/const.ts +++ b/cope2n-fe/src/pages/reviews2/const.ts @@ -68,3 +68,8 @@ export const SOURCE_OBJECT_NAMES = [ REVIEWED_ACCURACY, REVIEWED_RESULT ]; + +export type RecentRequest = { + request_id: string, + time: Date +} \ No newline at end of file diff --git a/cope2n-fe/src/pages/reviews2/index.tsx b/cope2n-fe/src/pages/reviews2/index.tsx index 5123174..4601dbf 100644 --- a/cope2n-fe/src/pages/reviews2/index.tsx +++ b/cope2n-fe/src/pages/reviews2/index.tsx @@ -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} /> ))} @@ -496,31 +527,32 @@ const ReviewPage = () => { overflowX: 'visible', }} > - file setLightBox(true)} - onLoad={() => { - setImageLoading(false); - }} - /> + + file setLightBox(true)} + onLoad={() => { + setImageLoading(false); + }} + /> - {lightBox && ( - setLightBox(false)} - > - )} + {lightBox && ( + setLightBox(false)} + > + )} + )} -
{ alignItems: 'center', }} > +

{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 = () => {

- { - // 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); - }} - > -
-
- - { - setOtherReason(e.target.value); - }} - style={{ - width: 200, - marginTop: 30, - marginBottom: 24, - marginLeft: 10, - }} - /> - )} -
-
- - - - {counter_measure_map[reason]} - - { - setOtherSolution(e.target.value); - }} - style={{ - width: 200, - marginBottom: 24, - marginLeft: 10, - }} - /> - )} -
-
); }; diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json deleted file mode 100644 index d2d5a1f..0000000 --- a/node_modules/.package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "sbt-idp", - "lockfileVersion": 3, - "requires": true, - "packages": {} -}