import { t } from '@lingui/macro'; import { Button, Input, Table, Tag, DatePicker, Form, Modal, Select, Spin, message, Upload } from 'antd'; import React, { useContext, useEffect, useRef, useState } from 'react'; import type { GetRef } from 'antd'; import { Layout } from 'antd'; import { DownloadOutlined, CheckCircleOutlined, ClockCircleFilled, } from '@ant-design/icons'; import styled from 'styled-components'; const { Sider, Content } = Layout; import { baseURL } from "request/api"; import { Viewer } from '@react-pdf-viewer/core'; import { SbtPageHeader } from 'components/page-header'; import { UploadOutlined } from '@ant-design/icons'; import type { GetProp, UploadFile, UploadProps } from 'antd'; import 'react-json-view-lite/dist/index.css'; type FileType = Parameters>[0]; const ENABLE_REVIEW = true; // Import the styles import '@react-pdf-viewer/core/lib/styles/index.css'; const siderStyle: React.CSSProperties = { backgroundColor: '#fafafa', padding: 10, width: 200, }; const StyledTable = styled(Table)` & .sbt-table-cell { padding: 4px!important; } `; type InputRef = GetRef; type FormInstance = GetRef>; const EditableContext = React.createContext | null>(null); interface Item { key: string; accuracy: number; revised: string; action: string; } interface EditableRowProps { index: number; } const EditableRow: React.FC = ({ index, ...props }) => { const [form] = Form.useForm(); return (
); }; interface EditableCellProps { title: React.ReactNode; editable: boolean; children: React.ReactNode; dataIndex: keyof Item; record: Item; handleSave: (record: Item) => void; } const EditableCell: React.FC = ({ title, editable, children, dataIndex, record, handleSave, ...restProps }) => { const [editing, setEditing] = useState(false); const inputRef = useRef(null); const form = useContext(EditableContext)!; useEffect(() => { if (editing) { inputRef.current!.focus(); } }, [editing]); const toggleEdit = () => { setEditing(!editing); form.setFieldsValue({ [dataIndex]: record[dataIndex] }); }; const save = async () => { try { const values = await form.validateFields(); toggleEdit(); handleSave({ ...record, ...values }); } catch (errInfo) { console.log('Save failed:', errInfo); } }; let childNode = children; if (editable) { childNode = editing ? ( ) : (
{children}
); } return {childNode}; }; // type EditableTableProps = Parameters[0]; const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => { const fileName = file["File Name"]; return (
{file["Doc Type"].toUpperCase()} {fileName ? fileName.substring(0, 25).replace("temp_", "") : fileName}
{/* */}
); }; const fetchRequest = async (id) => { const token = localStorage.getItem('sbt-token') || ''; const response = await fetch(`${baseURL}/ctel/request/${id}/`, { method: 'GET', headers: { "Authorization": `${JSON.parse(token)}` } }); return await (await response.json()).subscription_requests[0]; }; const InferencePage = () => { const [invoiceFiles, setInvoiceFiles] = useState([]); const [imei1Files, setImei1Files] = useState([]); const [imei2Files, setImei2Files] = useState([]); const [uploading, setUploading] = useState(false); const [responseData, setResponseData] = useState(null); const [finishedProcessing, setFinishedProcessing] = useState(false); const handleUpload = () => { const formData = new FormData(); if (invoiceFiles.length > 0) { formData.append('invoice_file', invoiceFiles[0] as FileType); } if (imei1Files.length > 0) { formData.append('imei_files', imei1Files[0] as FileType); } if (imei2Files.length > 0) { formData.append('imei_files', imei2Files[0] as FileType); } formData.append('is_test_request', 'true'); setUploading(true); setResponseData(null); const token = localStorage.getItem('sbt-token') || ''; fetch(`${baseURL}/ctel/images/process_sync/`, { method: 'POST', body: formData, headers: { "Authorization": `${JSON.parse(token)}` } }) .then(async (res) => { const data = await res.json(); if (data["status"] != "200") { setResponseData(null); return; } setTimeout(() => { loadRequestById(data["request_id"]); }, 2000); setFinishedProcessing(true); return data; }) .then(() => { message.success('Upload successfully.'); }) .catch((e) => { console.log(e); message.error('Upload failed.'); }) .finally(() => { setUploading(false); }); }; const [loading, setLoading] = useState(false); const [isReasonModalOpen, setIsReasonModalOpen] = useState(false); const [selectedFileId, setSelectedFileId] = useState(0); const [selectedFileData, setSelectedFileData] = useState(null); const [selectedFileName, setSelectedFileName] = useState(null); const [currentRequest, setCurrentRequest] = useState(null); const [dataSource, setDataSource] = useState([]); const setAndLoadSelectedFile = async (requestData, index) => { setSelectedFileId(index); if (!requestData["Files"][index]) { setSelectedFileData("FAILED_TO_LOAD_FILE"); return; }; const fileName = requestData["Files"][index]["File Name"]; const fileURL = requestData["Files"][index]["File URL"]; 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"); } }; const loadRequestById = (requestID) => { setLoading(true); const requestData = fetchRequest(requestID); requestData.then(async (data) => { if (data) setCurrentRequest(data); const predicted = (data && data["Predicted Result"]) ? data["Predicted 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["revised"] = revised[keys[i]]; tableRows.push(instance); } setDataSource(tableRows); setLoading(false); setAndLoadSelectedFile(data, 0); }).finally(() => { setLoading(false); }); }; const components = { body: { row: EditableRow, cell: EditableCell, }, }; // "Key", "Accuracy", "Revised" interface DataType { key: string; accuracy: number; revised: string; }; const updateRevisedData = async (newRevisedData: any) => { const requestID = currentRequest.RequestID; const token = localStorage.getItem('sbt-token') || ''; 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); message.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, }); setDataSource(newData); const newRevisedData = {}; for (let i = 0; i < newData.length; i++) { newRevisedData[newData[i].key] = newData[i].revised; } updateRevisedData(newRevisedData).then(() => { // "[Is Reviewed]" => true setCurrentRequest({ ...currentRequest, ["Is Reviewed"]: true, }) }) }; const submitRevisedData = async () => { const newData = [...dataSource]; const newRevisedData = {}; for (let i = 0; i < newData.length; i++) { if (newData[i].revised === "") { newData[i].revised = null; } if (typeof(newData[i].revised) === "string") { newData[i].revised = newData[i].revised.trim(); } if (newData[i].revised === "" || newData[i].revised === null || newData[i].revised === undefined) { newData[i].revised = null; } if ((newData[i].key === "imei_number" || newData[i].key === "purchase_date") && typeof(newData[i].revised) === "string") { // Convert to list newData[i].revised = new Array(newData[i].revised.split(",")); } if (Array.isArray(newData[i].revised)) { // Trim all empty strings for (let j = 0; j < newData[i].revised.length; j++) { if (typeof(newData[i].revised[j]) === "string") { newData[i].revised[j] = newData[i].revised[j].trim(); } if (newData[i].revised[j] === "") { newData[i].revised[j] = null; } } } newRevisedData[newData[i].key] = newData[i].revised; } updateRevisedData(newRevisedData).then(() => { // "[Is Reviewed]" => true setCurrentRequest({ ...currentRequest, ["Is Reviewed"]: true, }) }) }; const defaultColumns = [ { title: 'Key', dataIndex: 'key', key: 'key', width: 200, }, { title: 'Predicted', dataIndex: 'predicted', key: 'predicted', render: (text) => { if (!text) return {""}; const displayedContent = text; if (typeof(displayedContent) === "string") { return {displayedContent}; } else if (typeof(displayedContent) === "object") { if (displayedContent.length === 0) { return {""}; } // Set all empty values to "" for (const key in displayedContent) { if (!displayedContent[key]) { displayedContent[key] = ""; } } return {displayedContent.join(", ")}; } return {displayedContent}; }, }, { title: (
Revised   {ENABLE_REVIEW && }
), dataIndex: 'revised', key: 'revised', editable: ENABLE_REVIEW, render: (text) => { if (!text) return {""}; const displayedContent = text; if (typeof(displayedContent) === "string") { return {displayedContent}; } else if (typeof(displayedContent) === "object") { if (displayedContent.length === 0) { return {""}; } // Set all empty values to "" for (const key in displayedContent) { if (!displayedContent[key]) { displayedContent[key] = ""; } } return {displayedContent.join(", ")}; } return {displayedContent}; }, }, ]; const columns = defaultColumns.map((col) => { if (!col.editable) { return col; } return { ...col, onCell: (record: DataType) => ({ record, editable: col.key != "request_id" && col.editable, dataIndex: col.dataIndex, title: col.title, handleSave, }), }; }); const fileExtension = selectedFileName ? selectedFileName.split('.').pop() : ''; return ( <>
{ if (finishedProcessing) return; setInvoiceFiles([]) }} beforeUpload={(file) => { if (finishedProcessing) return; setInvoiceFiles([file]) return false; }} fileList={invoiceFiles} > Invoice:
{ if (finishedProcessing) return; setImei1Files([]) }} beforeUpload={(file) => { if (finishedProcessing) return; setImei1Files([file]) return false; }} fileList={imei1Files} > IMEI 1:
{ if (finishedProcessing) return; setImei2Files([]) }} beforeUpload={(file) => { if (finishedProcessing) return; setImei2Files([file]) return false; }} fileList={imei2Files} > IMEI 2:
{!finishedProcessing && } {finishedProcessing && }
{currentRequest?.Files?.length &&

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

{currentRequest?.Files.map((file, index) => ( { setAndLoadSelectedFile(currentRequest, index); } } setIsReasonModalOpen={setIsReasonModalOpen} /> ))}
} {selectedFileData &&
{selectedFileData === "FAILED_TO_LOAD_FILE" ?

: (fileExtension === "pdf" ? () :
file
)}
}
{currentRequest && (currentRequest["Is Reviewed"] ? } color="success" style={{ padding: "4px 16px" }}> Reviewed : } color="warning" style={{ padding: "4px 16px" }}> Not Reviewed )}
{ } } onCancel={ () => { setIsReasonModalOpen(false); } } >