Browse Source

remove unrelated things

pull/2/head
Muhammad Sulaiman Yusuf 2 years ago
parent
commit
c4bd7ecbc5
  1. 7
      src/routes.js
  2. 20
      src/views/Dashboard/index.js
  3. 128
      src/views/DashboardPMO/Dashboard.css
  4. 41
      src/views/DashboardPMO/PieChart.js
  5. 106
      src/views/DashboardPMO/chartDashboard.js
  6. 0
      src/views/DashboardPMO/index.js
  7. 130
      src/views/DashboardPMO/tableDashboard.js
  8. 44
      src/views/DashboardPMOV1/chartDashboard.js
  9. 181
      src/views/DashboardPMOV1/index.js
  10. 40
      src/views/DashboardPMOV1/projectMap.js
  11. 37
      src/views/DashboardPMOV1/projectPhaseChart.js
  12. 130
      src/views/DashboardPMOV1/tableDashboard.js
  13. 376
      src/views/DashboardPMOV1/tableDashboardv1.js
  14. 191
      src/views/DashboardProject/index.js
  15. 49
      src/views/DashboardSimpro/BarChart.js
  16. 128
      src/views/DashboardSimpro/Dashboard.css
  17. 18
      src/views/DashboardSimpro/LineChart.js
  18. 23
      src/views/DashboardSimpro/PieChart.js
  19. 308
      src/views/DashboardSimpro/index.js

7
src/routes.js

@ -9,8 +9,7 @@ const ConfigAlert = React.lazy(() => import('./views/Master/ConfigAlert'));
const ControlMonitoring = React.lazy(() => import('./views/Report/ControlMonitoring')); const ControlMonitoring = React.lazy(() => import('./views/Report/ControlMonitoring'));
const ControlMonitoringGantt = React.lazy(() => import('./views/ControlMonitoringGantt')); const ControlMonitoringGantt = React.lazy(() => import('./views/ControlMonitoringGantt'));
const CreatedProyek = React.lazy(() => import('./views/SimproV2/CreatedProyek')); const CreatedProyek = React.lazy(() => import('./views/SimproV2/CreatedProyek'));
const DashboardSimpro = React.lazy(() => import('./views/DashboardSimpro')); const Dashboard = React.lazy(() => import('./views/Dashboard'));
const DashboardPMO = React.lazy(() => import('./views/DashboardPMO'));
const Divisi = React.lazy(() => import('./views/SimproV2/Divisi')); const Divisi = React.lazy(() => import('./views/SimproV2/Divisi'));
const DivisiKaryawan = React.lazy(() => import('./views/Master/MasterTipeKaryawan')); const DivisiKaryawan = React.lazy(() => import('./views/Master/MasterTipeKaryawan'));
const Gantt = React.lazy(() => import('./views/SimproV2/Gantt')); const Gantt = React.lazy(() => import('./views/SimproV2/Gantt'));
@ -44,12 +43,10 @@ const TestGantt = React.lazy(() => import('./views/testgantt'));
const UserAdmin = React.lazy(() => import('./views/Master/UserAdmin')); const UserAdmin = React.lazy(() => import('./views/Master/UserAdmin'));
const UserShift = React.lazy(() => import('./views/SimproV2/UserShift')); const UserShift = React.lazy(() => import('./views/SimproV2/UserShift'));
const DashboardProject = React.lazy(() => import('./views/DashboardProject')); const DashboardProject = React.lazy(() => import('./views/DashboardProject'));
const DashboardPMOV1 = React.lazy(() => import('./views/DashboardPMOV1'));
const routes = [ const routes = [
{ path: '/', exact: true, name: 'Home' }, { path: '/', exact: true, name: 'Home' },
{ path: '/dashboardold', name: 'Dashboard', component: DashboardSimpro }, { path: '/dashboard', name: 'Dashboard', component: Dashboard},
{ path: '/dashboard', name: 'Dashboard', component: DashboardPMOV1 },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek }, { path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },
{ path: '/projects/:id/:project/gantt', exact: true, name: 'Gantt', component: Gantt }, { path: '/projects/:id/:project/gantt', exact: true, name: 'Gantt', component: Gantt },

20
src/views/Dashboard/index.js

@ -0,0 +1,20 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios'
const DashboardPMO = () => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
return (
<>
<div></div>
</>
);
}
export default DashboardPMO;

128
src/views/DashboardPMO/Dashboard.css

@ -1,128 +0,0 @@
.number-asset {
font-size: 50px;
font-weight: bold;
text-align: center;
}
.text-bold {
font-weight: bold;
}
.view-rectangle {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;
}
.view1 {
width: 220px;
height: 100px;
padding: 10px;
margin-bottom: -20px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #008B8B;
}
.view2 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #8B008B;
}
.view3 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #7CFC00;
}
.view4 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #FF0000;
}
.view5 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #4682B4;
}
.number-style {
font-size: 30px;
color: black;
font-weight: bold;
margin-bottom:15px;
}
.number-style1 {
font-size: 30px;
color: #FFFFFF;
font-weight: bold;
margin-bottom:15px;
}
.daily-info-card {
min-width: 130px;
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
margin: 4px;
border-radius: 8px;
}
.dashboard-container {
overflow-x: auto;
}
.maptable-window-button-container {
float: right;
right: 0px;
}
.maptable-close, .maptable-maximize, .maptable-minimize {
cursor: pointer;
padding: 4px;
}
.maptable-header {
margin-bottom: -10px;
}
.maptable-title {
font-size: 24px;
font-weight: 700;
text-align: left;
margin-left: 20px;
}
.maptable-close:hover, .maptable-maximize:hover, .maptable-minimize:hover {
color: #20a8d8;
}

41
src/views/DashboardPMO/PieChart.js vendored

@ -1,41 +0,0 @@
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Pie } from '@ant-design/plots';
const PieChart = () => {
const data = [
{
type: 'FTTH',
value: 27,
},
{
type: 'Konstruksi',
value: 25,
},
];
const config = {
appendPadding: 10,
data,
angleField: 'value',
colorField: 'type',
radius: 0.9,
label: {
type: 'inner',
offset: '-30%',
content: ({ percent }) => `${(percent * 100).toFixed(0)}%`,
style: {
fontSize: 14,
textAlign: 'center',
},
},
interactions: [
{
type: 'element-active',
},
],
};
return <Pie {...config} />;
};
export default PieChart;

106
src/views/DashboardPMO/chartDashboard.js

@ -1,106 +0,0 @@
import React from 'react';
import { Doughnut, Bar } from 'react-chartjs-2';
import faker from '@faker-js/faker';
export const optionsDoughnut = {
title: {
display: true,
text: 'PROJECT BY TYPE'
},
};
export const data = {
labels: ['Manned guarding ', 'C&T', 'CMS ', 'ESS', 'RSO'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
// 'rgba(255, 159, 64, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
// 'rgba(255, 159, 64, 1)',
],
borderWidth: 1,
},
],
};
export const DoughnutChart = () => {
return <Doughnut data={data} options={optionsDoughnut} />;
}
export const options = {
title: {
display: true,
text: 'PROJECT BY GOVERNANCE PHASE'
},
legend: {
position: 'right',
},
responsive: true,
scales: {
yAxes: [{
display: true,
// position: 'right',
stacked: true,
}],
xAxes: [{
display: true,
// position: 'right',
stacked: true,
}],
},
};
const labels = [''];
export const dataBar = {
labels,
datasets: [
{
indexAxis: 'y',
label: 'Initiation',
data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })),
backgroundColor: 'rgb(255, 99, 132)',
},
{
indexAxis: 'y',
label: 'Execution',
data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })),
backgroundColor: 'rgb(75, 192, 192)',
},
{
indexAxis: 'y',
label: 'Closing',
data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })),
backgroundColor: 'rgb(53, 162, 235)',
},
// {
// indexAxis: 'y',
// label: 'Excecution',
// data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })),
// backgroundColor: 'rgba(255, 159, 64, 1)',
// },
],
};
export function BarChart() {
return <Bar indexAxis='y' options={options} data={dataBar} />;
}

0
src/views/DashboardPMO/index.js

130
src/views/DashboardPMO/tableDashboard.js

@ -1,130 +0,0 @@
import React from 'react';
import { Table, Tag, Space } from 'antd';
const columns = [
{
title: 'Project Name',
dataIndex: 'project',
key: 'project',
fixed: 'left',
width: 200,
// render: text => <a>{text}</a>,
},
{
title: 'Project Owner',
dataIndex: 'owner',
key: 'owner',
},
{
title: 'Start Date',
dataIndex: 'startDate',
key: 'startDate',
},
{
title: 'End Date',
dataIndex: 'endDate',
key: 'endDate',
},
{
title: 'Cost',
dataIndex: 'cost',
key: 'cost',
render: text => `Rp. ${text.toLocaleString()}`,
align: 'right'
},
{
title: 'Cost Health',
dataIndex: 'costHealth',
key: 'costHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />
,
align: 'center',
},
{
title: 'Work Health',
dataIndex: 'workHealth',
key: 'workHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />,
align: 'center',
},
{
title: 'Schedule Health',
dataIndex: 'scheduleHealth',
key: 'scheduleHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />,
align: 'center',
},
{
title: '% Complete',
dataIndex: 'complete',
key: 'complete',
render: text => `${text}%`,
align: 'right'
},
// {
// title: 'Action',
// key: 'action',
// render: (text, record) => (
// <Space size="middle">
// <a>Invite {record.name}</a>
// <a>Delete</a>
// </Space>
// ),
// },
];
const data = [
{
key: '1',
project: 'Bay Plaza',
owner: 'John Brown',
startDate: '1/22/2022',
endDate: '1/22/2023',
complete: 20,
cost: 40000000,
costHealth: 'good',
workHealth: 'default',
scheduleHealth: 'warning'
},
{
key: '2',
project: 'Jambi Bridge',
owner: 'Jim Green',
startDate: '4/22/2022',
endDate: '11/22/2023',
complete: 65,
cost: 20000000,
costHealth: 'good',
workHealth: 'default',
scheduleHealth: 'danger'
},
{
key: '3',
project: 'Banten International Airport',
owner: 'Joe Black',
startDate: '1/22/2022',
endDate: '1/22/2025',
complete: 50,
cost: 200000000,
costHealth: 'default',
workHealth: 'default',
scheduleHealth: 'default'
},
];
const TableDashboard = () => {
return (
<Table size="small" columns={columns} dataSource={data} scroll={{ x: 1300, y: 300 }} />
);
}
export default TableDashboard;

44
src/views/DashboardPMOV1/chartDashboard.js

@ -1,44 +0,0 @@
import React from 'react';
import { Doughnut } from 'react-chartjs-2';
const options = {
title: {
display: true,
text: 'PROJECT BY TYPE'
},
};
export const ProjectTypeChart = ({ projectTypes, projectsByType }) => {
let total = []
for (var j = 0; j < projectTypes.length; j++) {
total.push(projectsByType[j].total)
}
let dataSets = [{
label: "#",
data: total,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
],
borderWidth: 1,
}]
const data = {
labels: projectTypes,
datasets: dataSets,
};
return <Doughnut data={data} options={options} />;
}

181
src/views/DashboardPMOV1/index.js

@ -1,181 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Row, Col, Collapse } from 'antd';
import TableDashboardV1 from './tableDashboardv1';
import { ProjectTypeChart } from './chartDashboard';
import { ProjectPhaseChart } from './projectPhaseChart';
import ProjectMap from './projectMap';
import axios from 'axios'
import { BASE_OSPRO } from '../../const/ApiConst';
import { formatRibuanDecimal } from '../../const/CustomFunc.js';
const { Panel } = Collapse;
function BoxDashboardNoIcon({ value, title, secondaryTitle, bgColor, valFSize = '1.0rem', fSize = '0.7rem' }) {
return (
<>
<div style={{ backgroundColor: bgColor, height: 60 }} class='box-dashboard-pm'>
<Row>
<Col span={24}>
<div class='box-content'>
<div style={{ fontSize: valFSize }} class='text-box'>{value}</div>
<div style={{ fontSize: fSize }} class='text-box'>{title}</div>
<div style={{ fontSize: '0.6rem' }} class='text-box-secondary'>{secondaryTitle && secondaryTitle.toUpperCase()}</div>
</div>
</Col>
</Row>
</div>
</>
)
}
const DashboardPM = () => {
const [PROJECTCOUNT, SET_PROJECTCOUNT] = useState(0)
const [PROJECTBUDGETTOTAL, SET_PROJECTBUDGETTOTAL] = useState(0)
const [PROJECTMANPOWER, SET_PROJETMANPOWER] = useState(0)
const [PROJECTACTUALCOSTTOTAL, SET_PROJECTACTUALCOSTTOTAL] = useState(0)
const [PROJECTCOSTTOTAL, SET_PROJECTCOSTTOTAL] = useState(0)
const [TOTALREVENUE, SET_TOTALREVENUE] = useState(0)
const [MANPOWERS, SET_MANPOWERS] = useState(0)
const [PROJECTPHASES, SET_PROJECTPHASES] = useState([])
const [PROJECTSBYPHASE, SET_PROJECTSBYPHASE] = useState([])
const [PROJECTSONDANGER, SET_PROJECTSONDANGER] = useState(0)
const [PROJECTLOCATIONS, SET_PROJECTLOCATIONS] = useState([])
const [PROJECTTYPES, SET_PROJECTTYPES] = useState([])
const [PROJECTSBYTYPE, SET_PROJECTSBYTYPE] = useState([])
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const getProjectInfos = async () => {
const URL = `${BASE_OSPRO}/api/project/list`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
let markers = []
SET_PROJECTCOUNT(result.data.totalRecord)
result.data.totalActualCost != undefined ? SET_PROJECTCOSTTOTAL(result.data.totalActualCost) : SET_PROJECTCOSTTOTAL(0)
result.data.totalPlannedCost != undefined ? SET_PROJECTBUDGETTOTAL(result.data.totalPlannedCost) : SET_PROJECTBUDGETTOTAL(0)
result.data.totalRevenue != undefined ? SET_TOTALREVENUE(result.data.totalRevenue) : SET_TOTALREVENUE(0)
result.data.manpowers != undefined ? SET_MANPOWERS(result.data.manpowers) : SET_MANPOWERS(0)
result.data.projectPhases != undefined ? SET_PROJECTPHASES(result.data.projectPhases) : SET_PROJECTPHASES([])
result.data.projectsByPhase != undefined ? SET_PROJECTSBYPHASE(result.data.projectsByPhase) : SET_PROJECTSBYPHASE([])
result.data.projectTypes != undefined ? SET_PROJECTTYPES(result.data.projectTypes) : SET_PROJECTTYPES([])
result.data.projectsByType != undefined ? SET_PROJECTSBYTYPE(result.data.projectsByType) : SET_PROJECTSBYTYPE([])
result.data.projectsOnDanger != undefined ? SET_PROJECTSONDANGER(result.data.projectsOnDanger) : SET_PROJECTSONDANGER(0)
for (let i = 0; i < result.data.totalRecord; i++) {
if (typeof (result.data.data[i].geolocation) == 'object' && result.data.data[i].geolocation.length > 0) {
markers.push({
lat: result.data.data[i].geolocation[0].lat,
lon: result.data.data[i].geolocation[0].lon,
label: result.data.data[i].area_kerja + "\n" + result.data.data[i].nama
})
}
}
SET_PROJECTLOCATIONS(markers)
}
useEffect(() => {
getProjectInfos();
}, [])
return (
<>
<div>
<Row
gutter={{
xs: 8,
sm: 16,
md: 24,
lg: 32,
}}
>
<Col span={2} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={PROJECTCOUNT}
bgColor="#0287c7"
title="Projects"
/>
</Col>
<Col span={3} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={PROJECTSONDANGER}
bgColor="#f51d1d"
title="Projects on Danger"
fSize="0.7rem"
/>
</Col>
<Col span={5} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={`${formatRibuanDecimal(PROJECTBUDGETTOTAL)}`}
bgColor="#cf6102"
title="Budget"
valFSize="1rem"
/>
</Col>
<Col span={5} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={`${formatRibuanDecimal(PROJECTCOSTTOTAL)}`}
bgColor="#f51d1d"
title="Project Expanditure"
valFSize="1rem"
/>
</Col>
<Col span={5} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={`${formatRibuanDecimal(TOTALREVENUE)}`}
bgColor="#077857"
title="Revenue"
valFSize="1rem"
/>
</Col>
<Col span={2} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={MANPOWERS}
bgColor="#0287c7"
title="Manpower"
/>
</Col>
<Col span={2} style={{ margin: '' }}>
<BoxDashboardNoIcon
value={<i style={{ color: '#fff' }} class="zmdi zmdi-truck zmdi-hc-2x"></i>}
bgColor="#0287c7"
title="OSLOG"
/>
</Col>
</Row>
<Row style={{ marginTop: '15px' }}>
<Col span={24} style={{ margin: '0px 0px 0px 0px' }}>
<Collapse>
<Panel header="More Information" key="1">
<Row style={{ margin: '10px 10px 0px 10px' }}>
<Col span={8} >
<ProjectMap markers={PROJECTLOCATIONS} />
</Col>
<Col span={8}>
<ProjectPhaseChart projectPhases={PROJECTPHASES} projectsByPhase={PROJECTSBYPHASE} />
</Col>
<Col span={8}>
<ProjectTypeChart projectTypes={PROJECTTYPES} projectsByType={PROJECTSBYTYPE} />
</Col>
</Row>
</Panel>
</Collapse>
</Col>
</Row>
<Row style={{ marginTop: '15px' }}>
<Col span={24}>
<TableDashboardV1 />
</Col>
</Row>
</div>
</>
);
}
export default DashboardPM;

40
src/views/DashboardPMOV1/projectMap.js

@ -1,40 +0,0 @@
import React from 'react';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
import L from 'leaflet';
import { MapContainer, Marker, TileLayer, Popup } from 'react-leaflet'
import 'leaflet/dist/leaflet.css';
const defaultMapPosition = [-6.1753924, 106.8271528]
const DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
iconSize: [15, 25],
shadowSize: [0, 0],
});
L.Marker.prototype.options.icon = DefaultIcon;
const ProjectMap = ({ markers }) => {
return (
<MapContainer
center={defaultMapPosition}
zoom={5}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{markers.map(({ lat, lon, label }) => (
<Marker position={[lat, lon]}>
<Popup>
{label}
</Popup>
</Marker>
))}
</MapContainer>
);
}
export default ProjectMap;

37
src/views/DashboardPMOV1/projectPhaseChart.js vendored

@ -1,37 +0,0 @@
import React from 'react';
import { HorizontalBar } from 'react-chartjs-2';
const options = {
responsive: true,
title: {
display: true,
text: 'PROJECT BY PHASE'
}
};
export const ProjectPhaseChart = ({ projectPhases, projectsByPhase }) => {
let dataSets = []
let total = []
for (var i = 0; i < projectsByPhase.length; i++) {
total = []
for (var j = 0; j < projectPhases.length; j++) {
if (projectPhases[j] != projectsByPhase[i].name) {
total.push(0)
} else {
total.push(projectsByPhase[i].total)
}
}
dataSets.push({
label: projectsByPhase[i].name,
data: total,
backgroundColor: projectsByPhase[i].color,
borderColor: '#000000',
});
}
const data = {
datasets: dataSets,
labels: projectPhases,
};
return <HorizontalBar options={options} data={data} />;
}

130
src/views/DashboardPMOV1/tableDashboard.js

@ -1,130 +0,0 @@
import React from 'react';
import { Table, Tag, Space } from 'antd';
const columns = [
{
title: 'Project Name',
dataIndex: 'project',
key: 'project',
fixed: 'left',
width: 200,
render: text => <a>{text}</a>,
},
{
title: 'Project Owner',
dataIndex: 'owner',
key: 'owner',
},
{
title: 'Start Date',
dataIndex: 'startDate',
key: 'startDate',
},
{
title: 'End Date',
dataIndex: 'endDate',
key: 'endDate',
},
{
title: 'Cost',
dataIndex: 'cost',
key: 'cost',
render: text => `Rp. ${text.toLocaleString()}`,
align: 'right'
},
{
title: 'Cost Health',
dataIndex: 'costHealth',
key: 'costHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />
,
align: 'center',
},
{
title: 'Work Health',
dataIndex: 'workHealth',
key: 'workHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />,
align: 'center',
},
{
title: 'Schedule Health',
dataIndex: 'scheduleHealth',
key: 'scheduleHealth',
render: text =>
text === 'good' ? <div className='health-status-good' /> :
text === 'danger' ? <div className='health-status-danger' /> :
text === 'warning' ? <div className='health-status-warning' /> : <div className='health-status-default' />,
align: 'center',
},
{
title: '% Complete',
dataIndex: 'complete',
key: 'complete',
render: text => `${text}%`,
align: 'right'
},
// {
// title: 'Action',
// key: 'action',
// render: (text, record) => (
// <Space size="middle">
// <a>Invite {record.name}</a>
// <a>Delete</a>
// </Space>
// ),
// },
];
const data = [
{
key: '1',
project: 'Bay Plaza',
owner: 'John Brown',
startDate: '1/22/2022',
endDate: '1/22/2023',
complete: 20,
cost: 40000000,
costHealth: 'good',
workHealth: 'default',
scheduleHealth: 'warning'
},
{
key: '2',
project: 'Jambi Bridge',
owner: 'Jim Green',
startDate: '4/22/2022',
endDate: '11/22/2023',
complete: 65,
cost: 20000000,
costHealth: 'good',
workHealth: 'default',
scheduleHealth: 'danger'
},
{
key: '3',
project: 'Banten International Airport',
owner: 'Joe Black',
startDate: '1/22/2022',
endDate: '1/22/2025',
complete: 50,
cost: 200000000,
costHealth: 'default',
workHealth: 'default',
scheduleHealth: 'default'
},
];
const TableDashboard = () => {
return (
<Table size="small" columns={columns} dataSource={data} scroll={{ x: 1300, y: 300 }} />
);
}
export default TableDashboard;

376
src/views/DashboardPMOV1/tableDashboardv1.js

@ -1,376 +0,0 @@
import '../../../node_modules/react-grid-layout/css/styles.css';
import '../../../node_modules/react-resizable/css/styles.css';
import './../DashboardPMO/Dashboard.css';
import { BASE_OSPRO } from '../../const/ApiConst';
import React, { useEffect, useState, useRef } from 'react';
import axios from 'axios'
import { Table, Row, Col, Button, Input, InputNumber, Space } from 'antd';
import { formatRibuanDecimal } from '../../const/CustomFunc.js';
import { Badge } from 'reactstrap';
import { Link } from "react-router-dom";
import { SearchOutlined } from '@ant-design/icons';
import Highlighter from 'react-highlight-words';
import _ from "lodash";
import Slider from "antd/lib/slider";
import numeral from "numeral";
const filterData = data => formatter => data.map(item => ({
text: formatter(item),
value: formatter(item)
}))
const TableDashboardV1 = () => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
}
}
const [MANPOWERS, SET_MANPOWERS] = useState(0)
const [MAXPLANNEDCOST, SET_MAXPLANNEDCOST] = useState(0)
const [MAXACTUALCOST, SET_MAXACTUALCOST] = useState(0)
const [MAXCOSTVARIANCE, SET_MAXCOSTVARIANCE] = useState(0)
const [dataTable, setDataTable] = useState([])
const [searchText, setSearchText] = useState('')
const [searchedColumn, setSearchedColumn] = useState('')
const searchInput = useRef(null)
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm()
setSearchText(selectedKeys[0])
setSearchedColumn(dataIndex)
};
const handleSlide = (dataIndex, value, confirm) => {
confirm({ closeDropdown: false });
};
const slider = (dataIndex, maxSlider) => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => {
return (
<div
className="custom-filter-dropdown ant-table-filter-dropdown"
style={{ minWidth: "20rem", padding: "0.5rem 1rem" }}
>
<Row>
<Col span={4}>
<div style={{ display: "flex", flexDirection: "column" }}>
<div>
<strong>Min: </strong>
</div>
<div>0</div>
</div>
</Col>
<Col span={16}>
<Slider
range={true}
min={0}
max={maxSlider}
defaultValue={[0, maxSlider]}
onAfterChange={(value) => {
setSelectedKeys([value])
handleSlide(dataIndex, value, confirm)}
}
/>
</Col>
<Col span={4}>
<div style={{ display: "flex", flexDirection: "column" }}>
<div>
<strong>Max:</strong>
</div>
<div style={{ whitespace: "nowrap", overflow: "hidden" }} ellipsis={true}>{dataIndex == 'manpower' || dataIndex == 'progress' ? maxSlider : formatRibuanDecimal(maxSlider)}</div>
</div>
</Col>
</Row>
</div>
)},
onFilter: (value, record) => {
return (record[dataIndex] >= value[0] && record[dataIndex] <= value[1])
},
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
});
const handleReset = (clearFilters) => {
clearFilters();
setSearchText('');
};
const getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => {
return (
<div
style={{
padding: 8,
}}
>
<Input
ref={searchInput}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{
marginBottom: 8,
display: 'block',
}}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{
width: 90,
}}
>
Search
</Button>
<Button
onClick={() => clearFilters && handleReset(clearFilters)}
size="small"
style={{
width: 90,
}}
>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({
closeDropdown: false,
});
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
}}
>
</Button>
</Space>
</div>
)},
filterIcon: (filtered) => (
<SearchOutlined
style={{
color: filtered ? '#1890ff' : undefined,
}}
/>
),
onFilter: (value, record) => {
return record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
},
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
render: (text, record) =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{
backgroundColor: '#ffc069',
padding: 0,
}}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
<>
<Link to={`/dashboard-project/${record.id}/${record.lastGanttId}`}>
{record.kode_sortname} <br /> {text}
</Link>
</>
),
});
const filterDate = (dataIndex) => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => {
return (
<div
style={{
padding: 8,
}}
>
<InputNumber
ref={searchInput}
placeholder={`Year`}
value={selectedKeys[0]}
min={2020}
max={2050}
//onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onChange={(e) => console.log(e)}
style={{
marginBottom: 8,
display: 'block',
}}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{
width: 90,
}}
>
Search
</Button>
<Button
onClick={() => clearFilters && handleReset(clearFilters)}
size="small"
style={{
width: 90,
}}
>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({
closeDropdown: false,
});
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
}}
>
</Button>
</Space>
</div>
)},
onFilter: (value, record) => {
return record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
},
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
}
});
const getProjects = async () => {
const URL = `${BASE_OSPRO}/api/project/list`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
if (result.data.code == 200) {
setDataTable(result.data.data);
result.data.manpowers != undefined ? SET_MANPOWERS(result.data.manpowers) : SET_MANPOWERS(0)
SET_MAXPLANNEDCOST(Math.max(...result.data.data.map(o => o.plannedCost)))
SET_MAXACTUALCOST(Math.max(...result.data.data.map(o => o.actualCost)))
SET_MAXCOSTVARIANCE(Math.max(...result.data.data.map(o => o.costVariance)))
}
}
const columns = [
{
title: 'Project',
dataIndex: 'nama',
key: 'nama',
render: (text, record) =>
<Link to={`/dashboard-project/${record.id}/${record.lastGanttId}`}>
{record.kode_sortname} <br /> {text}
</Link>,
...getColumnSearchProps('nama'),
},
{
title: 'Project Manager',
dataIndex: 'projectManager',
key: 'projectManager',
filters: _.uniqWith(filterData(dataTable)(i => i.projectManager), _.isEqual),
onFilter: (value, record) => record.projectManager.indexOf(value) === 0,
},
{
title: 'Planned Interval',
dataIndex: 'plannedInterval',
key: 'plannedInterval',
...filterDate('plannedInterval'),
},
{
title: 'Manpower',
dataIndex: 'manpower',
key: 'manpower',
render: (text) => {
return `${text}/${MANPOWERS}`
},
...slider('manpower', MANPOWERS)
},
{
title: 'Budget Project',
dataIndex: 'plannedCost',
key: 'plannedCost',
render: (text) => <a>{formatRibuanDecimal(text)}</a>,
...slider('plannedCost', MAXPLANNEDCOST)
},
{
title: 'Actual Cost',
dataIndex: 'actualCost',
key: 'actualCost',
render: (text) => <a>{formatRibuanDecimal(text)}</a>,
...slider('actualCost', MAXACTUALCOST)
},
{
title: 'Cost Variance',
dataIndex: 'costVariance',
key: 'costVariance',
render: (text) => <a>{formatRibuanDecimal(text)}</a>,
...slider('costVariance', MAXCOSTVARIANCE)
},
{
title: 'Cost Health',
dataIndex: 'costHealth',
key: 'costHealth',
render: (text) => {
if (text == "on-budget") {
return <Badge color="success">On Budget</Badge>
} else if (text == "warning") {
return <Badge color="warning">Warning</Badge>
} else {
return <Badge color="danger">Danger</Badge>
}
},
filters: _.uniqWith(filterData(dataTable)(i => i.costHealth), _.isEqual),
onFilter: (value, record) => record.costHealth.indexOf(value) === 0,
},
{
title: 'Progress',
dataIndex: 'progress',
key: 'progress',
render: (text) => {
return <Badge color={parseInt(text) > 74 ? 'success' : text > 49 ? 'warning' : 'danger'}>{text}%</Badge>
},
...slider('progress', 100)
},
];
useEffect(() => {
getProjects();
}, [])
return (
<>
<Row gutter={[16, 16]}>
<Col span={24}>
<Table
columns={columns}
dataSource={dataTable}
/>
</Col>
</Row>
</>
);
}
export default TableDashboardV1;

191
src/views/DashboardProject/index.js

@ -2,8 +2,6 @@ import React, { useEffect, useState } from 'react';
import { Row, Col, Select, Divider } from 'antd'; import { Row, Col, Select, Divider } from 'antd';
import moment from 'moment' import moment from 'moment'
import Gantt from './ganttDashboard'; import Gantt from './ganttDashboard';
// import CurvaS from './curvaS'
import TableDashboard from './tableDashboard';
import ChatDashboard from './chatDashboard'; import ChatDashboard from './chatDashboard';
import axios from 'axios' import axios from 'axios'
import { NotificationContainer, NotificationManager } from 'react-notifications'; import { NotificationContainer, NotificationManager } from 'react-notifications';
@ -12,7 +10,6 @@ import { Badge } from 'reactstrap';
import { BASE_OSPRO, BASE_INTEGRATION_V1, TOKEN_ADW } from '../../const/ApiConst'; import { BASE_OSPRO, BASE_INTEGRATION_V1, TOKEN_ADW } from '../../const/ApiConst';
import {formatRibuanDecimal} from "../../const/CustomFunc"; import {formatRibuanDecimal} from "../../const/CustomFunc";
import ProgressBar from "./progressBar"; import ProgressBar from "./progressBar";
import { Line } from 'react-chartjs-2';
import numeral from 'numeral'; import numeral from 'numeral';
function BoxDashboard({ value, title, secondaryTitle, icon, bgColor }) { function BoxDashboard({ value, title, secondaryTitle, icon, bgColor }) {
@ -37,81 +34,6 @@ function RenderHealthProject({params}){
} }
} }
const optionsChartKurvaS = {
// title: {
// display: true,
// text: 'Progress Cost Perencanaan dan Realisasi'
// },
responsive: true,
maintainAspectRatio: false,
aspectRatio: 1,
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
const label = data.datasets[tooltipItem.datasetIndex].label || "";
return `${label}: ${numeral(tooltipItem.value).format("0,0")}`;
},
},
},
scales: {
yAxes: [
{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
ticks: {
beginAtZero: true,
max: 100,
callback: function (value, index, values) {
return numeral(value).format("0,0");
},
},
min: 0,
max: 100,
},
],
},
zoom: {
enabled: true,
mode: "xy",
limits: {
y: { min: 0, max: 100 },
},
},
pan: {
enabled: true,
mode: "xy",
limits: {
y: { min: 0, max: 100 },
},
},
};
const DEFAULT_KURVAS = {
labels: [],
datasets: [
{
label: "Perencanaan",
data: [],
fill: false,
backgroundColor: "rgba(255, 99, 132, 0.5)",
borderColor: "rgba(255, 99, 132, 0.5)",
// stack: 'Stack-0'
yAxisID: "y-axis-1",
},
{
label: "Aktual",
data: [],
fill: false,
backgroundColor: "rgba(54, 162, 235, 0.5)",
borderColor: "rgba(54, 162, 235, 0.5)",
// stack: 'Stack-1'
yAxisID: "y-axis-1",
},
],
};
const DashboardProject = () => { const DashboardProject = () => {
const { ID } = useParams(); const { ID } = useParams();
@ -133,8 +55,6 @@ const DashboardProject = () => {
const [BUDGETHEALTH, SET_BUDGETHEALTH] = useState([]) const [BUDGETHEALTH, SET_BUDGETHEALTH] = useState([])
const [COMMENT, SET_COMMENT] = useState([]) const [COMMENT, SET_COMMENT] = useState([])
const [MANPOWER, SET_MANPOWER] = useState([0]) const [MANPOWER, SET_MANPOWER] = useState([0])
const [DATAKURVAS, SET_DATAKURVAS] = useState([])
const [CHARTKURVAS, SET_CHARTKURVAS] = useState([]);
const token = localStorage.getItem("token") const token = localStorage.getItem("token")
const HEADER = { const HEADER = {
@ -154,11 +74,13 @@ const DashboardProject = () => {
const getProjectDetail = async () => { const getProjectDetail = async () => {
const URL = `${BASE_OSPRO}/api/project/dashboard/${ID}` const URL = `${BASE_OSPRO}/api/project/dashboard/${ID}`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
if (result.data.code !== 200) { if (result.data.code !== 200) {
NotificationManager.error('Belum ada data proyek!', 'Failed'); NotificationManager.error(result.data.message, 'Failed');
} }
if(result.data.code == 200) {
let resData = result.data.data; let resData = result.data.data;
// result.data.data.map(datas => resData = datas);
SET_BUDGET(resData.rencana_biaya) SET_BUDGET(resData.rencana_biaya)
SET_PROJECTMGR(resData.pm) SET_PROJECTMGR(resData.pm)
SET_RO(resData.company) SET_RO(resData.company)
@ -173,6 +95,7 @@ const DashboardProject = () => {
SET_MANPOWER(resData.man_power) SET_MANPOWER(resData.man_power)
getDataCostActual(resData.kode_sortname); getDataCostActual(resData.kode_sortname);
} }
}
const getDataCostActual = async (kode_project) => { const getDataCostActual = async (kode_project) => {
const URL = `${BASE_INTEGRATION_V1}/api/project_cost?project_no=${kode_project}` const URL = `${BASE_INTEGRATION_V1}/api/project_cost?project_no=${kode_project}`
@ -185,93 +108,8 @@ const DashboardProject = () => {
} }
const getKurvaS = async () => {
const URL = `${BASE_OSPRO}/api/activity/get-curva-s`
const payload = {
project_id: [`${ID}`],
period: "week",
};
const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response)
if (result.data.code !== 200) {
NotificationManager.error('Belum ada data kurva S!', 'Failed');
}
let resData = result.data.data;
console.log('resData kurvaS', resData);
let dataCurvaS = resData[0];
if (dataCurvaS) {
let dataChart = [];
let proyekName = dataCurvaS.proyek_name ? dataCurvaS.proyek_name : "-";
let dataRes = dataCurvaS.data;
// let labelCostPlanning = dataRes ? dataRes.map(res => res.kode_sortname) : []; // ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
// let labels = dataRes ? dataRes.date ? moment(dataRes.date).format('DD-MM-YY') : '-' : [];
let labels =
dataRes && dataRes.date
? dataRes.date.map((item, idx) => {
let date = item[0];
let bcwp = item[1];
let acwp = item[2];
date = date ? moment(date).format("DD MMM YY") : "-";
bcwp = bcwp
? this.renderFormatRupiah(bcwp.toString(), "Rp")
: "";
acwp = acwp
? this.renderFormatRupiah(acwp.toString(), "Rp")
: "";
return [date, bcwp, acwp];
})
: [];
// let valueCostPlaning = dataRes ? dataRes.map(res => res.rencana_biaya) : []; // [10, 23, 39, 47, 55, 68, 70, 82, 90, 100]
// let valueCostPlanning = dataRes ? dataRes.map(res => parseFloat(res.cal_budget_cost)) : []; // [10, 23, 39, 47, 55, 68, 70, 82, 90, 100]
let valuePlanning = dataRes
? dataRes.percentage.map((res) =>
res && res[0] !== null ? res[0] : null
)
: []; // validate if null (holiday)
// let valueCostRealisasi = dataRes ? dataRes.map(res => res.biaya_actual) : []; // [10, 23, 39, 47, 55, 68, 70, 82, 90, 100]
// let valueCostRealisasi = dataRes ? dataRes.map(res => parseFloat(res.cal_actual_cost)) : []; // [10, 23, 39, 47, 55, 68, 70, 82, 90, 100]
let valueRealisasi = dataRes
? dataRes.percentage.map((res) =>
res && res[1] !== null ? res[1] : null
)
: []; // validate if null (holiday)
// console.log('labelCostPlanning', labelCostPlanning)
let chartData = {
proyek_name: proyekName,
// labels: [['P1',1500,1000],['P2',2000,1500],['P3',2500,1800],['P4',3000,2000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000],['P5',3500,3000]],
labels: labels,
datasets: [
{
label: "Perencanaan",
data: valuePlanning,
fill: false,
backgroundColor: "rgba(255, 99, 132, 0.5)",
borderColor: "rgba(255, 99, 132, 0.5)",
yAxisID: "y-axis-1",
// stack: 'Stack-0'
},
{
label: "Aktual",
data: valueRealisasi,
fill: false,
backgroundColor: "rgba(54, 162, 235, 0.5)",
borderColor: "rgba(54, 162, 235, 0.5)",
yAxisID: "y-axis-1",
// stack: 'Stack-1'
},
],
};
// dataChart.push(chartData);
SET_DATAKURVAS(chartData);
}
}
useEffect(() => { useEffect(() => {
getProjectDetail(); getProjectDetail();
getKurvaS();
}, []) }, [])
@ -282,7 +120,6 @@ const DashboardProject = () => {
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> <div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project">
<div><i style={{ color: 'teal' }} class="zmdi zmdi-assignment zmdi-hc-lg"></i></div> <div><i style={{ color: 'teal' }} class="zmdi zmdi-assignment zmdi-hc-lg"></i></div>
<div style={{ textTransform: 'uppercase' }}>Project </div> <div style={{ textTransform: 'uppercase' }}>Project </div>
{/* <div style={{ marginTop: 5 }} className='health-status-good' /> */}
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}> {PROJECTNAME}</div> <div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}> {PROJECTNAME}</div>
</div> </div>
</Col> </Col>
@ -388,19 +225,12 @@ const DashboardProject = () => {
</Col> </Col>
<Col span={5}> <Col span={5}>
{/* <BoxDashboard
// icon={<i style={{ color: '#fff' }} class="zmdi zmdi-money zmdi-hc-lg"></i>}
value={`${CURRENCYSYMBOL} ${formatRibuanDecimal(BUDGET)}`}
bgColor="#059669"
title="Budget" /> */}
<div style={{ backgroundColor: "#059669" }} className='box-header-dashboard-project'> <div style={{ backgroundColor: "#059669" }} className='box-header-dashboard-project'>
<div style={{ display: 'flex', justifyContent: 'center' }}> <div style={{ display: 'flex', justifyContent: 'center' }}>
<div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>Progress</div> <div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>Progress</div>
</div> </div>
<ProgressBar bgcolor="#ffc355" completed={PROGRESS} /> <ProgressBar bgcolor="#ffc355" completed={PROGRESS} />
</div> </div>
{/* <div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> */}
<Row> <Row>
<Col span={12}> <Col span={12}>
<div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> <div style={{ margin: '5px 0' }} className="box-header-dashboard-project">
@ -431,17 +261,6 @@ const DashboardProject = () => {
<div style={{ paddingTop: 20 }}> <div style={{ paddingTop: 20 }}>
<Row> <Row>
<Col span={19}> <Col span={19}>
<Line
options={optionsChartKurvaS}
height={100}
width={100}
data={DATAKURVAS}
/>
{/* <Gantt /> */}
{/* <div style={{ marginTop: 15 }}>
<h6>Curva S</h6>
<TableDashboard />
</div> */}
</Col> </Col>
<Col span={5}> <Col span={5}>
<ChatDashboard <ChatDashboard

49
src/views/DashboardSimpro/BarChart.js vendored

@ -1,49 +0,0 @@
import React from 'react';
import { Bar } from 'react-chartjs-2';
const data = {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
],
borderWidth: 1,
},
],
};
const options = {
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
};
const BarChart = () => (
<>
<Bar data={data} options={options} />
</>
);
export default BarChart;

128
src/views/DashboardSimpro/Dashboard.css

@ -1,128 +0,0 @@
.number-asset {
font-size: 50px;
font-weight: bold;
text-align: center;
}
.text-bold {
font-weight: bold;
}
.view-rectangle {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;
}
.view1 {
width: 220px;
height: 100px;
padding: 10px;
margin-bottom: -20px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #008B8B;
}
.view2 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #8B008B;
}
.view3 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #7CFC00;
}
.view4 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #FF0000;
}
.view5 {
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
background-color: #4682B4;
}
.number-style {
font-size: 30px;
color: black;
font-weight: bold;
margin-bottom:15px;
}
.number-style1 {
font-size: 30px;
color: #FFFFFF;
font-weight: bold;
margin-bottom:15px;
}
.daily-info-card {
min-width: 130px;
width: 220px;
height: 100px;
padding: 10px;
justify-content: center;
align-items: center;
text-align: center;
margin: 4px;
border-radius: 8px;
}
.dashboard-container {
overflow-x: auto;
}
.maptable-window-button-container {
float: right;
right: 0px;
}
.maptable-close, .maptable-maximize, .maptable-minimize {
cursor: pointer;
padding: 4px;
}
.maptable-header {
margin-bottom: -10px;
}
.maptable-title {
font-size: 24px;
font-weight: 700;
text-align: left;
margin-left: 20px;
}
.maptable-close:hover, .maptable-maximize:hover, .maptable-minimize:hover {
color: #20a8d8;
}

18
src/views/DashboardSimpro/LineChart.js vendored

@ -1,18 +0,0 @@
import React from 'react';
import { Line } from 'react-chartjs-2';
const MultiAxisLine = ({ data, handleClickChart, optionsAdded }) => {
const options = { ...optionsAdded };
return (
<>
<Line
data={data}
options={options}
{...handleClickChart && { getElementAtEvent: handleClickChart }}
/>
</>
);
}
export default MultiAxisLine;

23
src/views/DashboardSimpro/PieChart.js vendored

@ -1,23 +0,0 @@
import React from 'react';
import { Pie } from 'react-chartjs-2';
const options = {
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'Status Proyek'
},
legend: {
display: true,
position: 'bottom'
}
}
const PieChart = ({data}) => (
<>
<Pie data={data} options={options} />
</>
);
export default PieChart;

308
src/views/DashboardSimpro/index.js

@ -1,308 +0,0 @@
import '../../../node_modules/react-grid-layout/css/styles.css';
import '../../../node_modules/react-resizable/css/styles.css';
import '../Map/CustomScroll.css';
import './Dashboard.css';
import { Chart } from 'chart.js';
import { ChartDataLabels } from 'chartjs-plugin-datalabels';
import ContentLoader from "react-content-loader"
import LineChart from './LineChart';
import PieChart from './PieChart';
import React, { useEffect, useState } from 'react';
import SiopasMap from '../Map/Map_16.js';
import axios from 'axios'
import moment from 'moment';
import numeral from 'numeral';
import { BASE_SIMPRO } from '../../const/ApiConst';
import { DatePicker } from 'antd';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { PLANNING_REALISASI_SEARCH, PLANNING_SEARCH, PROYEK_SEARCH_DETAIL, PROYEK_EDIT } from '../../const/ApiConst.js';
import { Pagination, Tooltip, Tree, List, Checkbox } from 'antd';
import { getChildrenTree, formatRupiah, DATE_TIME_FORMAT } from '../../const/CustomFunc.js';
import { projectTreeConst } from '../../const/LayerTreeConst.js';
import {
Card, Modal, ModalHeader, ModalBody, ModalFooter, Button,
CardBody, CardHeader, Col, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, Row
} from 'reactstrap';
import {
DONE_COLOR, IZIN_COLOR, NOT_YET_COLOR,
PRESENT_COLOR, TOTAL_COLOR,
RED_COLOR,
ORANGE_COLOR,
GREEN_COLOR,
DARK_GREY_COLOR,
BLUE_COLOR,
PURPLE_COLOR
} from '../../const/AppConst.js';
const id_org = window.localStorage.getItem('id_org');
const roleName = window.localStorage.getItem('role_name');
Chart.plugins.register(ChartDataLabels);
const { RangePicker } = DatePicker;
let menu = [
{
"id": 3,
"title": "PANIC BUTTON",
"key": "absent",
"color": IZIN_COLOR
},
{
"id": 4,
"title": "WASPANG ACTIVE",
"key": "karyawan telat",
"color": GREEN_COLOR
},
{
"id": 5,
"title": "WASPANG ABSENT",
"key": "karyawan tanpa keterangan",
"color": ORANGE_COLOR
}
]
const defaultPersentaseProyek = {
labels: [],
datasets: [
{
label: 'Progress',
data: [],
fill: false,
backgroundColor: 'rgb(54, 162, 235)',
borderColor: 'rgba(54, 162, 235, 0.2)',
yAxisID: 'y-axis-1',
},
],
};
const defaultCostProyek = {
labels: [],
datasets: [
{
label: 'Perencanaan',
data: [],
fill: false,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgba(255, 99, 132, 0.2)',
yAxisID: 'y-axis-1',
},
{
label: 'Realisasi',
data: [],
fill: false,
backgroundColor: 'rgb(54, 162, 235)',
borderColor: 'rgba(54, 162, 235, 0.2)',
yAxisID: 'y-axis-1',
},
],
};
const defaultStatusProyek = {
labels: ['Aman', 'Alert', 'Critical'],
datasets: [
{
label: '# of Votes',
data: [],
backgroundColor: [
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 99, 132, 0.2)',
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(255, 99, 132, 1)',
],
borderWidth: 1,
},
],
};
const DashboardSimpro = () => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const [openPlanRealisasi, setopenPlanRealisasi] = useState(false);
const [openCostPlanRealisasi, setopenCostPlanRealisasi] = useState(false);
const [dataChart, setDataChart] = useState([]);
const [projectTree, setProjectTree] = useState([]);
const [allProyek, setAllProyek] = useState(true);
const [dataStatusProyek, setDataStatusProyek] = useState(null);
const [dataPersentaseProyek, setDataPersentaseProyek] = useState(null);
const [dataCostProyek, setdataCostProyek] = useState(null);
const [projectTreeVisible, setProjectTreeVisible] = useState(false);
const [checkedKeysProjectTree, setCheckedKeysProjectTree] = useState([]);
const [openModalTable, setOpenModalTable] = useState(false);
const [dataDashboard, setDataDashboard] = useState(null);
const handleGetDataDashboard = async () => {
const URL = `${BASE_SIMPRO}/dashboard-proyek/search`
const payload = {
"columns": [
{ "name": "created_at", "logic_operator": "range", "value": "2021-11-06 00:00:00", "value1": "2021-11-06 23:59:59", "operator": "AND" }
],
"paging": { "start": 0, "length": -1 }
}
const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response)
if (result.data.code !== 200) {
NotificationManager.error('Gaga Menambah Data!!', 'Failed');
}
setDataDashboard(result.data.data);
}
const handleGetDataDashboardChart = async () => {
const URL = `${BASE_SIMPRO}/dashboard-status/search`
let str = ''
checkedKeysProjectTree.map((res, idx) => {
if (idx == 0) str += `${res}`
if (idx != 0) str += `,${res}`
})
const payload = {
"columns": [
{ "name": "id", "logic_operator": "in", "value": str ? str : "0", "operator": "AND" }
],
"orders": { "columns": ["nama"], "ascending": true }
}
const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response)
if (result.data.code !== 200) {
NotificationManager.error('Gaga Menambah Data!!', 'Failed');
}
const { persentase_progress, progress_cost_planning, progress_cost_realisasi, status_proyek } = result.data.data
const labelPersentaseProyek = persentase_progress ? persentase_progress.map(res => res.label) : []
const valuePersentaseProyek = persentase_progress ? persentase_progress.map(res => res.total) : []
const persentaseProyek = {
labels: labelPersentaseProyek,
datasets: [
{
label: 'Progress',
data: valuePersentaseProyek,
fill: false,
backgroundColor: 'rgb(54, 162, 235)',
borderColor: 'rgba(54, 162, 235, 0.2)',
yAxisID: 'y-axis-1',
},
],
};
setDataPersentaseProyek(persentaseProyek)
const labelCostPlaning = progress_cost_planning ? progress_cost_planning.map(res => res.label) : []
const valueCostPlaning = progress_cost_planning ? progress_cost_planning.map(res => res.total) : []
const valueCostRealisasi = progress_cost_realisasi ? progress_cost_realisasi.map(res => res.total) : []
const costProyek = {
labels: labelCostPlaning,
datasets: [
{
label: 'Perencanaan',
data: valueCostPlaning,
fill: false,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgba(255, 99, 132, 0.2)',
yAxisID: 'y-axis-1',
},
{
label: 'Realisasi',
data: valueCostRealisasi,
fill: false,
backgroundColor: 'rgb(54, 162, 235)',
borderColor: 'rgba(54, 162, 235, 0.2)',
yAxisID: 'y-axis-1',
},
],
};
setdataCostProyek(costProyek)
const valueStatusProyek = status_proyek ? status_proyek.map(res => res.total) : []
const statusProyek = {
labels: ['Aman', 'Alert', 'Critical'],
datasets: [
{
label: '# of Votes',
data: valueStatusProyek,
backgroundColor: [
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 99, 132, 0.2)',
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(255, 99, 132, 1)',
],
borderWidth: 1,
},
],
};
setDataStatusProyek(statusProyek)
}
const getProyek = async () => {
const URL = `${BASE_SIMPRO}/proyek/list?start=0&length=-1&orderby=nama&asc=true`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
if (result.data.code !== 200) {
NotificationManager.error('Gaga Menambah Data!!', 'Failed');
}
setProjectTree(result.data.data);
const arr = result.data.data.map(res => res.id)
setCheckedKeysProjectTree(arr)
}
const renderDailyInfo = () => {
return (
<>
<div className="daily-info-card" style={{ backgroundColor: IZIN_COLOR, cursor: 'pointer' }} >
<p className="number-style1">{dataDashboard ? dataDashboard.panic_button : 0}</p>
<p style={{ color: "#FFFFFF", fontWeight: "bold" }}>PANIC BUTTON</p>
</div>
<div className="daily-info-card" style={{ backgroundColor: GREEN_COLOR, cursor: 'pointer' }} >
<p className="number-style1">{dataDashboard ? dataDashboard.waspang_status.presensi : 0}</p>
<p style={{ color: "#FFFFFF", fontWeight: "bold" }}>WASPANG ACTIVE</p>
</div>
<div className="daily-info-card" style={{ backgroundColor: ORANGE_COLOR, cursor: 'pointer' }} >
<p className="number-style1">{dataDashboard ? dataDashboard.waspang_status.absensi : 0}</p>
<p style={{ color: "#FFFFFF", fontWeight: "bold" }}>WASPANG ABSENT</p>
</div>
</>
)
}
const handleClickChart = param => {
if (!param.length) return;
const { _datasetIndex, _index } = param[0];
const data = dataPersentaseProyek.datasets[_datasetIndex].label
setOpenModalTable(true)
}
const handleClickProyek = id => {
const arr = [...checkedKeysProjectTree]
const idx = arr.indexOf(id)
if (idx == -1) {
arr.push(id)
} else {
arr.splice(idx, 1)
}
setCheckedKeysProjectTree(arr)
}
return (
<>
<SiopasMap />
</>
);
}
export default DashboardSimpro;
Loading…
Cancel
Save