Merge pull request #12 from SDSRV-IDP/feature/inference
Add inference page
This commit is contained in:
commit
93aee28494
12
cope2n-fe/package-lock.json
generated
12
cope2n-fe/package-lock.json
generated
@ -24,6 +24,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-json-view-lite": "^1.2.1",
|
||||
"react-router-dom": "^6.6.1",
|
||||
"styled-components": "^5.3.6",
|
||||
"uuid": "^9.0.0"
|
||||
@ -10192,6 +10193,17 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/react-json-view-lite": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz",
|
||||
"integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "sbt-ui",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=development npm run extract && npm run compile && vite --host",
|
||||
"start": "NODE_ENV=development vite --host",
|
||||
"build": "NODE_ENV=production npm run extract && npm run compile && tsc && vite build",
|
||||
"serve": "vite preview",
|
||||
"extract": "lingui extract --clean",
|
||||
@ -42,6 +42,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-json-view-lite": "^1.2.1",
|
||||
"react-router-dom": "^6.6.1",
|
||||
"styled-components": "^5.3.6",
|
||||
"uuid": "^9.0.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AppstoreOutlined, BarChartOutlined } from '@ant-design/icons';
|
||||
import { AppstoreOutlined, BarChartOutlined, RotateRightOutlined } from '@ant-design/icons';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Menu, MenuProps } from 'antd';
|
||||
import React from 'react';
|
||||
@ -34,9 +34,9 @@ function LeftMenu() {
|
||||
|
||||
const generalSubItems = [
|
||||
getItem(t`Dashboard`, '/dashboard', <AppstoreOutlined />),
|
||||
// getItem(t`Inference`, '/inference', <RotateRightOutlined />),
|
||||
// getItem(t`Reviews`, '/reviews', <FileSearchOutlined />),
|
||||
getItem(t`Reports`, '/reports', <BarChartOutlined />),
|
||||
getItem(t`Inference`, '/inference', <RotateRightOutlined />),
|
||||
// getItem(t`Users`, '/users', <UsergroupAddOutlined />),
|
||||
];
|
||||
|
||||
|
@ -109,7 +109,7 @@ export const MainLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
<Layout.Sider
|
||||
style={{
|
||||
background: colorBgContainer,
|
||||
padding: 4,
|
||||
padding: 8,
|
||||
borderRight: `1px solid ${colorBorder}`,
|
||||
}}
|
||||
>
|
||||
@ -119,7 +119,7 @@ export const MainLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
style={{
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
padding: 16,
|
||||
padding: 32,
|
||||
background: colorBgContainer,
|
||||
}}
|
||||
>
|
||||
|
@ -7,6 +7,7 @@
|
||||
"Download Report": "Download Report",
|
||||
"Email format is not correct": "Email format is not correct",
|
||||
"English": "English",
|
||||
"Inference": "Inference",
|
||||
"Language": "Language",
|
||||
"Login": "Login",
|
||||
"Logout": "Logout",
|
||||
|
@ -7,6 +7,7 @@
|
||||
"Download Report": "",
|
||||
"Email format is not correct": "Định dạng email không hợp lệ",
|
||||
"English": "Tiếng Anh",
|
||||
"Inference": "",
|
||||
"Language": "Ngôn ngữ",
|
||||
"Login": "Đăng nhập",
|
||||
"Logout": "Đăng xuất",
|
||||
|
@ -1,5 +1,153 @@
|
||||
function Inference() {
|
||||
return <div>Inference</div>;
|
||||
}
|
||||
import { t } from '@lingui/macro';
|
||||
import { Button, message, Upload } from 'antd';
|
||||
import { SbtPageHeader } from 'components/page-header';
|
||||
import { useState } from 'react';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import type { GetProp, UploadFile, UploadProps } from 'antd';
|
||||
import { JsonView, allExpanded, defaultStyles } from 'react-json-view-lite';
|
||||
import 'react-json-view-lite/dist/index.css';
|
||||
import { baseURL } from "request/api"
|
||||
|
||||
export default Inference;
|
||||
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
|
||||
|
||||
const InferencePage = () => {
|
||||
const [invoiceFiles, setInvoiceFiles] = useState<UploadFile[]>([]);
|
||||
const [imei1Files, setImei1Files] = useState<UploadFile[]>([]);
|
||||
const [imei2Files, setImei2Files] = useState<UploadFile[]>([]);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [jsonData, setJsonData] = useState({});
|
||||
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);
|
||||
setJsonData({
|
||||
"message": "Please wait..."
|
||||
})
|
||||
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();
|
||||
setJsonData(data);
|
||||
setFinishedProcessing(true);
|
||||
return data;
|
||||
})
|
||||
.then(() => {
|
||||
message.success('Upload successfully.');
|
||||
})
|
||||
.catch(() => {
|
||||
message.error('Upload failed.');
|
||||
})
|
||||
.finally(() => {
|
||||
setUploading(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SbtPageHeader
|
||||
title={t`Inference`}
|
||||
/>
|
||||
<div style={{
|
||||
paddingTop: "0.5rem"
|
||||
}}>
|
||||
<Upload
|
||||
onRemove={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setInvoiceFiles([])
|
||||
}}
|
||||
beforeUpload={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setInvoiceFiles([file])
|
||||
return false;
|
||||
}}
|
||||
fileList={invoiceFiles}
|
||||
>
|
||||
Invoice File: <Button disabled={finishedProcessing} icon={<UploadOutlined />}>Select Image/PDF</Button>
|
||||
</Upload>
|
||||
</div>
|
||||
<div style={{
|
||||
paddingTop: "0.5rem"
|
||||
}}>
|
||||
<Upload
|
||||
onRemove={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setImei1Files([])
|
||||
}}
|
||||
beforeUpload={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setImei1Files([file])
|
||||
return false;
|
||||
}}
|
||||
fileList={imei1Files}
|
||||
>
|
||||
IMEI File 1: <Button disabled={finishedProcessing} icon={<UploadOutlined />}>Select Image</Button>
|
||||
</Upload>
|
||||
</div>
|
||||
<div style={{
|
||||
paddingTop: "0.5rem"
|
||||
}}>
|
||||
<Upload
|
||||
onRemove={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setImei2Files([])
|
||||
}}
|
||||
beforeUpload={(file) => {
|
||||
if (finishedProcessing) return;
|
||||
setImei2Files([file])
|
||||
return false;
|
||||
}}
|
||||
fileList={imei2Files}
|
||||
>
|
||||
IMEI File 2: <Button disabled={finishedProcessing} icon={<UploadOutlined />}>Select Image</Button>
|
||||
</Upload>
|
||||
</div>
|
||||
{!finishedProcessing && <Button
|
||||
type="primary"
|
||||
onClick={handleUpload}
|
||||
disabled={imei1Files.length === 0 && imei2Files.length === 0}
|
||||
loading={uploading}
|
||||
style={{ marginTop: 16, marginBottom: 24 }}
|
||||
>
|
||||
{uploading ? 'Uploading' : 'Process Data'}
|
||||
</Button>}
|
||||
{finishedProcessing && <Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setFinishedProcessing(false);
|
||||
setJsonData({});
|
||||
setInvoiceFiles([]);
|
||||
setImei1Files([]);
|
||||
setImei2Files([]);
|
||||
}}
|
||||
style={{ marginTop: 16, marginBottom: 24 }}
|
||||
>
|
||||
Reset
|
||||
</Button>}
|
||||
<div style={{
|
||||
paddingTop: "0.5rem"
|
||||
}}>
|
||||
<h3>Result:</h3>
|
||||
<JsonView data={jsonData} shouldExpandNode={allExpanded} style={defaultStyles} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default InferencePage;
|
||||
|
@ -11,18 +11,18 @@ const environment = process.env.NODE_ENV;
|
||||
const AXIOS_TIMEOUT_MS = 30 * 60 * 1000; // This config sastified long-live upload file request
|
||||
const EXPIRED_PASSWORD_SIGNAL = 'expired_password';
|
||||
|
||||
export const baseURL = environment === 'development' ? 'http://42.96.42.13:9000/api' : '/api';
|
||||
|
||||
export const API = axios.create({
|
||||
timeout: AXIOS_TIMEOUT_MS,
|
||||
baseURL:
|
||||
environment === 'development' ? 'http://42.96.42.13:9000/api' : '/api',
|
||||
baseURL: baseURL,
|
||||
maxContentLength: Number.MAX_SAFE_INTEGER,
|
||||
maxBodyLength: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
export const PublicAPI = axios.create({
|
||||
timeout: AXIOS_TIMEOUT_MS,
|
||||
baseURL:
|
||||
environment === 'development' ? 'http://42.96.42.13:9000/api' : '/api',
|
||||
baseURL: baseURL,
|
||||
});
|
||||
|
||||
// interceptor to handle locale header
|
||||
|
Loading…
Reference in New Issue
Block a user