Merge pull request #164 from SDSRV-IDP/feature/add_filter_review2
Feature/add filter review2
This commit is contained in:
commit
fe56fb91a4
69
cope2n-fe/src/pages/reviews2/DocumentCompareInfo.tsx
Normal file
69
cope2n-fe/src/pages/reviews2/DocumentCompareInfo.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import { Button, Descriptions, Input } from 'antd';
|
||||
import type { DescriptionsProps } from 'antd';
|
||||
import { CopyOutlined } from '@ant-design/icons';
|
||||
import { FEEDBACK_RESULT, PREDICTED_RESULT, REVIEWED_RESULT } from './const';
|
||||
|
||||
const DocumentCompareInfo = ({ key, data, selectedFileDataSource, updateRevisedByFeedback, handleUpdateFileInField, shouldRevised, disabledInput }) => {
|
||||
const items: DescriptionsProps['items'] = [
|
||||
{
|
||||
key: selectedFileDataSource[data]?.[FEEDBACK_RESULT] || '1',
|
||||
label: 'Feedback',
|
||||
children: selectedFileDataSource[data]?.[FEEDBACK_RESULT],
|
||||
labelStyle: { color: '#333', padding: '4px 16px' },
|
||||
contentStyle: { padding: '4px 16px' },
|
||||
span: 3
|
||||
},
|
||||
{
|
||||
key: selectedFileDataSource[data]?.[PREDICTED_RESULT] || '2',
|
||||
label: 'Predicted',
|
||||
children: selectedFileDataSource[data]?.[PREDICTED_RESULT],
|
||||
labelStyle: { color: '#333', padding: '4px 16px' },
|
||||
contentStyle: { padding: '4px 16px' },
|
||||
span: 3
|
||||
},
|
||||
{
|
||||
key: selectedFileDataSource[data]?.[REVIEWED_RESULT] || '3',
|
||||
label: 'Revised',
|
||||
children: <Input
|
||||
style={{ background: shouldRevised ? 'yellow' : '' }}
|
||||
value={selectedFileDataSource[data]?.[REVIEWED_RESULT]}
|
||||
size='small'
|
||||
onChange={(e) =>
|
||||
handleUpdateFileInField(data, e.target.value)
|
||||
}
|
||||
variant="borderless"
|
||||
disabled={disabledInput === undefined || disabledInput === 0}
|
||||
/>,
|
||||
labelStyle: { color: '#333', padding: '4px 16px' },
|
||||
contentStyle: { padding: '4px 16px' },
|
||||
span: 3
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div style={{ margin: '0 0 8px' }} className='file-input-group' key={key}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
margin: '0 0 4px',
|
||||
}}
|
||||
>
|
||||
<p style={{ fontWeight: 'bold', margin: 0 }}>{data}</p>
|
||||
<Button
|
||||
shape='round'
|
||||
type='primary'
|
||||
ghost
|
||||
icon={<CopyOutlined />}
|
||||
size='small'
|
||||
onClick={() => updateRevisedByFeedback(data)}
|
||||
disabled={disabledInput === undefined || disabledInput === 0}
|
||||
/>
|
||||
</div>
|
||||
<Descriptions bordered items={items} layout="horizontal" size='small' contentStyle={{ height: '13px' }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocumentCompareInfo;
|
39
cope2n-fe/src/pages/reviews2/DocumentHeadInfo.tsx
Normal file
39
cope2n-fe/src/pages/reviews2/DocumentHeadInfo.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import { Descriptions } from 'antd';
|
||||
import type { DescriptionsProps } from 'antd';
|
||||
|
||||
const DocumentHeadInfo = ({ currentRequest }) => {
|
||||
const items: DescriptionsProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: 'Request ID',
|
||||
children: currentRequest?.RequestID,
|
||||
span: 2,
|
||||
labelStyle: { color: '#333', width: '200px' }
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: 'Redemption ID',
|
||||
children: currentRequest?.RedemptionID,
|
||||
labelStyle: { color: '#333', width: '200px' }
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: 'Raw accuracy',
|
||||
children: currentRequest?.raw_accuracy,
|
||||
span: 2,
|
||||
labelStyle: { color: '#333', width: '200px' }
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
label: 'Processing time',
|
||||
children: currentRequest?.['Server Processing Time (ms)'],
|
||||
labelStyle: { color: '#333', width: '200px' }
|
||||
}
|
||||
];
|
||||
return (
|
||||
<Descriptions bordered items={items} size="small" />
|
||||
)
|
||||
}
|
||||
|
||||
export default DocumentHeadInfo;
|
@ -10,6 +10,8 @@ export const fetchAllRequests = async (
|
||||
filterFeedbackResult: string,
|
||||
filterPredictResult: string,
|
||||
filterReviewedResult: string,
|
||||
filterBadReason: string,
|
||||
filterOtherReason: string,
|
||||
page = 1,
|
||||
page_size = 20,
|
||||
max_accuracy = 100,
|
||||
@ -42,6 +44,11 @@ export const fetchAllRequests = async (
|
||||
if (filterReviewedResult) {
|
||||
filterStr += `reviewed_result=${filterReviewedResult}&`;
|
||||
}
|
||||
if (filterBadReason === 'other' && filterOtherReason.trim()) {
|
||||
filterStr += `bad_reason=${filterOtherReason}&`;
|
||||
} else if(filterBadReason !== 'other') {
|
||||
filterStr += `bad_reason=${filterBadReason}&`;
|
||||
}
|
||||
//
|
||||
if (startDate && endDate) {
|
||||
filterStr += `start_date=${startDate}&end_date=${endDate}&`;
|
||||
@ -105,7 +112,7 @@ export const fetchRequest = async (id: string) => {
|
||||
});
|
||||
return await (
|
||||
await response.json()
|
||||
).subscription_requests?.[0] || null;
|
||||
).subscription_requests?.[0];
|
||||
};
|
||||
|
||||
export const addRecentRequest = (
|
||||
|
@ -3,7 +3,6 @@ import {
|
||||
ArrowRightOutlined,
|
||||
CheckCircleOutlined,
|
||||
ClockCircleFilled,
|
||||
CopyOutlined,
|
||||
FullscreenExitOutlined,
|
||||
FullscreenOutlined,
|
||||
} from '@ant-design/icons';
|
||||
@ -55,6 +54,8 @@ import {
|
||||
import FileCard from './FileCard';
|
||||
import RecentRequest from './RecentRequest';
|
||||
import './style.css';
|
||||
import DocumentHeadInfo from './DocumentHeadInfo';
|
||||
import DocumentCompareInfo from './DocumentCompareInfo';
|
||||
|
||||
const ReviewPage = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -76,6 +77,9 @@ const ReviewPage = () => {
|
||||
const [filterFeedbackResult, setFilterFeedbackResult] = useState('');
|
||||
const [filterPredictResult, setFilterPredictResult] = useState('');
|
||||
const [filterReviewedResult, setFilterReviewedResult] = useState('');
|
||||
const [filterBadReason, setFilterBadReason] = useState('other');
|
||||
const [filterOtherReason, setFilterOtherReason] = useState('');
|
||||
|
||||
// const [requests, setRequests] = useState([]);
|
||||
const [currentRequest, setCurrentRequest] = useState(null);
|
||||
const [currentRequestIndex, setCurrentRequestIndex] = useState(1);
|
||||
@ -118,6 +122,8 @@ const ReviewPage = () => {
|
||||
filterFeedbackResult,
|
||||
filterPredictResult,
|
||||
filterReviewedResult,
|
||||
filterBadReason,
|
||||
filterOtherReason,
|
||||
1,
|
||||
1,
|
||||
filterAccuracy,
|
||||
@ -125,7 +131,7 @@ const ReviewPage = () => {
|
||||
setTotalPages(data?.page?.total_requests);
|
||||
setHasNextRequest(1 < data?.page?.total_requests);
|
||||
const firstRequest = fetchRequest(
|
||||
data?.subscription_requests[0].RequestID,
|
||||
data?.subscription_requests?.[0]?.RequestID,
|
||||
);
|
||||
firstRequest.then(async (data) => {
|
||||
if (data) setCurrentRequest(data);
|
||||
@ -231,6 +237,8 @@ const ReviewPage = () => {
|
||||
filterFeedbackResult,
|
||||
filterPredictResult,
|
||||
filterReviewedResult,
|
||||
filterBadReason,
|
||||
filterOtherReason,
|
||||
requestIndex,
|
||||
1,
|
||||
filterAccuracy,
|
||||
@ -290,6 +298,8 @@ const ReviewPage = () => {
|
||||
filterFeedbackResult,
|
||||
filterPredictResult,
|
||||
filterReviewedResult,
|
||||
filterBadReason,
|
||||
filterOtherReason,
|
||||
1,
|
||||
1,
|
||||
filterAccuracy,
|
||||
@ -491,42 +501,10 @@ const ReviewPage = () => {
|
||||
>
|
||||
{fullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
|
||||
</Button>
|
||||
{totalRequests && (
|
||||
<div
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr 1fr',
|
||||
marginLeft: '16px',
|
||||
}}
|
||||
>
|
||||
<div style={{ gridColumn: 'span 2 / span 2' }}>
|
||||
<b>Request ID: </b>
|
||||
{currentRequest?.RequestID}
|
||||
</div>{' '}
|
||||
<div>
|
||||
<b>Created at: </b>
|
||||
{currentRequest?.created_at}
|
||||
</div>{' '}
|
||||
<div>
|
||||
<b>Request time: </b>
|
||||
{currentRequest?.['Client Request Time (ms)']}
|
||||
</div>{' '}
|
||||
<div style={{ gridColumn: 'span 2 / span 2' }}>
|
||||
<b>Redemption ID: </b>
|
||||
{currentRequest?.RedemptionID}
|
||||
</div>{' '}
|
||||
<div>
|
||||
<b>Raw accuracy: </b>
|
||||
{currentRequest?.raw_accuracy}
|
||||
</div>{' '}
|
||||
<div style={{ gridColumn: 'span 2 / span 2' }}>
|
||||
<b>Processing time: </b>
|
||||
{currentRequest?.['Server Processing Time (ms)']}
|
||||
</div>{' '}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{totalRequests && (
|
||||
<DocumentHeadInfo currentRequest={currentRequest} />
|
||||
)}
|
||||
{totalRequests > 0 && (
|
||||
<div
|
||||
style={{
|
||||
@ -787,47 +765,14 @@ const ReviewPage = () => {
|
||||
}
|
||||
} catch (error) { }
|
||||
return (
|
||||
<div style={{ margin: '0 0 8px' }} className='file-input-group' key={data}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
margin: '0 0 4px',
|
||||
}}
|
||||
>
|
||||
<p style={{ fontWeight: 'bold', margin: 0 }}>{data}</p>
|
||||
<Button
|
||||
shape='round'
|
||||
type='primary'
|
||||
ghost
|
||||
icon={<CopyOutlined />}
|
||||
size='small'
|
||||
onClick={() => updateRevisedByFeedback(data)}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
addonBefore='Feedback'
|
||||
size='small'
|
||||
readOnly
|
||||
value={selectedFileDataSource[data]?.[FEEDBACK_RESULT]}
|
||||
/>
|
||||
<Input
|
||||
addonBefore='Predicted'
|
||||
readOnly
|
||||
size='small'
|
||||
value={selectedFileDataSource[data]?.[PREDICTED_RESULT]}
|
||||
/>
|
||||
<Input
|
||||
addonBefore='Revised'
|
||||
style={{ background: shouldRevised ? 'yellow' : '' }}
|
||||
size='small'
|
||||
value={selectedFileDataSource[data]?.[REVIEWED_RESULT]}
|
||||
onChange={(e) =>
|
||||
handleUpdateFileInField(data, e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<DocumentCompareInfo key={data}
|
||||
data={data}
|
||||
selectedFileDataSource={selectedFileDataSource}
|
||||
updateRevisedByFeedback={updateRevisedByFeedback}
|
||||
handleUpdateFileInField={handleUpdateFileInField}
|
||||
shouldRevised={shouldRevised}
|
||||
disabledInput = {currentRequest?.Files?.length}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<b>{t`Bad image reason:`}</b>
|
||||
@ -919,31 +864,75 @@ const ReviewPage = () => {
|
||||
style={{
|
||||
marginTop: 30,
|
||||
}}
|
||||
layout="vertical"
|
||||
>
|
||||
<Form.Item
|
||||
name='dateRange'
|
||||
label={t`Date (GMT+8)`}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: 'Please select a date range',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
<DatePicker.RangePicker
|
||||
onChange={(date, dateString) => {
|
||||
setFilterDateRange(dateString);
|
||||
}}
|
||||
style={{ width: 200 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginLeft: 0,
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
name='dateRange'
|
||||
label={t`Date (GMT+8)`}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: 'Please select a date range',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<DatePicker.RangePicker
|
||||
onChange={(date, dateString) => {
|
||||
setFilterDateRange(dateString);
|
||||
}}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
}}>
|
||||
<Form.Item
|
||||
name='bad_reason'
|
||||
label={t`Bad image reason`}
|
||||
>
|
||||
<Select
|
||||
placeholder='Select a reason'
|
||||
style={{ width: 300 }}
|
||||
options={REASON_BAD_QUALITY}
|
||||
value={filterBadReason}
|
||||
defaultValue={filterBadReason}
|
||||
onChange={setFilterBadReason}
|
||||
/>
|
||||
</Form.Item>
|
||||
{filterBadReason === 'other' && (
|
||||
<Form.Item
|
||||
name='other_reason'
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
placeholder='Other reason'
|
||||
value={filterOtherReason}
|
||||
style={{ width: 300 }}
|
||||
onChange={(e) => {
|
||||
setFilterOtherReason(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginLeft: 0,
|
||||
@ -959,10 +948,13 @@ const ReviewPage = () => {
|
||||
message: 'Please select a subsidiary',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
placeholder='Select a subsidiary'
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 300 }}
|
||||
options={SUBSIDIARIES}
|
||||
value={filterSubsidiaries}
|
||||
defaultValue={filterSubsidiaries}
|
||||
@ -978,8 +970,12 @@ const ReviewPage = () => {
|
||||
message: 'Please select max accuracy',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<InputNumber
|
||||
style={{ width: 300 }}
|
||||
min={1}
|
||||
max={100}
|
||||
defaultValue={filterAccuracy}
|
||||
@ -989,7 +985,7 @@ const ReviewPage = () => {
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginLeft: 0,
|
||||
@ -1005,9 +1001,12 @@ const ReviewPage = () => {
|
||||
message: 'Please select review status',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 300 }}
|
||||
options={[
|
||||
{ label: 'All', value: 'all' },
|
||||
{ label: 'Reviewed', value: 'reviewed' },
|
||||
@ -1027,10 +1026,10 @@ const ReviewPage = () => {
|
||||
message: 'Please select test status',
|
||||
},
|
||||
]}
|
||||
style={{ marginLeft: 16 }}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<Select
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 300 }}
|
||||
options={[
|
||||
{ label: 'Include tests', value: 'true' },
|
||||
{ label: 'Exclude tests', value: 'false' },
|
||||
@ -1044,7 +1043,7 @@ const ReviewPage = () => {
|
||||
{/* add 4 more filter fields */}
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginLeft: 0,
|
||||
@ -1054,16 +1053,13 @@ const ReviewPage = () => {
|
||||
<Form.Item
|
||||
name='doc_type'
|
||||
label={t`Only type`}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: 'Please select a document type',
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
placeholder='Select a document type'
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 300 }}
|
||||
options={DOCTYPE}
|
||||
value={filterDoctype}
|
||||
defaultValue={filterDoctype}
|
||||
@ -1073,8 +1069,12 @@ const ReviewPage = () => {
|
||||
<Form.Item
|
||||
name='feedback_result'
|
||||
label={t`Feedback includes`}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
style={{ width: 300 }}
|
||||
defaultValue={filterFeedbackResult}
|
||||
onChange={(e) => setFilterFeedbackResult(e.target.value)}
|
||||
/>
|
||||
@ -1082,7 +1082,7 @@ const ReviewPage = () => {
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginLeft: 0,
|
||||
@ -1092,17 +1092,25 @@ const ReviewPage = () => {
|
||||
<Form.Item
|
||||
name='predict_result'
|
||||
label={t`Predict includes`}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
style={{ width: 300 }}
|
||||
defaultValue={filterPredictResult}
|
||||
onChange={(e) => setFilterPredictResult(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name='reviewed_result'
|
||||
label={t`Review inculdes`}
|
||||
label={t`Review includes`}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
style={{ width: 300 }}
|
||||
defaultValue={filterReviewedResult}
|
||||
onChange={(e) => setFilterReviewedResult(e.target.value)}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user