Wahyu Ramadhan
2 years ago
6 changed files with 420 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,397 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import axios from "../../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Button, Table, Form, Upload, Tooltip, Alert, Spin } from 'antd'; |
||||
import { InboxOutlined, UploadOutlined } from '@ant-design/icons'; |
||||
import {OutTable, ExcelRenderer} from 'react-excel-renderer'; |
||||
import './table.css'; |
||||
import { BASE_OSPRO } from '../../../../const/ApiConst'; |
||||
import { Prompt } from 'react-router-dom'; |
||||
//
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
//const token = window.localStorage.getItem('token');
|
||||
const token = localStorage.getItem("token"); |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
Authorization: `Bearer ${token}`, |
||||
}, |
||||
}; |
||||
|
||||
const normFile = (e) => { |
||||
if (Array.isArray(e)) { |
||||
return e; |
||||
} |
||||
|
||||
return e?.fileList; |
||||
}; |
||||
|
||||
const formItemLayout = { |
||||
labelCol: { |
||||
span: 6, |
||||
}, |
||||
wrapperCol: { |
||||
span: 14, |
||||
}, |
||||
}; |
||||
|
||||
const errorHandler = { |
||||
// error notif
|
||||
// reload table
|
||||
// reload upload
|
||||
}; |
||||
|
||||
const columnToIndexs = { |
||||
columnName: 'index', |
||||
level: 0, |
||||
predecessor: 1, |
||||
no: 2, |
||||
name: 3, |
||||
weight: 4, |
||||
start_date: 5, |
||||
end_date: 6, |
||||
picKit: 7, |
||||
picOwner: 8, |
||||
duration: 9 |
||||
} |
||||
|
||||
const ExcelDateToJSDate = (date) => { |
||||
let converted_date = new Date(Math.round((date - 25569) * 864e5)); |
||||
converted_date = String(converted_date).slice(4, 15) |
||||
date = converted_date.split(" ") |
||||
let day = date[1]; |
||||
let month = date[0]; |
||||
month = "JanFebMarAprMayJunJulAugSepOctNovDec".indexOf(month) / 3 + 1 |
||||
if (month.toString().length <= 1) |
||||
month = '0' + month |
||||
let year = date[2]; |
||||
return String(day + '-' + month + '-' + year.slice(2, 4)) |
||||
} |
||||
|
||||
const ImportActivity = ({ params }) => { |
||||
const pageName = params.name; |
||||
|
||||
const [dataTable, setDatatable] = useState([]) |
||||
//
|
||||
const [isMovePage, setIsMovePage] = useState(false); |
||||
const [isPreview, setIsPreview] = useState(false); |
||||
|
||||
const fileHandler = (file) => { |
||||
setIsMovePage(true); |
||||
if(file.name.slice(file.name.lastIndexOf('.')+1) === "xlsx"){ |
||||
// NotificationManager.info('Loading...',' ');
|
||||
setTimeout(() => {
|
||||
previewHandler(file); |
||||
setIsMovePage(false); |
||||
}, 5000); |
||||
} else { |
||||
NotificationManager.error('file harus dalam format .xlsx', 'Failed'); |
||||
} |
||||
// else{
|
||||
// errorHandler()
|
||||
// }
|
||||
return false |
||||
} |
||||
|
||||
const previewHandler = (fileObj) => { |
||||
let dataMapped = [] |
||||
|
||||
ExcelRenderer(fileObj, (err, resp) => { |
||||
if(err){ |
||||
console.log(err) |
||||
errorHandler() |
||||
} else { |
||||
// let columns = resp.cols
|
||||
let rawRows = resp.rows |
||||
|
||||
let rows = rawRows.filter(function (el) { |
||||
return el.length > 0; |
||||
}); |
||||
|
||||
for(let i = 5; i < rows.length; i++){ |
||||
let extractedRow = {} |
||||
|
||||
for (var prop in columnToIndexs) { |
||||
if (columnToIndexs.hasOwnProperty.call(columnToIndexs, prop)) { |
||||
let columnData = rows[i][columnToIndexs[prop]] |
||||
|
||||
// remove leading whitespace
|
||||
if(typeof(columnData) == 'string') { |
||||
columnData = columnData.trim().replace(/ /g, '').replace(/<[^\/>][^>]*><\/[^>]+>/g, "") |
||||
} |
||||
|
||||
// convert excel's DATEVALUE
|
||||
if(["start_date", "end_date"].includes(prop)){ |
||||
columnData = ExcelDateToJSDate(columnData) |
||||
} |
||||
|
||||
if(prop == 'weight'){ |
||||
columnData = Math.round(columnData * 100) |
||||
} |
||||
|
||||
extractedRow[prop] = columnData |
||||
|
||||
} |
||||
} |
||||
|
||||
dataMapped.push(extractedRow) |
||||
} |
||||
|
||||
setDatatable(dataMapped) |
||||
setIsPreview(true) |
||||
} |
||||
}); |
||||
|
||||
} |
||||
|
||||
const saveHandler = async (e) => { |
||||
setIsMovePage(true); |
||||
|
||||
let url = window.location.href; |
||||
let urlSplitted = url.split('/') |
||||
const ganttId = urlSplitted[5] |
||||
|
||||
const URL = `${BASE_OSPRO}/api/activity/import` |
||||
|
||||
let payload = { |
||||
ganttId: ganttId, |
||||
activities: dataTable |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(URL, payload, HEADER) |
||||
.then((res) => res) |
||||
.catch((error) => error.response); |
||||
|
||||
console.log(result) |
||||
if (result.data.code == 200) { |
||||
window.location = urlSplitted[0] + '//' + urlSplitted[2] + `/#/projects/` + ganttId + '/' + result.data.projectId + '/gantt' |
||||
} |
||||
|
||||
setIsMovePage(true); |
||||
|
||||
} |
||||
|
||||
const columns = [ |
||||
{ |
||||
title: 'No', |
||||
dataIndex: 'no', |
||||
key: 'no', |
||||
width: '5%', |
||||
}, |
||||
{ |
||||
title: 'Level', |
||||
dataIndex: 'level', |
||||
key: 'level', |
||||
width: '10%', |
||||
align: 'center', |
||||
|
||||
}, |
||||
{ |
||||
title: 'Predecessor', |
||||
dataIndex: 'predecessor', |
||||
key: 'predecessor', |
||||
align: 'center', |
||||
}, |
||||
{ |
||||
title: 'Name', |
||||
dataIndex: 'name', |
||||
key: 'name', |
||||
render: (text, record) => { |
||||
let prepend = "" |
||||
for(let i = 1; i < record.level; i++) { |
||||
prepend = prepend + "--" |
||||
} |
||||
|
||||
return <Tooltip title={text}><span> {prepend} {text}</span></Tooltip> |
||||
}, |
||||
ellipsis: true, |
||||
width: '25%', |
||||
}, |
||||
{ |
||||
title: 'Weight', |
||||
dataIndex: 'weight', |
||||
key: 'weight', |
||||
render: (text, record) => { |
||||
return <span>{text}%</span> |
||||
}, |
||||
width: '10%', |
||||
align: 'center', |
||||
}, |
||||
{ |
||||
title: 'Start Date', |
||||
dataIndex: 'start_date', |
||||
key: 'start_date', |
||||
}, |
||||
{ |
||||
title: 'Finish Date', |
||||
dataIndex: 'end_date', |
||||
key: 'end_date', |
||||
}, |
||||
{ |
||||
title: 'Duration', |
||||
dataIndex: 'duration', |
||||
key: 'duration', |
||||
align: 'right', |
||||
}, |
||||
{ |
||||
title: 'PIC KIT', |
||||
dataIndex: 'picKit', |
||||
key: 'picKit', |
||||
}, |
||||
{ |
||||
title: 'PIC Owner', |
||||
dataIndex: 'picOwner', |
||||
key: 'picOwner', |
||||
}, |
||||
]; |
||||
|
||||
if (isMovePage) { |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<div> |
||||
<Row> |
||||
<Col span={22}> |
||||
<Form |
||||
name="import_preview" |
||||
{...formItemLayout} |
||||
> |
||||
<Form.Item |
||||
name="upload" |
||||
valuePropName="fileList" |
||||
getValueFromEvent={normFile} |
||||
extra="" |
||||
> |
||||
<Button |
||||
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||
href={"/template/template_activity.xlsx"} |
||||
> |
||||
<i className="fa fa-print" style={{ marginRight: "5px" }}></i> Download Template |
||||
</Button> |
||||
<Tooltip title="Format file .xlsx"> |
||||
<Upload |
||||
name="template" |
||||
listType="text" |
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
||||
maxCount={1} |
||||
beforeUpload={(file)=> fileHandler(file)} |
||||
showUploadList={false} |
||||
> |
||||
<Button icon={<UploadOutlined />}>Import Excel</Button> |
||||
</Upload> |
||||
</Tooltip> |
||||
</Form.Item> |
||||
</Form> |
||||
</Col> |
||||
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}> |
||||
<Button |
||||
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||
disabled={dataTable.length > 0 ? false : true} |
||||
onClick={(e)=> saveHandler(e)} |
||||
> |
||||
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">Data Preview</h4> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Spin tip="Loading..."> |
||||
<Table |
||||
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'} |
||||
dataSource={dataTable} |
||||
columns={columns} |
||||
pagination={false} |
||||
/> |
||||
</Spin> |
||||
</CardBody> |
||||
</Card> |
||||
<Prompt |
||||
when={isPreview} |
||||
message={() => 'Import Activity belum disave ingin meninggalkan halaman ini?'} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<div> |
||||
<Row> |
||||
<Col span={22}> |
||||
<Form |
||||
name="import_preview" |
||||
{...formItemLayout} |
||||
> |
||||
<Form.Item |
||||
name="upload" |
||||
valuePropName="fileList" |
||||
getValueFromEvent={normFile} |
||||
extra="" |
||||
> |
||||
<Button |
||||
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||
href={"/template/template_activity.xlsx"} |
||||
> |
||||
<i className="fa fa-print" style={{ marginRight: "5px" }}></i> Download Template |
||||
</Button> |
||||
<Tooltip title="Format file .xlsx"> |
||||
<Upload |
||||
name="template" |
||||
listType="text" |
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
||||
maxCount={1} |
||||
beforeUpload={(file)=> fileHandler(file)} |
||||
showUploadList={false} |
||||
> |
||||
<Button icon={<UploadOutlined />}>Import Excel</Button> |
||||
</Upload> |
||||
</Tooltip> |
||||
</Form.Item> |
||||
</Form> |
||||
</Col> |
||||
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}> |
||||
<Button |
||||
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||
disabled={dataTable.length > 0 ? false : true} |
||||
onClick={(e)=> saveHandler(e)} |
||||
> |
||||
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">Data Preview</h4> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table |
||||
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'} |
||||
dataSource={dataTable} |
||||
columns={columns} |
||||
pagination={false} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
<Prompt |
||||
when={isPreview} |
||||
message={() => 'Import Activity belum disave ingin meninggalkan halaman ini?'} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ImportActivity; |
Loading…
Reference in new issue