commit
aa686b7367
21
cope2n-fe/Dockerfile
Normal file
21
cope2n-fe/Dockerfile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FROM node:21-alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /app/
|
||||||
|
COPY --chown=node:node package*.json ./
|
||||||
|
RUN npm install -g npm@10.4.0 && npm install
|
||||||
|
COPY --chown=node:node . .
|
||||||
|
RUN npm run build
|
||||||
|
RUN npm cache clean --force
|
||||||
|
USER node
|
||||||
|
|
||||||
|
###################
|
||||||
|
# PRODUCTION
|
||||||
|
###################
|
||||||
|
FROM nginx:stable-alpine AS nginx
|
||||||
|
|
||||||
|
COPY --from=build /app/dist/ /usr/share/nginx/html/
|
||||||
|
COPY --from=build /app/run.sh /app/
|
||||||
|
COPY --from=build /app/nginx.conf /configs/
|
||||||
|
RUN chmod +x /app/run.sh
|
||||||
|
|
||||||
|
CMD ["/app/run.sh"]
|
35
cope2n-fe/nginx.conf
Normal file
35
cope2n-fe/nginx.conf
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
server {
|
||||||
|
# listen {{port}};
|
||||||
|
# listen [::]:{{port}};
|
||||||
|
# server_name localhost;
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location ~ ^/api {
|
||||||
|
proxy_pass {{proxy_server}};
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/drf_spectacular_sidecar/ {
|
||||||
|
alias /backend-static/drf_spectacular_sidecar/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/static/drf_spectacular_sidecar/swagger-ui-dist {
|
||||||
|
proxy_pass {{proxy_server}};
|
||||||
|
}
|
||||||
|
|
||||||
|
# redirect server error pages to the static page /50x.html
|
||||||
|
#
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
cope2n-fe/run.sh
Normal file
5
cope2n-fe/run.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# update port and BD proxy
|
||||||
|
sed "s#{{proxy_server}}#$VITE_PROXY#g" /configs/nginx.conf > /etc/nginx/conf.d/default.conf
|
||||||
|
# run up
|
||||||
|
nginx -g 'daemon off;'
|
@ -30,15 +30,19 @@ const columns: TableColumnsType<DataType> = [
|
|||||||
width: '100px',
|
width: '100px',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
if (record.subSidiaries === '+') return '';
|
if (record.subSidiaries === '+') return '';
|
||||||
return record.subSidiaries;
|
return String(record.subSidiaries).toUpperCase();
|
||||||
},
|
},
|
||||||
filters: [
|
filters: [
|
||||||
{ text: 'all', value: 'all' },
|
{ text: 'ALL', value: 'ALL' },
|
||||||
{ text: 'sesp', value: 'sesp' },
|
{ text: 'SEAU', value: 'SEAU' },
|
||||||
{ text: 'seau', value: 'seau' },
|
{ text: 'SESP', value: 'SESP' },
|
||||||
|
{ text: 'SME', value: 'SME' },
|
||||||
|
{ text: 'SEPCO', value: 'SEPCO' },
|
||||||
|
{ text: 'TSE', value: 'TSE' },
|
||||||
|
{ text: 'SEIN', value: 'SEIN' },
|
||||||
],
|
],
|
||||||
filterMode: 'menu',
|
filterMode: 'menu',
|
||||||
onFilter: (value: string, record) => record.subSidiaries.includes(value),
|
onFilter: (value: string, record) => record.subSidiaries.includes(String(value).toUpperCase()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'OCR extraction date',
|
title: 'OCR extraction date',
|
||||||
@ -216,23 +220,11 @@ const columns: TableColumnsType<DataType> = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
interface ReportOverViewTableProps {
|
interface ReportOverViewTableProps {
|
||||||
pagination: {
|
|
||||||
page: number;
|
|
||||||
page_size: number;
|
|
||||||
};
|
|
||||||
setPagination: React.Dispatch<
|
|
||||||
React.SetStateAction<{
|
|
||||||
page: number;
|
|
||||||
page_size: number;
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReportOverViewTable: React.FC<ReportOverViewTableProps> = ({
|
const ReportOverViewTable: React.FC<ReportOverViewTableProps> = ({
|
||||||
pagination,
|
|
||||||
setPagination,
|
|
||||||
isLoading,
|
isLoading,
|
||||||
data,
|
data,
|
||||||
}) => {
|
}) => {
|
||||||
@ -270,20 +262,6 @@ const ReportOverViewTable: React.FC<ReportOverViewTableProps> = ({
|
|||||||
bordered
|
bordered
|
||||||
size='small'
|
size='small'
|
||||||
scroll={{ x: 2000 }}
|
scroll={{ x: 2000 }}
|
||||||
pagination={{
|
|
||||||
current: pagination.page,
|
|
||||||
pageSize: 10,
|
|
||||||
total: dataSubsRows?.length,
|
|
||||||
// showTotal: (total, range) =>
|
|
||||||
// `${range[0]}-${range[1]} of ${total} items`,
|
|
||||||
onChange: (page, pageSize) => {
|
|
||||||
setPagination({
|
|
||||||
page,
|
|
||||||
page_size: pageSize || 10,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showSizeChanger: false,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -37,15 +37,42 @@ const ReportTable: React.FC = () => {
|
|||||||
title: 'ID',
|
title: 'ID',
|
||||||
dataIndex: 'ID',
|
dataIndex: 'ID',
|
||||||
key: 'ID',
|
key: 'ID',
|
||||||
sorter: (a, b) => a.ID - b.ID,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Created Date',
|
title: 'Report Date',
|
||||||
dataIndex: 'Created Date',
|
dataIndex: 'Created Date',
|
||||||
key: 'Created Date',
|
key: 'Created Date',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return <span>{record['Created Date'].toString().split('T')[0]}</span>;
|
return <span>{record['Created Date'].toString().split('T')[0]}</span>;
|
||||||
},
|
},
|
||||||
|
width: 110,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Start Date',
|
||||||
|
dataIndex: 'Start Date',
|
||||||
|
key: 'Start Date',
|
||||||
|
render: (_, record) => {
|
||||||
|
return <span>{record['Start Date'].toString().split('T')[0]}</span>;
|
||||||
|
},
|
||||||
|
width: 110,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'End Date',
|
||||||
|
dataIndex: 'End Date',
|
||||||
|
key: 'End Date',
|
||||||
|
render: (_, record) => {
|
||||||
|
return <span>{record['End Date'].toString().split('T')[0]}</span>;
|
||||||
|
},
|
||||||
|
width: 110,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Subsidiary',
|
||||||
|
dataIndex: 'Subsidiary',
|
||||||
|
key: 'Subsidiary',
|
||||||
|
render: (_, record) => {
|
||||||
|
return <span>{String(record['Subsidiary']).toUpperCase()}</span>;
|
||||||
|
},
|
||||||
|
width: 110,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'No. Requests',
|
title: 'No. Requests',
|
||||||
@ -149,7 +176,7 @@ const ReportTable: React.FC = () => {
|
|||||||
title: 'Actions',
|
title: 'Actions',
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
width: 200,
|
width: 240,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return (
|
return (
|
||||||
<div style={{ flexDirection: 'row' }}>
|
<div style={{ flexDirection: 'row' }}>
|
||||||
@ -159,7 +186,7 @@ const ReportTable: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
style={{ marginRight: 10 }}
|
style={{ marginRight: 10 }}
|
||||||
>
|
>
|
||||||
Detail
|
Details
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={() => handleDownloadReport(record.report_id)}>
|
<Button onClick={() => handleDownloadReport(record.report_id)}>
|
||||||
Download
|
Download
|
||||||
|
@ -53,6 +53,11 @@ export type ReportListParams = {
|
|||||||
subsidiary?: string;
|
subsidiary?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DashboardOverviewParams = {
|
||||||
|
duration?: string;
|
||||||
|
subsidiary?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export interface MakeReportResponse {
|
export interface MakeReportResponse {
|
||||||
report_id: string;
|
report_id: string;
|
||||||
}
|
}
|
||||||
|
@ -1,112 +1,120 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Button, DatePicker, Form, Select } from 'antd';
|
import { Button, Form, Select } from 'antd';
|
||||||
import { SbtPageHeader } from 'components/page-header';
|
import { SbtPageHeader } from 'components/page-header';
|
||||||
import { ReportOverViewTable } from 'components/report-detail';
|
import { ReportOverViewTable } from 'components/report-detail';
|
||||||
import { Dayjs } from 'dayjs';
|
|
||||||
import { useOverViewReport } from 'queries/report';
|
import { useOverViewReport } from 'queries/report';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { DownloadOutlined } from '@ant-design/icons';
|
||||||
|
import { downloadDashboardReport } from 'request/report';
|
||||||
|
|
||||||
export interface ReportFormValues {
|
export interface ReportFormValues {
|
||||||
dateRange: [Dayjs, Dayjs];
|
duration: string;
|
||||||
subsidiary: string;
|
subsidiary: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [duration, setDuration] = useState<string>('30d');
|
||||||
|
const [subsidiary, setSubsidiary] = useState<string>('ALL');
|
||||||
const [form] = Form.useForm<ReportFormValues>();
|
const [form] = Form.useForm<ReportFormValues>();
|
||||||
const [pagination, setPagination] = useState({
|
|
||||||
page: 1,
|
|
||||||
page_size: 10,
|
|
||||||
});
|
|
||||||
const [fromData, setFormData] = useState<{
|
|
||||||
start_date: string;
|
|
||||||
end_date: string;
|
|
||||||
subsidiary: string;
|
|
||||||
}>({
|
|
||||||
start_date: '',
|
|
||||||
end_date: '',
|
|
||||||
subsidiary: '',
|
|
||||||
});
|
|
||||||
const { isLoading, data } = useOverViewReport({
|
const { isLoading, data } = useOverViewReport({
|
||||||
start_date: fromData.start_date,
|
duration: duration,
|
||||||
end_date: fromData.end_date,
|
subsidiary: subsidiary,
|
||||||
subsidiary: fromData.subsidiary,
|
|
||||||
page: pagination.page,
|
|
||||||
page_size: 30,
|
|
||||||
});
|
});
|
||||||
const handleSubmit = (values: ReportFormValues) => {
|
|
||||||
console.log('check values >>>', values);
|
|
||||||
setFormData({
|
|
||||||
start_date: values.dateRange[0].format('YYYY-MM-DDTHH:mm:ssZ'),
|
|
||||||
end_date: values.dateRange[1].format('YYYY-MM-DDTHH:mm:ssZ'),
|
|
||||||
subsidiary: values.subsidiary,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const handleDownloadReport = async () => {
|
||||||
|
console.log('duration >>>', duration);
|
||||||
|
console.log('subsidiary >>>', subsidiary);
|
||||||
|
const {file, filename} = await downloadDashboardReport(duration, subsidiary);
|
||||||
|
const anchorElement = document.createElement('a');
|
||||||
|
anchorElement.href = URL.createObjectURL(file);
|
||||||
|
anchorElement.download = filename;
|
||||||
|
|
||||||
|
document.body.appendChild(anchorElement);
|
||||||
|
anchorElement.click();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
document.body.removeChild(anchorElement);
|
||||||
|
URL.revokeObjectURL(anchorElement.href);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SbtPageHeader
|
<SbtPageHeader
|
||||||
title={t`Dashboard`}
|
title={t`Dashboard`}
|
||||||
extra={
|
extra={
|
||||||
<>
|
<>
|
||||||
{/* <Button type='primary' icon={<DownloadOutlined />}>
|
<Button type='primary' size='large' icon={<DownloadOutlined />}
|
||||||
Download
|
onClick={() => handleDownloadReport()}
|
||||||
</Button> */}
|
>
|
||||||
{/* <Button type='primary' onClick={() => navigate('/reports')}>
|
{t`Download`}
|
||||||
{t`Go to Report page`}
|
</Button>
|
||||||
</Button> */}
|
<Button type='primary' size='large' onClick={() => navigate('/reports')}>
|
||||||
|
{t`Go to Reports`}
|
||||||
|
</Button>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
style={{ display: 'flex', flexDirection: 'row', gap: 10 }}
|
style={{ display: 'flex', flexDirection: 'row', gap: 10 }}
|
||||||
onFinish={handleSubmit}
|
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name='dateRange'
|
label={t`Duration`}
|
||||||
label={t`Date`}
|
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: 'Please select a date range',
|
message: 'Please select a duration',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
required
|
||||||
>
|
>
|
||||||
<DatePicker.RangePicker />
|
<Select
|
||||||
|
placeholder='Select a date range'
|
||||||
|
style={{ width: 200 }}
|
||||||
|
options={[
|
||||||
|
{ value: '30d', label: 'Last 30 days' },
|
||||||
|
{ value: '7d', label: 'Last 7 days' },
|
||||||
|
]}
|
||||||
|
value={duration}
|
||||||
|
onChange={(value) => {
|
||||||
|
setDuration(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name='subsidiary'
|
name='subsidiary'
|
||||||
label={t`Subsidiary`}
|
label={t`Subsidiary`}
|
||||||
rules={[
|
required
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: 'Please select a subsidiary',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
placeholder='Select a subsidiary'
|
placeholder='Select a subsidiary'
|
||||||
style={{ width: 200 }}
|
style={{ width: 200 }}
|
||||||
options={[
|
options={[
|
||||||
{ value: 'all', label: 'ALL' },
|
{ value: 'ALL', label: 'ALL' },
|
||||||
{ value: 'sesp', label: 'SESP' },
|
{ value: 'SEAU', label: 'SEAU' },
|
||||||
{ value: 'seau', label: 'SEAU' },
|
{ value: 'SESP', label: 'SESP' },
|
||||||
|
{ value: 'SME', label: 'SME' },
|
||||||
|
{ value: 'SEPCO', label: 'SEPCO' },
|
||||||
|
{ value: 'TSE', label: 'TSE' },
|
||||||
|
{ value: 'SEIN', label: 'SEIN' },
|
||||||
]}
|
]}
|
||||||
allowClear
|
defaultValue='ALL'
|
||||||
|
value={subsidiary}
|
||||||
|
onChange={(value) => {
|
||||||
|
setSubsidiary(value);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type='primary' htmlType='submit' style={{ height: 38 }}>
|
<Button type='primary' style={{ height: 38 }}
|
||||||
Submit
|
>
|
||||||
|
View
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
<ReportOverViewTable
|
<ReportOverViewTable
|
||||||
pagination={pagination}
|
|
||||||
setPagination={setPagination}
|
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
data={data}
|
data={data}
|
||||||
/>
|
/>
|
||||||
|
@ -64,6 +64,9 @@ const InferencePage = () => {
|
|||||||
<SbtPageHeader
|
<SbtPageHeader
|
||||||
title={t`Inference`}
|
title={t`Inference`}
|
||||||
/>
|
/>
|
||||||
|
<p>
|
||||||
|
{t`Upload files to process. The requests here will not be used in accuracy or payment calculations.`}
|
||||||
|
</p>
|
||||||
<div style={{
|
<div style={{
|
||||||
paddingTop: "0.5rem"
|
paddingTop: "0.5rem"
|
||||||
}}>
|
}}>
|
||||||
|
@ -105,9 +105,13 @@ const ReportsPage = () => {
|
|||||||
placeholder='Select a subsidiary'
|
placeholder='Select a subsidiary'
|
||||||
style={{ width: 200 }}
|
style={{ width: 200 }}
|
||||||
options={[
|
options={[
|
||||||
{ value: 'all', label: 'ALL' },
|
{ value: 'ALL', label: 'ALL' },
|
||||||
{ value: 'sesp', label: 'SESP' },
|
{ value: 'SEAU', label: 'SEAU' },
|
||||||
{ value: 'seau', label: 'SEAU' },
|
{ value: 'SESP', label: 'SESP' },
|
||||||
|
{ value: 'SME', label: 'SME' },
|
||||||
|
{ value: 'SEPCO', label: 'SEPCO' },
|
||||||
|
{ value: 'TSE', label: 'TSE' },
|
||||||
|
{ value: 'SEIN', label: 'SEIN' },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DownloadOutlined } from '@ant-design/icons';
|
import { DownloadOutlined, ArrowLeftOutlined } from '@ant-design/icons';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@ -271,14 +271,32 @@ const ReportDetail = () => {
|
|||||||
URL.revokeObjectURL(anchorElement.href);
|
URL.revokeObjectURL(anchorElement.href);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
window.history.back();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SbtPageHeader
|
<SbtPageHeader
|
||||||
title={
|
title={
|
||||||
<Tooltip
|
<>
|
||||||
title={id}
|
<Tooltip title={t`Back`}>
|
||||||
style={{ cursor: 'pointer' }}
|
<Button
|
||||||
>{t`Report ${id.slice(0, 16)}...`}</Tooltip>
|
size='middle'
|
||||||
|
type='default'
|
||||||
|
icon={<ArrowLeftOutlined />}
|
||||||
|
onClick={() => handleBack()}
|
||||||
|
style={{
|
||||||
|
marginRight: 10,
|
||||||
|
lineHeight: '1.8',
|
||||||
|
height: 38
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t`Back`}
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
{t`Report Details`}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
extra={
|
extra={
|
||||||
<Button
|
<Button
|
||||||
@ -298,7 +316,6 @@ const ReportDetail = () => {
|
|||||||
{report_data?.metadata?.subsidiary}
|
{report_data?.metadata?.subsidiary}
|
||||||
</span>
|
</span>
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
|
|
||||||
<Typography.Title level={5}>
|
<Typography.Title level={5}>
|
||||||
Start date:{' '}
|
Start date:{' '}
|
||||||
<span style={{ fontWeight: '400' }}>
|
<span style={{ fontWeight: '400' }}>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { ReportListParams } from 'models';
|
import { ReportListParams, DashboardOverviewParams } from 'models';
|
||||||
import {
|
import {
|
||||||
getOverViewReport,
|
getOverViewReport,
|
||||||
getReportDetailList,
|
getReportDetailList,
|
||||||
@ -42,7 +42,7 @@ export function useReportList(params?: ReportListParams, options?: any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useOverViewReport(params?: ReportListParams, options?: any) {
|
export function useOverViewReport(params?: DashboardOverviewParams, options?: any) {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['overview-report', params],
|
queryKey: ['overview-report', params],
|
||||||
queryFn: () => getOverViewReport(params),
|
queryFn: () => getOverViewReport(params),
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
ReportDetailListParams,
|
ReportDetailListParams,
|
||||||
ReportListParams,
|
ReportListParams,
|
||||||
ReportListType,
|
ReportListType,
|
||||||
|
DashboardOverviewParams,
|
||||||
} from 'models';
|
} from 'models';
|
||||||
import { API } from './api';
|
import { API } from './api';
|
||||||
|
|
||||||
@ -68,14 +69,11 @@ export async function getReportList(params?: ReportListParams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOverViewReport(params?: ReportListParams) {
|
export async function getOverViewReport(params?: DashboardOverviewParams) {
|
||||||
try {
|
try {
|
||||||
const response = await API.get<OverViewDataResponse>('/ctel/overview/', {
|
const response = await API.get<OverViewDataResponse>('/ctel/overview/', {
|
||||||
params: {
|
params: {
|
||||||
page: params?.page,
|
duration: params?.duration,
|
||||||
page_size: params?.page_size,
|
|
||||||
start_date: params?.start_date,
|
|
||||||
end_date: params?.end_date,
|
|
||||||
subsidiary: params?.subsidiary,
|
subsidiary: params?.subsidiary,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -104,6 +102,35 @@ export async function downloadReport(report_id: string) {
|
|||||||
const file = new Blob([response.data], {
|
const file = new Blob([response.data], {
|
||||||
type: 'application/vnd.ms-excel',
|
type: 'application/vnd.ms-excel',
|
||||||
});
|
});
|
||||||
|
return {
|
||||||
|
file: file,
|
||||||
|
filename: filename,
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
notification.error({
|
||||||
|
message: `${error?.message}`,
|
||||||
|
});
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function downloadDashboardReport(duration='30d', subsidiary='ALL') {
|
||||||
|
try {
|
||||||
|
const response = await API.get(`/ctel/overview_download_file/?duration=${duration}&subsidiary=${subsidiary}`, {
|
||||||
|
responseType: 'blob', // Important
|
||||||
|
});
|
||||||
|
let filename = "report.xlsx";
|
||||||
|
try {
|
||||||
|
let basename = response.headers['content-disposition'].split('filename=')[1].split('.')[0];
|
||||||
|
let extension = response.headers['content-disposition'].split('.')[1].split(';')[0];
|
||||||
|
filename = `${basename}.${extension}`
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
const file = new Blob([response.data], {
|
||||||
|
type: 'application/vnd.ms-excel',
|
||||||
|
});
|
||||||
// const fileURL = URL.createObjectURL(file);
|
// const fileURL = URL.createObjectURL(file);
|
||||||
// window.open(fileURL);
|
// window.open(fileURL);
|
||||||
return {
|
return {
|
||||||
|
Loading…
Reference in New Issue
Block a user