This commit is contained in:
Viet Anh Nguyen 2024-03-06 11:43:11 +07:00
parent 19c799cfc4
commit 451381d5d7
4 changed files with 337 additions and 44 deletions

View File

@ -14,6 +14,8 @@
"@ant-design/pro-layout": "^7.10.3",
"@babel/core": "^7.13.10",
"@cyntler/react-doc-viewer": "^1.14.1",
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/default-layout": "^3.12.0",
"@tanstack/react-query": "^4.20.4",
"antd": "^5.4.0",
"axios": "^1.2.2",
@ -21,6 +23,7 @@
"history": "^5.3.0",
"lodash-es": "^4.17.21",
"mousetrap": "^1.6.5",
"pdfjs-dist": "^3.11.174",
"process": "^0.11.10",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",
@ -3939,6 +3942,236 @@
"react-dom": ">=16.9.0"
}
},
"node_modules/@react-pdf-viewer/attachment": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/attachment/-/attachment-3.12.0.tgz",
"integrity": "sha512-mhwrYJSIpCvHdERpLUotqhMgSjhtF+BTY1Yb9Fnzpcq3gLZP+Twp5Rynq21tCrVdDizPaVY7SKu400GkgdMfZw==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/bookmark": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/bookmark/-/bookmark-3.12.0.tgz",
"integrity": "sha512-i7nEit8vIFMAES8RFGwprZ9cXOOZb9ZStPW6E6yuObJEXcvBj/ctsbBJGZxqUZOGklM0JoB7sjHyxAriHfe92A==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/core": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/core/-/core-3.12.0.tgz",
"integrity": "sha512-8MsdlQJ4jaw3GT+zpCHS33nwnvzpY0ED6DEahZg9WngG++A5RMhk8LSlxdHelwaFFHFiXBjmOaj2Kpxh50VQRg==",
"peerDependencies": {
"pdfjs-dist": "^2.16.105 || ^3.0.279",
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/default-layout": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/default-layout/-/default-layout-3.12.0.tgz",
"integrity": "sha512-K2fS4+TJynHxxCBFuIDiFuAw3nqOh4bkBgtVZ/2pGvnFn9lLg46YGLMnTXCQqtyZzzXYh696jmlFViun3is4pA==",
"dependencies": {
"@react-pdf-viewer/attachment": "3.12.0",
"@react-pdf-viewer/bookmark": "3.12.0",
"@react-pdf-viewer/core": "3.12.0",
"@react-pdf-viewer/thumbnail": "3.12.0",
"@react-pdf-viewer/toolbar": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/full-screen": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/full-screen/-/full-screen-3.12.0.tgz",
"integrity": "sha512-hQouJ26QUaRBCXNMU1aI1zpJn4l4PJRvlHhuE2dZYtLl37ycjl7vBCQYZW1FwnuxMWztZsY47R43DKaZORg0pg==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/get-file": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/get-file/-/get-file-3.12.0.tgz",
"integrity": "sha512-Uhq45n2RWlZ7Ec/BtBJ0WQESRciaYIltveDXHNdWvXgFdOS8XsvB+mnTh/wzm7Cfl9hpPyzfeezifdU9AkQgQg==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/open": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/open/-/open-3.12.0.tgz",
"integrity": "sha512-vhiDEYsiQLxvZkIKT9VPYHZ1BOnv46x9eCEmRWxO1DJ8fa/GRDTA9ivXmq/ap0dGEJs6t+epleCkCEfllLR/Yw==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/page-navigation": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/page-navigation/-/page-navigation-3.12.0.tgz",
"integrity": "sha512-tVEJ48Dd5kajV1nKkrPWijglJRNBiKBTyYDKVexhiRdTHUP1f6QQXiSyDgCUb0IGSZeJzOJb1h7ApKHe8OTtuw==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/print": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/print/-/print-3.12.0.tgz",
"integrity": "sha512-xJn76CgbU/M2iNaN7wLHTg+sdOekkRMfCakFLwPrE+SR7qD6NUF4vQQKJBSVCCK5bUijzb6cWfKGfo8VA72o4Q==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/properties": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/properties/-/properties-3.12.0.tgz",
"integrity": "sha512-dYTCHtVwFNkpDo7QxL2qk/8zAKndLwdD1FFxBftl6jIlQbtvNdxkFfkv1HcQING9Ic+7DBryOiD7W0ze4IERYg==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/rotate": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/rotate/-/rotate-3.12.0.tgz",
"integrity": "sha512-yaxaMYPChvNOjR8+AxRmj0kvojyJKPq4XHEcIB2lJJgBY1Zra3mliDUP3Nlb4yV8BS9+yBqWn9U9mtnopQD+tw==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/scroll-mode": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/scroll-mode/-/scroll-mode-3.12.0.tgz",
"integrity": "sha512-okII7Xqhl6cMvl1izdEvlXNJ+vJVq/qdg53hJIDYVgBCWskLk/cpjUg/ZonBxseG9lIDP3w2VO1McT8Gn11OAg==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/search": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/search/-/search-3.12.0.tgz",
"integrity": "sha512-jAkLpis49fsDDY/HrbUZIOIhzF5vynONQNA4INQKI38r/MjveblrkNv7qbr9j5lQ/WFic5+gD1e+Mtpf1/7DiA==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/selection-mode": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/selection-mode/-/selection-mode-3.12.0.tgz",
"integrity": "sha512-yysWEu2aCtBvzSgbhgI9kT5cq2hf0FU6Z+3B7MMXz14Kxyc3y18wUqxtgbvpFEfWF0bNUUq16JtWRljtxvZ83w==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/theme": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/theme/-/theme-3.12.0.tgz",
"integrity": "sha512-cdBi+wR1VOZ6URCcO9plmAZQu4ZGFcd7HJdBe7VIFiGyrvl9I/Of74ONLycnDImSuONt8D3uNjPBLieeaShVeg==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/thumbnail": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/thumbnail/-/thumbnail-3.12.0.tgz",
"integrity": "sha512-Vc8j3bO6wumWZV4o6pAbktPWKDSC9tQAzOCJ3cof541u4i44C11ccYC4W9aNcsMMUSO3bNwAGWtP8OFthV5akQ==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/toolbar": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/toolbar/-/toolbar-3.12.0.tgz",
"integrity": "sha512-qACTU3qXHgtNK8J+T13EWio+0liilj86SJ87BdapqXynhl720OKPlSKOQqskUGqg3oTUJAhrse9XG6SFdHJx+g==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0",
"@react-pdf-viewer/full-screen": "3.12.0",
"@react-pdf-viewer/get-file": "3.12.0",
"@react-pdf-viewer/open": "3.12.0",
"@react-pdf-viewer/page-navigation": "3.12.0",
"@react-pdf-viewer/print": "3.12.0",
"@react-pdf-viewer/properties": "3.12.0",
"@react-pdf-viewer/rotate": "3.12.0",
"@react-pdf-viewer/scroll-mode": "3.12.0",
"@react-pdf-viewer/search": "3.12.0",
"@react-pdf-viewer/selection-mode": "3.12.0",
"@react-pdf-viewer/theme": "3.12.0",
"@react-pdf-viewer/zoom": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@react-pdf-viewer/zoom": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/zoom/-/zoom-3.12.0.tgz",
"integrity": "sha512-V0GUTyPM77+LzhoKX+T3XI10/HfGdqRTbgeP7ID60FCzcwu6kXWqJn5tzabjDKLTlFv8mJmn0aa/ppkIU97nfA==",
"dependencies": {
"@react-pdf-viewer/core": "3.12.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@remix-run/router": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",

View File

@ -32,6 +32,8 @@
"@ant-design/pro-layout": "^7.10.3",
"@babel/core": "^7.13.10",
"@cyntler/react-doc-viewer": "^1.14.1",
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/default-layout": "^3.12.0",
"@tanstack/react-query": "^4.20.4",
"antd": "^5.4.0",
"axios": "^1.2.2",
@ -39,6 +41,7 @@
"history": "^5.3.0",
"lodash-es": "^4.17.21",
"mousetrap": "^1.6.5",
"pdfjs-dist": "^3.11.174",
"process": "^0.11.10",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",

View File

@ -6,6 +6,7 @@ import { queryClient } from 'queries';
import { Suspense } from 'react';
import { createRoot } from 'react-dom/client';
import AppRoutes from 'routes';
import { Worker } from '@react-pdf-viewer/core';
import 'antd/dist/reset.css';
import './theme/compose.scss';
@ -16,7 +17,9 @@ function App() {
<QueryClientProvider client={queryClient}>
<Internationalization>
{/* <AbilityContext.Provider value={appAbilitiy}> */}
<Worker workerUrl="https://unpkg.com/pdfjs-dist@3.11.174/build/pdf.worker.min.js">
<AppRoutes />
</Worker>
{/* </AbilityContext.Provider> */}
</Internationalization>
<ReactQueryDevtools initialIsOpen={false} />

View File

@ -11,12 +11,15 @@ import {
FullscreenExitOutlined,
ClockCircleFilled,
} from '@ant-design/icons';
import FileViewer from '@cyntler/react-doc-viewer';
import styled from 'styled-components';
const { Sider, Content } = Layout;
import { baseURL } from "request/api";
import moment from 'moment';
import { useHotkeys } from "react-hotkeys-hook";
// Import the main component
import { Viewer } from '@react-pdf-viewer/core';
// Import the styles
import '@react-pdf-viewer/core/lib/styles/index.css';
const siderStyle: React.CSSProperties = {
@ -133,32 +136,6 @@ const EditableCell: React.FC<EditableCellProps> = ({
// type EditableTableProps = Parameters<typeof Table>[0];
const defaultColumns = [
{
title: 'Key',
dataIndex: 'key',
key: 'key',
width: 200,
},
{
title: 'Predicted',
dataIndex: 'predicted',
key: 'predicted',
},
{
title: 'Submitted',
dataIndex: 'submitted',
key: 'submitted',
},
{
title: 'Revised',
dataIndex: 'revised',
key: 'revised',
editable: true,
},
];
const FileCard = ({ file, isSelected, onClick, setIsReasonModalOpen }) => {
const fileName = file["File Name"];
@ -311,9 +288,9 @@ const ReviewPage = () => {
}
};
const loadCurrentRequest = (requestID) => {
const loadCurrentRequest = (requestIndex) => {
setLoading(true);
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, requestID, 2).then((data) => {
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, requestIndex, 1).then((data) => {
setRequests(data?.subscription_requests);
setHasNextRequest(data?.subscription_requests.length > 1);
setTotalPages(data?.page?.total_requests);
@ -364,7 +341,7 @@ const ReviewPage = () => {
const reloadFilters = () => {
setCurrentRequestIndex(1);
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, currentRequestIndex, 2).then((data) => {
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, 1, 2).then((data) => {
setTotalPages(data?.page?.total_requests);
setRequests(data?.subscription_requests);
setHasNextRequest(data?.subscription_requests.length > 1);
@ -372,6 +349,9 @@ const ReviewPage = () => {
firstRequest.then(async (data) => {
if (data) setCurrentRequest(data);
setAndLoadSelectedFile(data, 0);
setTimeout(() => {
loadCurrentRequest(1);
}, 500);
});
});
@ -379,7 +359,7 @@ const ReviewPage = () => {
useEffect(() => {
setCurrentRequestIndex(1);
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, currentRequestIndex, 2).then((data) => {
fetchAllRequests(filterDateRange, filterSubsidiaries, filterReviewState, filterIncludeTests, 1, 2).then((data) => {
setTotalPages(data?.page?.total_requests);
setRequests(data?.subscription_requests);
setHasNextRequest(data?.subscription_requests.length > 1);
@ -446,6 +426,89 @@ const ReviewPage = () => {
})
};
const submitRevisedData = async () => {
const newData = [...dataSource];
const newRevisedData = {};
for (let i = 0; i < newData.length; i++) {
newRevisedData[newData[i].key] = newData[i].revised;
}
console.log(currentRequest)
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',
},
{
title: 'Submitted',
dataIndex: 'submitted',
key: 'submitted',
},
{
title: (<div style={{
width: 120,
display: 'flex',
lineHeight: '32px',
marginLeft: 10,
}}>Revised&nbsp;&nbsp;
<Button
onClick={() => {
if (!dataSource || !dataSource.length) return;
setDataSource(dataSource.map(item => {
item.revised = item.predicted;
return item;
}));
setTimeout(() => {
submitRevisedData();
}, 1000);
}}
>
Copy Predicted
</Button>
<Button
onClick={() => {
if (!dataSource || !dataSource.length) return;
setDataSource(dataSource.map(item => {
item.revised = item.submitted;
return item;
}));
setTimeout(() => {
submitRevisedData();
}, 1000);
}}
>
Copy Submitted
</Button>
</div>),
dataIndex: 'revised',
key: 'revised',
editable: true,
render: (text, record) => {
return <div style={{
color: '#000',
fontWeight: 'bold',
}}>{text}</div>;
},
},
];
const columns = defaultColumns.map((col) => {
if (!col.editable) {
return col;
@ -549,17 +612,9 @@ const ReviewPage = () => {
flexGrow: 1,
height: '100%',
}}>
{selectedFileData === "FAILED_TO_LOAD_FILE" ? <p style={{ color: "#333" }}>Failed to load file.</p> : ( fileExtension === "pdf" ? (<FileViewer documents={[
{ uri: selectedFileData }
]} config={{
header: {
disableHeader: true,
disableFileName: true,
retainURLParams: true,
},
csvDelimiter: ",", // "," as default,
pdfVerticalScrollByDefault: true, // false as default
}} />) : <div style={{
{selectedFileData === "FAILED_TO_LOAD_FILE" ? <p style={{ color: "#333" }}>Failed to load file.</p> : (fileExtension === "pdf" ? (<Viewer
fileUrl={selectedFileData}
/>) : <div style={{
height: "100%",
width: "100%",
overflow: "auto",
@ -777,7 +832,6 @@ const ReviewPage = () => {
}
}
>
{currentRequest && JSON.stringify(currentRequest["Files"][selectedFileId])}
<Form
style={{
marginTop: 30,