From 4c9c9b1a951044a983a05fabfd642d21615c4e11 Mon Sep 17 00:00:00 2001 From: dx-tan Date: Tue, 7 May 2024 10:53:16 +0700 Subject: [PATCH 1/9] Update: sunmodules --- cope2n-ai-fi/modules/sdsvkvu | 2 +- cope2n-api/fwd_api/utils/sdsvkvu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cope2n-ai-fi/modules/sdsvkvu b/cope2n-ai-fi/modules/sdsvkvu index 910420b..ec0d9a0 160000 --- a/cope2n-ai-fi/modules/sdsvkvu +++ b/cope2n-ai-fi/modules/sdsvkvu @@ -1 +1 @@ -Subproject commit 910420b53636b43af540e72237c06f49127163d3 +Subproject commit ec0d9a0a5a8c17c9a78165d1f78103951a2e138b diff --git a/cope2n-api/fwd_api/utils/sdsvkvu b/cope2n-api/fwd_api/utils/sdsvkvu index b7baf49..9564ba4 160000 --- a/cope2n-api/fwd_api/utils/sdsvkvu +++ b/cope2n-api/fwd_api/utils/sdsvkvu @@ -1 +1 @@ -Subproject commit b7baf4954e592068288c606376b035b41dd9e319 +Subproject commit 9564ba478c4df27b78526639d987b72dbbfccb40 From 8d4a7da23a4d8a3d445a25dc7eaade70e5f06b68 Mon Sep 17 00:00:00 2001 From: dx-tan Date: Thu, 16 May 2024 17:38:50 +0700 Subject: [PATCH 2/9] Update: Dockerfile --- cope2n-fe/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cope2n-fe/Dockerfile b/cope2n-fe/Dockerfile index f0b31ef..6a0f99c 100644 --- a/cope2n-fe/Dockerfile +++ b/cope2n-fe/Dockerfile @@ -2,7 +2,7 @@ FROM node:21-alpine AS build WORKDIR /app/ COPY --chown=node:node package*.json ./ -RUN npm install -g npm@10.4.0 && npm install +RUN yarn COPY --chown=node:node . . RUN npm run build RUN npm cache clean --force From 14ca844a1eee447eb20a6461051c2c0c2012e11b Mon Sep 17 00:00:00 2001 From: dx-tan Date: Thu, 16 May 2024 17:39:01 +0700 Subject: [PATCH 3/9] Update: Submodules --- cope2n-ai-fi/modules/sdsvkvu | 2 +- cope2n-api/fwd_api/utils/sdsvkvu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cope2n-ai-fi/modules/sdsvkvu b/cope2n-ai-fi/modules/sdsvkvu index ec0d9a0..c8056ad 160000 --- a/cope2n-ai-fi/modules/sdsvkvu +++ b/cope2n-ai-fi/modules/sdsvkvu @@ -1 +1 @@ -Subproject commit ec0d9a0a5a8c17c9a78165d1f78103951a2e138b +Subproject commit c8056adf6caf7f75b7e2cd9a9c2915098061fad7 diff --git a/cope2n-api/fwd_api/utils/sdsvkvu b/cope2n-api/fwd_api/utils/sdsvkvu index 9564ba4..c8056ad 160000 --- a/cope2n-api/fwd_api/utils/sdsvkvu +++ b/cope2n-api/fwd_api/utils/sdsvkvu @@ -1 +1 @@ -Subproject commit 9564ba478c4df27b78526639d987b72dbbfccb40 +Subproject commit c8056adf6caf7f75b7e2cd9a9c2915098061fad7 From 9cc368ec30be78708e3878f1ed9a0bdd2ab31908 Mon Sep 17 00:00:00 2001 From: dx-tan Date: Fri, 17 May 2024 10:12:25 +0700 Subject: [PATCH 4/9] Update: model weight --- cope2n-ai-fi/configs/sdsap_sbt/configs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cope2n-ai-fi/configs/sdsap_sbt/configs.py b/cope2n-ai-fi/configs/sdsap_sbt/configs.py index 7120915..288a546 100755 --- a/cope2n-ai-fi/configs/sdsap_sbt/configs.py +++ b/cope2n-ai-fi/configs/sdsap_sbt/configs.py @@ -29,7 +29,7 @@ kvu_model = { "option": "sbt_v2", "model": { "pretrained_model_path": "/workspace/cope2n-ai-fi/weights/layoutxlm-base", - "config": "/workspace/cope2n-ai-fi/weights/models/sdsvkvu/key_value_understanding_for_sbt-20240503-182151_1/base.yaml", - "checkpoint": "/workspace/cope2n-ai-fi/weights/models/sdsvkvu/key_value_understanding_for_sbt-20240503-182151_1/checkpoints/best_model.pth" + "config": "/workspace/cope2n-ai-fi/weights/models/sdsvkvu/key_value_understanding_for_sbt-20240506-175534/base.yaml", + "checkpoint": "/workspace/cope2n-ai-fi/weights/models/sdsvkvu/key_value_understanding_for_sbt-20240506-175534/checkpoints/best_model.pth" } } \ No newline at end of file From f57a0a6ea667072a4daca87c2d1b490f6698d22b Mon Sep 17 00:00:00 2001 From: dx-tan Date: Fri, 17 May 2024 10:16:03 +0700 Subject: [PATCH 5/9] Update: submodules --- cope2n-ai-fi/modules/sdsvkvu | 2 +- cope2n-api/fwd_api/utils/sdsvkvu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cope2n-ai-fi/modules/sdsvkvu b/cope2n-ai-fi/modules/sdsvkvu index c8056ad..e035559 160000 --- a/cope2n-ai-fi/modules/sdsvkvu +++ b/cope2n-ai-fi/modules/sdsvkvu @@ -1 +1 @@ -Subproject commit c8056adf6caf7f75b7e2cd9a9c2915098061fad7 +Subproject commit e0355598ca82da176d7a0e1a07f1b8488fd96e3e diff --git a/cope2n-api/fwd_api/utils/sdsvkvu b/cope2n-api/fwd_api/utils/sdsvkvu index c8056ad..e035559 160000 --- a/cope2n-api/fwd_api/utils/sdsvkvu +++ b/cope2n-api/fwd_api/utils/sdsvkvu @@ -1 +1 @@ -Subproject commit c8056adf6caf7f75b7e2cd9a9c2915098061fad7 +Subproject commit e0355598ca82da176d7a0e1a07f1b8488fd96e3e From 4682bf67de88f9ccd2c801176499be2f3b3ef112 Mon Sep 17 00:00:00 2001 From: dx-tan Date: Mon, 20 May 2024 11:07:39 +0700 Subject: [PATCH 6/9] Remove: feedback validation --- cope2n-api/fwd_api/celery_worker/internal_task.py | 4 ++-- cope2n-api/fwd_api/utils/accuracy.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cope2n-api/fwd_api/celery_worker/internal_task.py b/cope2n-api/fwd_api/celery_worker/internal_task.py index ec53777..90a7a68 100755 --- a/cope2n-api/fwd_api/celery_worker/internal_task.py +++ b/cope2n-api/fwd_api/celery_worker/internal_task.py @@ -127,7 +127,7 @@ def process_csv_feedback(csv_file_path, feedback_id): print(f"[ERROR] image.doc_type: {image.doc_type} - image.index_in_request: {image.index_in_request} - time_cost: {time_cost} - {e}") if not validate_feedback_file(_feedback_result, _predict_result): status[request_id] = "Missalign imei number between feedback and predict" - continue + # continue if image.doc_type == "invoice": _predict_result["imei_number"] = [] if _feedback_result: @@ -136,7 +136,7 @@ def process_csv_feedback(csv_file_path, feedback_id): else: try: _predict_result = {"retailername": None, "sold_to_party": None, "invoice_no": None, "purchase_date": [], "imei_number": [_predict_result["imei_number"][image.index_in_request]]} - _feedback_result = {"retailername": None, "sold_to_party": None, "invoice_no": None, "purchase_date": None, "imei_number": [_feedback_result["imei_number"][image.index_in_request]]} if _feedback_result else None + _feedback_result = {"retailername": None, "sold_to_party": None, "invoice_no": None, "purchase_date": None, "imei_number": [_feedback_result["imei_number"][image.index_in_request]]} if _feedback_result and len(_feedback_result["imei_number"]) > image.index_in_request else None except Exception as e: print (f"[ERROR]: {request_id} - {e}") image.predict_result = _predict_result diff --git a/cope2n-api/fwd_api/utils/accuracy.py b/cope2n-api/fwd_api/utils/accuracy.py index 1d5e938..a45e435 100755 --- a/cope2n-api/fwd_api/utils/accuracy.py +++ b/cope2n-api/fwd_api/utils/accuracy.py @@ -529,6 +529,7 @@ def validate_feedback_file(feedback, predict): num_imei_predict = len(predict.get("imei_number", [])) if num_imei_feedback != num_imei_predict: return False + feedback["imei_number"] = imei_feedback return True def first_of_list(the_list): From c279d0997c8709cebdb221cbe9a707f737d16ffd Mon Sep 17 00:00:00 2001 From: dx-tan Date: Wed, 22 May 2024 14:42:09 +0700 Subject: [PATCH 7/9] Update: Submodules --- cope2n-ai-fi/modules/sdsvkvu | 2 +- cope2n-api/fwd_api/utils/sdsvkvu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cope2n-ai-fi/modules/sdsvkvu b/cope2n-ai-fi/modules/sdsvkvu index e035559..f5604a9 160000 --- a/cope2n-ai-fi/modules/sdsvkvu +++ b/cope2n-ai-fi/modules/sdsvkvu @@ -1 +1 @@ -Subproject commit e0355598ca82da176d7a0e1a07f1b8488fd96e3e +Subproject commit f5604a92edcf8fd9021397b047c946a03dbb9e5a diff --git a/cope2n-api/fwd_api/utils/sdsvkvu b/cope2n-api/fwd_api/utils/sdsvkvu index e035559..f5604a9 160000 --- a/cope2n-api/fwd_api/utils/sdsvkvu +++ b/cope2n-api/fwd_api/utils/sdsvkvu @@ -1 +1 @@ -Subproject commit e0355598ca82da176d7a0e1a07f1b8488fd96e3e +Subproject commit f5604a92edcf8fd9021397b047c946a03dbb9e5a From 5c93d5f87e16869e60a698f5fcda48ed2acf8a7f Mon Sep 17 00:00:00 2001 From: phanphan Date: Thu, 23 May 2024 18:48:21 +0700 Subject: [PATCH 8/9] =?UTF-8?q?r=C3=A8actor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cope2n-fe/src/pages/reviews2/FileCard.tsx | 38 +-- cope2n-fe/src/pages/reviews2/const.ts | 31 +- cope2n-fe/src/pages/reviews2/index.tsx | 386 +++++++++++++--------- 3 files changed, 273 insertions(+), 182 deletions(-) diff --git a/cope2n-fe/src/pages/reviews2/FileCard.tsx b/cope2n-fe/src/pages/reviews2/FileCard.tsx index 241989a..2fd0130 100644 --- a/cope2n-fe/src/pages/reviews2/FileCard.tsx +++ b/cope2n-fe/src/pages/reviews2/FileCard.tsx @@ -10,8 +10,9 @@ const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => { border: '1px solid #ccc', backgroundColor: isSelected ? '#d4ecff' : '#fff', padding: '4px 8px', - margin: '0 0 4px', + margin: '0 8px 4px', cursor: 'pointer', + display: 'flex', }} onClick={onClick} > @@ -41,35 +42,18 @@ const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => { {fileName ? fileName.substring(0, 25).replace('temp_', '') : fileName} -
{ + const downloadUrl = file['File URL']; + window.open(downloadUrl, '_blank'); }} > - - -
+ + + ); }; diff --git a/cope2n-fe/src/pages/reviews2/const.ts b/cope2n-fe/src/pages/reviews2/const.ts index e4b1f1d..0122ac5 100644 --- a/cope2n-fe/src/pages/reviews2/const.ts +++ b/cope2n-fe/src/pages/reviews2/const.ts @@ -1,4 +1,4 @@ -import { t } from "@lingui/macro"; +import { t } from '@lingui/macro'; export const counter_measure_map = { invalid_image: 'Remove this image from the evaluation report', @@ -23,9 +23,9 @@ export const REASON_BAD_QUALITY = [ { value: 'wrong_feedback', label: t`Wrong Feedback` }, { value: 'ocr_cannot_extract', label: t`Ocr cannot extract` }, { value: 'other', label: t`Other` }, -] +]; -export const SOLUTION_BAD_QUALITY =[ +export const SOLUTION_BAD_QUALITY = [ { value: 'Remove this image from the evaluation report', label: t`Remove this image from the evaluation report`, @@ -36,7 +36,7 @@ export const SOLUTION_BAD_QUALITY =[ label: t`Update revised result and re-calculate accuracy`, }, { value: 'other', label: t`Other` }, -] +]; export const SUBSIDIARIES = [ { value: 'SEAO', label: 'SEAO' }, @@ -46,4 +46,25 @@ export const SUBSIDIARIES = [ { value: 'SEPCO', label: 'SEPCO' }, { value: 'TSE', label: 'TSE' }, { value: 'SEIN', label: 'SEIN' }, -] \ No newline at end of file +]; + +export const SOURCE_KEYS = [ + 'retailername', + 'sold_to_party', + 'invoice_no', + 'purchase_date', + 'imei_number', +]; + +export const FEEDBACK_RESULT = 'Feedback Result'; +export const FEEDBACK_ACCURACY = 'Feedback Accuracy'; +export const PREDICTED_RESULT = 'Predicted Result'; +export const REVIEWED_ACCURACY = 'Reviewed Accuracy'; +export const REVIEWED_RESULT = 'Reviewed Result'; +export const SOURCE_OBJECT_NAMES = [ + FEEDBACK_RESULT, + FEEDBACK_ACCURACY, + PREDICTED_RESULT, + REVIEWED_ACCURACY, + REVIEWED_RESULT +]; diff --git a/cope2n-fe/src/pages/reviews2/index.tsx b/cope2n-fe/src/pages/reviews2/index.tsx index 46a11bf..2310db6 100644 --- a/cope2n-fe/src/pages/reviews2/index.tsx +++ b/cope2n-fe/src/pages/reviews2/index.tsx @@ -35,8 +35,14 @@ import { normalizeData } from 'utils/field-value-process'; import { fetchAllRequests, fetchRequest } from './api'; import { counter_measure_map, + FEEDBACK_ACCURACY, + FEEDBACK_RESULT, + PREDICTED_RESULT, REASON_BAD_QUALITY, + REVIEWED_RESULT, SOLUTION_BAD_QUALITY, + SOURCE_KEYS, + SOURCE_OBJECT_NAMES, SUBSIDIARIES, } from './const'; import FileCard from './FileCard'; @@ -48,6 +54,7 @@ const ReviewPage = () => { const [isReasonModalOpen, setIsReasonModalOpen] = useState(false); const [selectedFileId, setSelectedFileId] = useState(0); const [selectedFileData, setSelectedFileData] = useState(null); + const [selectedFileDataSource, setSelectedFileDataSource] = useState({}); const [selectedFileName, setSelectedFileName] = useState(null); // Default date range: 1 month ago to today @@ -78,6 +85,18 @@ const ReviewPage = () => { } }, [reason]); + const updateSelectedFileDataSource = (fileContent) => { + let tempData = {}; + SOURCE_KEYS.forEach((k) => { + tempData[k] = {}; + SOURCE_OBJECT_NAMES.forEach((name) => { + tempData[k][name] = fileContent[name][k]; + }); + }); + + setSelectedFileDataSource(tempData); + }; + const setAndLoadSelectedFile = async (requestData, index) => { setSelectedFileId(index); if (!requestData['Files'][index]) { @@ -87,6 +106,8 @@ const ReviewPage = () => { } const fileName = requestData['Files'][index]['File Name']; const fileURL = requestData['Files'][index]['File URL']; + updateSelectedFileDataSource(requestData['Files'][index]); + const response = await fetch(fileURL); if (response.status === 200) { setSelectedFileName(fileName); @@ -99,7 +120,6 @@ const ReviewPage = () => { } }; - console.log(dataSource); const loadCurrentRequest = (requestIndex) => { setLoading(true); setImageLoading(true); @@ -122,7 +142,6 @@ const ReviewPage = () => { ); requestData .then(async (data) => { - console.log('🚀 ~ .then ~ data:', data); if (data) setCurrentRequest(data); const predicted = data && data['Predicted Result'] ? data['Predicted Result'] : {}; @@ -308,6 +327,26 @@ const ReviewPage = () => { const [lightBox, setLightBox] = useState(false); + const updateRevised = (fieldName) => { + console.log('🚀 ~ updateRevised ~ fieldName:', fieldName); + // const tempData = Object.assign({}, selectedFileDataSource); + // tempData[fieldName][REVIEWED_RESULT] = tempData[fieldName][FEEDBACK_RESULT]; + // console.log('🚀 ~ updateRevised ~ tempData:', tempData); + // updateSelectedFileDataSource(tempData); + + setSelectedFileDataSource((prevData) => { + prevData[fieldName][REVIEWED_RESULT] = + prevData[fieldName][FEEDBACK_RESULT]; + return { + ...prevData, + }; + }); + }; + + // useEffect(() => { + + // }, [selectedFileDataSource]); + console.log('update data:', selectedFileDataSource); return (
{ margin: '0 0 4px 0', }} > -
- + {totalRequests ? ( +
- {fullscreen ? : } - {fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'} - - {totalRequests ? ( - <> -    Request ID: {currentRequest?.RequestID} - - ) : ( - '' - )} -
-
+
+   Request ID:   + {currentRequest?.RequestID} +
{' '} +
+   Redemption ID:   + {currentRequest?.RedemptionID} +
{' '} +
+   Created at:   + {currentRequest?.created_at} +
{' '} +
+   Request time:   + {currentRequest?.['Client Request Time (ms)']} +
{' '} +
+   Processing time:   + {currentRequest?.['Server Processing Time (ms)']} +
{' '} +
+   Raw accuracy:   + {currentRequest?.raw_accuracy} +
{' '} +
+ ) : ( + '' + )} + {/*
{ > Filters -
+
*/}
{ display: 'flex', }} > -
- {totalRequests > 0 && ( -
-
-

- Files ({currentRequest?.Files?.length}) -

- {currentRequest?.Files.map((file, index) => ( - { - setAndLoadSelectedFile(currentRequest, index); - setImageLoading(true); - }} - setIsReasonModalOpen={setIsReasonModalOpen} - /> - ))} -
- {totalRequests > 0 && ( -
- Request ID - - Redemption - - Created date - - Request time - - Processing time - - Raw accuracy - -
- )} -
- )} -
{ display: 'flex', flexDirection: 'column', position: 'relative', - padding: '0 16px', + padding: '8px 16px', // overflow: 'auto' }} > + {totalRequests > 0 && ( +
+

+ Files ({currentRequest?.Files?.length}) +

+ {currentRequest?.Files.map((file, index) => ( + { + setAndLoadSelectedFile(currentRequest, index); + setImageLoading(true); + }} + setIsReasonModalOpen={setIsReasonModalOpen} + /> + ))} +
+ )}
@@ -685,11 +666,18 @@ const ReviewPage = () => { />
+
{ flexDirection: 'column', }} > +
+ + +
- {dataSource?.map((data) => { + {SOURCE_KEYS?.map((data) => { + let shouldRevised = false; + try { + if ( + selectedFileDataSource[data]?.[FEEDBACK_ACCURACY].length > 0 + ) { + shouldRevised = + selectedFileDataSource[data][FEEDBACK_ACCURACY][0] < 1; + } + } catch (error) {} return (
{ margin: '0 0 4px', }} > -

{data.key}

+

{data}

); })} + + {/*
+ +
*/} + {t`Bad image reason:`} +
+ { + setOtherReason(e.target.value); + }} + /> + )} +
+ {t`Solution:`} +
+ { + setOtherSolution(e.target.value); + }} + /> + )} +
-
Date: Fri, 24 May 2024 12:59:34 +0700 Subject: [PATCH 9/9] update data by field and confirm review --- cope2n-fe/src/pages/reviews2/FileCard.tsx | 89 ++++-- cope2n-fe/src/pages/reviews2/api.ts | 29 +- cope2n-fe/src/pages/reviews2/index.tsx | 366 ++++++++++------------ 3 files changed, 249 insertions(+), 235 deletions(-) diff --git a/cope2n-fe/src/pages/reviews2/FileCard.tsx b/cope2n-fe/src/pages/reviews2/FileCard.tsx index 2fd0130..1e76926 100644 --- a/cope2n-fe/src/pages/reviews2/FileCard.tsx +++ b/cope2n-fe/src/pages/reviews2/FileCard.tsx @@ -1,50 +1,78 @@ -import { DownloadOutlined } from '@ant-design/icons'; -import { Button } from 'antd'; +import { + CheckCircleOutlined, + DownloadOutlined, + ExclamationCircleOutlined, +} from '@ant-design/icons'; +import { Button, Tag } from 'antd'; const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => { const fileName = file['File Name']; - + let status = true; + if (file['Is Required'] && !file['Is Reviewed']) { + status = false; + } return (
-

+

+ {file['Doc Type'].toUpperCase()} +

+ + {fileName + ? fileName.substring(0, 25).replace('temp_', '') + : fileName} + +
+ : + } + style={{ display: 'inline-block', fontWeight: 'bold' }} + // bordered={false} > - {file['Doc Type'].toUpperCase()} -

- - {fileName ? fileName.substring(0, 25).replace('temp_', '') : fileName} - + {status ? 'Good' : 'Warning'}{' '} +
- ); }; diff --git a/cope2n-fe/src/pages/reviews2/api.ts b/cope2n-fe/src/pages/reviews2/api.ts index a8c1885..75def5b 100644 --- a/cope2n-fe/src/pages/reviews2/api.ts +++ b/cope2n-fe/src/pages/reviews2/api.ts @@ -43,7 +43,6 @@ export const fetchAllRequests = async ( export const updateRevisedData = async ( requestID: any, - newRevisedData: any, ) => { // const requestID = ; const token = localStorage.getItem('sbt-token') || ''; @@ -53,9 +52,7 @@ export const updateRevisedData = async ( Authorization: `${JSON.parse(token)}`, 'Content-Type': 'application/json', }, - body: JSON.stringify({ - reviewed_result: newRevisedData, - }), + body: JSON.stringify({"request_file_results": []}), }).catch((error) => { console.log(error); throw error; @@ -65,6 +62,30 @@ export const updateRevisedData = async ( } }; +export const updateRevisedDataByFile = async ( + requestID: any, + fileID: any, + newRevisedData: any, +) => { + // 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', + }, + body: JSON.stringify(newRevisedData), + }).catch((error) => { + console.log(error); + throw error; + }); + if (result.status != 200) { + throw new Error('Could not update revised data'); + } +}; + + export const fetchRequest = async (id) => { const token = localStorage.getItem('sbt-token') || ''; const response = await fetch(`${baseURL}/ctel/request/${id}/`, { diff --git a/cope2n-fe/src/pages/reviews2/index.tsx b/cope2n-fe/src/pages/reviews2/index.tsx index 2310db6..fca81ca 100644 --- a/cope2n-fe/src/pages/reviews2/index.tsx +++ b/cope2n-fe/src/pages/reviews2/index.tsx @@ -26,13 +26,17 @@ 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 { baseURL } from 'request/api'; // Import the styles import '@react-pdf-viewer/core/lib/styles/index.css'; import { badQualityReasonSubmit } from 'request'; -import { normalizeData } from 'utils/field-value-process'; -import { fetchAllRequests, fetchRequest } from './api'; +import { getErrorMessage } from 'utils/error-handler'; +import { + fetchAllRequests, + fetchRequest, + updateRevisedData, + updateRevisedDataByFile, +} from './api'; import { counter_measure_map, FEEDBACK_ACCURACY, @@ -56,6 +60,7 @@ const ReviewPage = () => { const [selectedFileData, setSelectedFileData] = useState(null); const [selectedFileDataSource, setSelectedFileDataSource] = useState({}); const [selectedFileName, setSelectedFileName] = useState(null); + const [disableUpdateFileBtn, setDisableUpdateFileBtn] = useState(false); // Default date range: 1 month ago to today const [filterDateRange, setFilterDateRange] = useState(['', '']); @@ -69,7 +74,6 @@ const ReviewPage = () => { const [currentRequestIndex, setCurrentRequestIndex] = useState(1); const [hasNextRequest, setHasNextRequest] = useState(true); const [totalRequests, setTotalPages] = useState(0); - const [dataSource, setDataSource] = useState([]); const [pageIndexToGoto, setPageIndexToGoto] = useState(1); @@ -106,14 +110,32 @@ const ReviewPage = () => { } const fileName = requestData['Files'][index]['File Name']; const fileURL = requestData['Files'][index]['File URL']; - updateSelectedFileDataSource(requestData['Files'][index]); + let fileDataSource = requestData['Files'][index]; + updateSelectedFileDataSource(fileDataSource); + let reason = fileDataSource.Reason; + let solution = fileDataSource['Counter Measures']; + if (!reason) { + setReason(null); + } else if (REASON_BAD_QUALITY.some((r) => r.value === reason)) { + setReason(reason); + } else { + setReason('other'); + setOtherReason(reason); + } + if (!solution) { + setSolution(null); + } else if (SOLUTION_BAD_QUALITY.some((r) => r.value === solution)) { + setSolution(solution); + } else { + setSolution('other'); + setOtherSolution(solution); + } + + setSelectedFileName(fileName); const response = await fetch(fileURL); if (response.status === 200) { - setSelectedFileName(fileName); setSelectedFileData(fileURL); - console.log('Loading file: ' + fileName); - console.log('URL: ' + fileURL); } else { setSelectedFileData('FAILED_TO_LOAD_FILE'); setImageLoading(false); @@ -143,23 +165,6 @@ const ReviewPage = () => { requestData .then(async (data) => { if (data) setCurrentRequest(data); - const predicted = - data && data['Predicted Result'] ? data['Predicted Result'] : {}; - const submitted = - data && data['Feedback Result'] ? data['Feedback Result'] : {}; - const revised = - data && data['Reviewed Result'] ? data['Reviewed Result'] : {}; - const keys = Object.keys(predicted); - const tableRows = []; - for (let i = 0; i < keys.length; i++) { - let instance = {}; - instance['key'] = keys[i]; - instance['predicted'] = predicted[keys[i]]; - instance['submitted'] = submitted[keys[i]]; - instance['revised'] = revised[keys[i]]; - tableRows.push(instance); - } - setDataSource(tableRows); setAndLoadSelectedFile(data, 0); }) .finally(() => { @@ -241,80 +246,58 @@ const ReviewPage = () => { }); }, []); - // "Key", "Accuracy", "Submitted", "Revised" - interface DataType { - key: string; - accuracy: number; - submitted: string; - revised: string; - } - - const updateRevisedData = async (newRevisedData: any) => { - const requestID = currentRequest.RequestID; - const token = localStorage.getItem('sbt-token') || ''; - const result = await fetch(`${baseURL}/ctel/request/${requestID}/`, { - method: 'POST', - headers: { - Authorization: `${JSON.parse(token)}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - reviewed_result: newRevisedData, - }), - }).catch((error) => { - console.log(error); - throw error; - }); - if (result.status != 200) { - throw new Error('Could not update revised data'); - } - }; - - const handleSave = (row: DataType) => { - const newData = [...dataSource]; - const index = newData.findIndex((item) => row.key === item.key); - const item = newData[index]; - newData.splice(index, 1, { - ...item, - ...row, - }); - const newRevisedData = {}; - for (let i = 0; i < newData.length; i++) { - newData[i].revised = normalizeData(newData[i].key, newData[i].revised); - newRevisedData[newData[i].key] = newData[i].revised; - } - updateRevisedData(newRevisedData) - .then(() => { - // "[Is Reviewed]" => true + const handleConfirmReview = async () => { + const isConfirmed = window.confirm( + 'Are you sure you want to confirm this request is reviewed?', + ); + if (isConfirmed) { + try { + await updateRevisedData(currentRequest?.RequestID); setCurrentRequest({ ...currentRequest, ['Is Reviewed']: true, }); - }) - .then(() => { - setDataSource(newData); - }) - .catch((error) => { - message.error( - 'Could not update revised data. Please check the format.', - ); - }); + notification.success({ message: 'Update file success' }); + } catch (error) { + notification.error({ + message: getErrorMessage(error), + }); + } + } }; const submitRevisedData = async () => { - const newData = [...dataSource]; - const newRevisedData = {}; - for (let i = 0; i < newData.length; i++) { - newData[i].revised = normalizeData(newData[i].key, newData[i].revised); - newRevisedData[newData[i].key] = newData[i].revised; - } - updateRevisedData(newRevisedData).then(() => { - // "[Is Reviewed]" => true - setCurrentRequest({ - ...currentRequest, - ['Is Reviewed']: true, - }); + const fileId = selectedFileName.split('.')[0]; + + let request_file_result = {}; + SOURCE_KEYS.forEach((k) => { + request_file_result[k] = selectedFileDataSource[k][REVIEWED_RESULT]; }); + let data = { + request_file_result, + reason: reason ? reason : otherReason, + solution: solution ? solution : otherSolution, + }; + try { + await updateRevisedDataByFile(currentRequest?.RequestID, fileId, data); + + let newData = currentRequest; + newData.Files[selectedFileId]['Is Reviewed'] = true; + + setCurrentRequest({ + ...newData, + }); + notification.success({ message: 'Update file success' }); + + const requestData = await fetchRequest( + currentRequest?.RequestID, + ); + setCurrentRequest(requestData) + } catch (error) { + notification.error({ + message: getErrorMessage(error), + }); + } }; // use left/right keys to navigate @@ -328,12 +311,6 @@ const ReviewPage = () => { const [lightBox, setLightBox] = useState(false); const updateRevised = (fieldName) => { - console.log('🚀 ~ updateRevised ~ fieldName:', fieldName); - // const tempData = Object.assign({}, selectedFileDataSource); - // tempData[fieldName][REVIEWED_RESULT] = tempData[fieldName][FEEDBACK_RESULT]; - // console.log('🚀 ~ updateRevised ~ tempData:', tempData); - // updateSelectedFileDataSource(tempData); - setSelectedFileDataSource((prevData) => { prevData[fieldName][REVIEWED_RESULT] = prevData[fieldName][FEEDBACK_RESULT]; @@ -343,10 +320,15 @@ const ReviewPage = () => { }); }; - // useEffect(() => { + const handleUpdateFileInField = (fieldName, fieldValue) => { + setSelectedFileDataSource((prevData) => { + prevData[fieldName][REVIEWED_RESULT] = fieldValue; + return { + ...prevData, + }; + }); + }; - // }, [selectedFileDataSource]); - console.log('update data:', selectedFileDataSource); return (
{ size='large' />
-
- - {totalRequests ? ( -
-
-   Request ID:   - {currentRequest?.RequestID} -
{' '} -
-   Redemption ID:   - {currentRequest?.RedemptionID} -
{' '} -
-   Created at:   - {currentRequest?.created_at} -
{' '} -
-   Request time:   - {currentRequest?.['Client Request Time (ms)']} -
{' '} -
-   Processing time:   - {currentRequest?.['Server Processing Time (ms)']} -
{' '} -
-   Raw accuracy:   - {currentRequest?.raw_accuracy} -
{' '} -
- ) : ( - '' - )} - {/*
- - -
*/} -
+
+
+ + {totalRequests && ( +
+
+ Request ID:   + {currentRequest?.RequestID} +
{' '} +
+ Created at:   + {currentRequest?.created_at} +
{' '} +
+ Request time:   + {currentRequest?.['Client Request Time (ms)']} +
{' '} +
+ Redemption ID:   + {currentRequest?.RedemptionID} +
{' '} +
+ Raw accuracy:   + {currentRequest?.raw_accuracy} +
{' '} +
+ Processing time:   + {currentRequest?.['Server Processing Time (ms)']} +
{' '} +
+ )} +
{totalRequests > 0 && (
{ flexDirection: 'row', alignItems: 'center', flexGrow: 0, + margin: '8px 0 0 0', }} >

{

{
-
+
{SOURCE_KEYS?.map((data) => { let shouldRevised = false; try { @@ -755,25 +718,15 @@ const ReviewPage = () => { value={selectedFileDataSource[data]?.[PREDICTED_RESULT]} /> handleUpdateFileInField(data, e.target.value)} />
); })} - - {/*
- -
*/} {t`Bad image reason:`}
{ > { setOtherReason(e.target.value); }} @@ -810,7 +763,7 @@ const ReviewPage = () => { > { @@ -828,6 +781,19 @@ const ReviewPage = () => { )}
+
+ +