Browse Source

Adding import activity

pull/2/head
Wahyu Ramadhan 2 years ago
parent
commit
99603aa75d
  1. 1
      package.json
  2. BIN
      public/template/template_activity.xlsx
  3. 2
      src/routes.js
  4. 7
      src/views/SimproV2/CreatedProyek/DialogGantt.js
  5. 397
      src/views/SimproV2/CreatedProyek/ImportActivity/index.js
  6. 13
      src/views/SimproV2/CreatedProyek/ImportActivity/table.css

1
package.json

@ -74,6 +74,7 @@
"react-color": "^2.17.3",
"react-content-loader": "^6.0.3",
"react-dom": "^16.14.0",
"react-excel-renderer": "^1.1.0",
"react-grid-layout": "^1.2.5",
"react-highlight-words": "^0.18.0",
"react-i18next": "^12.1.5",

BIN
public/template/template_activity.xlsx

Binary file not shown.

2
src/routes.js

@ -9,6 +9,7 @@ const ConfigAlert = React.lazy(() => import('./views/Master/ConfigAlert'));
const ControlMonitoring = React.lazy(() => import('./views/Report/ControlMonitoring'));
const ControlMonitoringGantt = React.lazy(() => import('./views/ControlMonitoringGantt'));
const CreatedProyek = React.lazy(() => import('./views/SimproV2/CreatedProyek'));
const GanttImportActivity = React.lazy(() => import('./views/SimproV2/CreatedProyek/ImportActivity'));
const Dashboard = React.lazy(() => import('./views/Dashboard'));
const Divisi = React.lazy(() => import('./views/SimproV2/Divisi'));
const DivisiKaryawan = React.lazy(() => import('./views/Master/MasterTipeKaryawan'));
@ -55,6 +56,7 @@ const routes = [
{ path: '/dashboard-customer/:PROJECT_ID/:GANTT_ID', name: 'DashboardCustomer', component: DashboardCustomer },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },
{ path: '/projects/:id/import/activity', exact: true, name: 'Gantt Import Activity', component: GanttImportActivity },
{ path: '/projects/:id/:project/gantt', exact: true, name: 'Gantt', component: Gantt },
{ path: '/human-resource', exact: true, name: 'Human Resource', component: ResourceWorker },
{ path: '/material-resource', exact: true, name: 'Material Resource', component: ResourceMaterial },

7
src/views/SimproV2/CreatedProyek/DialogGantt.js

@ -123,6 +123,13 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
<Tooltip title="Gantt Permission">
<Button size="small" size={"sm"} color='success' onClick={() => handleUserGant(text.id)}><i className="fa fa-users"></i></Button>
</Tooltip>{" "}
<Link to={`/projects/${text.id}/import/activity`}>
{" "}<Tooltip title="Import Activity">
<Button size={"sm"} color='success'>
<i className="fa fa-file-excel-o"></i>
</Button>
</Tooltip>{" "}
</Link>
<Link to={`/projects/${text.id}/${idTask}/gantt`}>
<Tooltip title="Gantt">
<Button size="small" size={"sm"} color='primary'><i className="fa fa-gears"></i></Button>

397
src/views/SimproV2/CreatedProyek/ImportActivity/index.js

@ -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(/&nbsp;/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;

13
src/views/SimproV2/CreatedProyek/ImportActivity/table.css

@ -0,0 +1,13 @@
.ant-table-tbody{
padding: 0 !important;
}
.ant-table-tbody > tr > td{
padding: 0 !important;
}
.table-row-light {
background-color: #ffffff;
}
.table-row-dark {
background-color: #f0f3f5;
}
Loading…
Cancel
Save