Browse Source

WIP: Dashboard all project summary

pull/2/head
Yusuf 2 years ago
parent
commit
27fd6ee8dd
  1. 2
      package.json
  2. 198
      src/routes.js
  3. 128
      src/views/DashboardPMO/Dashboard.css
  4. 41
      src/views/DashboardPMO/PieChart.js
  5. 152
      src/views/DashboardPMO/index.js

2
package.json

@ -12,6 +12,7 @@
"url": "https://git.oslog.id/iu/simpro-website.git"
},
"dependencies": {
"@ant-design/plots": "^1.1.1",
"@coreui/coreui": "^2.1.12",
"@coreui/icons": "0.3.0",
"@coreui/react": "^2.5.1",
@ -25,6 +26,7 @@
"@iconify/icons-uil": "^1.0.6",
"@iconify/react": "^1.1.1",
"@nicholasadamou/react-iframe": "^1.0.3",
"@terrestris/ol-util": "^7.2.0",
"@terrestris/react-geo": "^12.0.0",
"alasql": "^1.7.3",
"antd": "^4.16.13",

198
src/routes.js

@ -1,98 +1,100 @@
import React from 'react';
const Absensi = React.lazy(() => import('./views/Master/MasterAbsensi'));
const BaseLayers = React.lazy(() => import('./views/BaseLayers'));
const Broadcast = React.lazy(() => import('./views/Master/MasterBroadcast'));
const ChecklistK3 = React.lazy(() => import('./views/SimproV2/ChecklistK3'));
const Closing = React.lazy(() => import('./views/SimproV2/Closing'));
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 DashboardSimpro = React.lazy(() => import('./views/DashboardSimpro'));
const Divisi = React.lazy(() => import('./views/SimproV2/Divisi'));
const DivisiKaryawan = React.lazy(() => import('./views/Master/MasterTipeKaryawan'));
const Gantt = React.lazy(() => import('./views/SimproV2/Gantt'));
const Izin = React.lazy(() => import('./views/Master/MasterCuti'));
const K3 = React.lazy(() => import('./views/Report/k3'));
const LaporanAlert = React.lazy(() => import('./views/Report/alert'));
const LaporanTugas = React.lazy(() => import('./views/Master/MasterTask'));
const Layer = React.lazy(() => import('./views/Layers/Layer'));
const Layers = React.lazy(() => import('./views/Layers/Layers'));
const Lembur = React.lazy(() => import('./views/Master/MasterLembur'));
const MapConfig = React.lazy(() => import('./views/MapConfig'));
const Menu = React.lazy(() => import('./views/Master/MasterMenu'));
const OfficeHours = React.lazy(() => import('./views/Master/MasterOfficeHours'));
const Organization = React.lazy(() => import('./views/Master/MasterOrganization'));
const PanicButton = React.lazy(() => import('./views/SimproV2/PanicButton'));
const PlanningHarian = React.lazy(() => import('./views/SimproV2/PlanningHarian'));
const Presensi = React.lazy(() => import('./views/SimproV2/Presence'));
const ProjectRole = React.lazy(() => import('./views/Master/RoleProject'));
const ProjectType = React.lazy(() => import('./views/SimproV2/ProjectType'));
const Proyek = React.lazy(() => import('./views/Master/Proyek'));
const RateCost = React.lazy(() => import('./views/SimproV2/RateCost'));
const ResourceMaterial = React.lazy(() => import('./views/SimproV2/ResourceMaterial'));
const ResourceTools = React.lazy(() => import('./views/SimproV2/ResourceTools'));
const ResourceWorker = React.lazy(() => import('./views/SimproV2/ResourceWorker'));
const Roles = React.lazy(() => import('./views/Master/MasterRoles'));
const Satuan = React.lazy(() => import('./views/SimproV2/Satuan'));
const ScheduleShift = React.lazy(() => import('./views/SimproV2/ScheduleShift'));
const Shift = React.lazy(() => import('./views/SimproV2/Shift'));
const TestGantt = React.lazy(() => import('./views/testgantt'));
const UserAdmin = React.lazy(() => import('./views/Master/UserAdmin'));
const UserShift = React.lazy(() => import('./views/SimproV2/UserShift'));
const routes = [
{ path: '/', exact: true, name: 'Home' },
{ path: '/dashboard', name: 'Dashboard', component: DashboardSimpro },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },
{ 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 },
{ path: '/tools-resource', exact: true, name: 'Tools Resource', component: ResourceTools },
{ path: '/control-monitoring', exact: true, name: 'Control Monitoring', component: ControlMonitoring },
{ path: '/control-monitoring-gantt', exact: true, name: 'Control Monitoring Gantt', component: ControlMonitoringGantt },
{ path: '/presensi-resource', exact: true, name: 'Presensi Resource', component: Presensi },
{ path: '/absensi-resource', exact: true, name: 'Absensi Resource', component: Absensi },
{ path: '/laporan-k3', exact: true, name: 'Laporan K3', component: K3 },
{ path: '/broadcast', exact: true, name: 'Broadcast', component: Broadcast },
{ path: '/panic-button', exact: true, name: 'Tombol Darurat', component: PanicButton },
{ path: '/closing', exact: true, name: 'Closing', component: Closing },
{ path: '/menu', exact: true, name: 'Menu', component: Menu },
{ path: '/roles', exact: true, name: 'Roles', component: Roles },
{ path: '/project-role', exact: true, name: 'Project Role', component: ProjectRole },
{ path: '/project-type', exact: true, name: 'Project Type', component: ProjectType },
{ path: '/divisi', exact: true, name: 'Divisi', component: Divisi },
{ path: '/satuan', exact: true, name: 'Satuan', component: Satuan },
{ path: '/config-alert', exact: true, name: 'Config Alert', component: ConfigAlert },
{ path: '/checklist-k3', exact: true, name: 'Checklist K3', component: ChecklistK3 },
{ path: '/absensi', exact: true, name: 'Absensi', component: Absensi },
{ path: '/divisi-karyawan', exact: true, name: 'Divisi Karyawan', component: DivisiKaryawan },
{ path: '/izin', exact: true, name: 'Izin', component: Izin },
{ path: '/laporan-alert', exact: true, name: 'Laporan Alert', component: LaporanAlert },
{ path: '/laporan-tugas-karyawan', exact: true, name: 'Laporan Tugas Karyawan', component: LaporanTugas },
{ path: '/lembur', exact: true, name: 'Lembur', component: Lembur },
{ path: '/map/baselayers', exact: true, name: 'Base Layers', component: BaseLayers },
{ path: '/map/config', exact: true, name: 'Config', component: MapConfig },
{ path: '/map/layers', exact: true, name: 'Layers', component: Layers },
{ path: '/map/layers/:id', exact: true, name: 'Layer Details', component: Layer },
{ path: '/office-hours', exact: true, name: 'Jam Kerja', component: OfficeHours },
{ path: '/organization', exact: true, name: 'Organisasi', component: Organization },
{ path: '/planning-harian', exact: true, name: 'Planning Harian', component: PlanningHarian },
{ path: '/presensi', exact: true, name: 'Presensi', component: Presensi },
{ path: '/proyek', exact: true, name: 'Created Project', component: Proyek },
{ path: '/proyek-gantt', exact: true, name: 'Gantt Chart Proyek', component: TestGantt },
{ path: '/rate-cost', exact: true, name: 'Rate Cost', component: RateCost },
{ path: '/schedule-shift', exact: true, name: 'Schedule Shift', component: ScheduleShift },
{ path: '/user-admin', exact: true, name: 'User Admin', component: UserAdmin },
{ path: '/user-shift', exact: true, name: 'Shift', component: UserShift },
{ path: '/working-hour', exact: true, name: 'Working Hour', component: Shift },
];
export default routes;
import React from 'react';
const Absensi = React.lazy(() => import('./views/Master/MasterAbsensi'));
const BaseLayers = React.lazy(() => import('./views/BaseLayers'));
const Broadcast = React.lazy(() => import('./views/Master/MasterBroadcast'));
const ChecklistK3 = React.lazy(() => import('./views/SimproV2/ChecklistK3'));
const Closing = React.lazy(() => import('./views/SimproV2/Closing'));
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 DashboardSimpro = React.lazy(() => import('./views/DashboardSimpro'));
const DashboardPMO = React.lazy(() => import('./views/DashboardPMO'));
const Divisi = React.lazy(() => import('./views/SimproV2/Divisi'));
const DivisiKaryawan = React.lazy(() => import('./views/Master/MasterTipeKaryawan'));
const Gantt = React.lazy(() => import('./views/SimproV2/Gantt'));
const Izin = React.lazy(() => import('./views/Master/MasterCuti'));
const K3 = React.lazy(() => import('./views/Report/k3'));
const LaporanAlert = React.lazy(() => import('./views/Report/alert'));
const LaporanTugas = React.lazy(() => import('./views/Master/MasterTask'));
const Layer = React.lazy(() => import('./views/Layers/Layer'));
const Layers = React.lazy(() => import('./views/Layers/Layers'));
const Lembur = React.lazy(() => import('./views/Master/MasterLembur'));
const MapConfig = React.lazy(() => import('./views/MapConfig'));
const Menu = React.lazy(() => import('./views/Master/MasterMenu'));
const OfficeHours = React.lazy(() => import('./views/Master/MasterOfficeHours'));
const Organization = React.lazy(() => import('./views/Master/MasterOrganization'));
const PanicButton = React.lazy(() => import('./views/SimproV2/PanicButton'));
const PlanningHarian = React.lazy(() => import('./views/SimproV2/PlanningHarian'));
const Presensi = React.lazy(() => import('./views/SimproV2/Presence'));
const ProjectRole = React.lazy(() => import('./views/Master/RoleProject'));
const ProjectType = React.lazy(() => import('./views/SimproV2/ProjectType'));
const Proyek = React.lazy(() => import('./views/Master/Proyek'));
const RateCost = React.lazy(() => import('./views/SimproV2/RateCost'));
const ResourceMaterial = React.lazy(() => import('./views/SimproV2/ResourceMaterial'));
const ResourceTools = React.lazy(() => import('./views/SimproV2/ResourceTools'));
const ResourceWorker = React.lazy(() => import('./views/SimproV2/ResourceWorker'));
const Roles = React.lazy(() => import('./views/Master/MasterRoles'));
const Satuan = React.lazy(() => import('./views/SimproV2/Satuan'));
const ScheduleShift = React.lazy(() => import('./views/SimproV2/ScheduleShift'));
const Shift = React.lazy(() => import('./views/SimproV2/Shift'));
const TestGantt = React.lazy(() => import('./views/testgantt'));
const UserAdmin = React.lazy(() => import('./views/Master/UserAdmin'));
const UserShift = React.lazy(() => import('./views/SimproV2/UserShift'));
const routes = [
{ path: '/', exact: true, name: 'Home' },
{ path: '/dashboard', name: 'Dashboard', component: DashboardSimpro },
{ path: '/dashboardpmo', name: 'Dashboard', component: DashboardPMO },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },
{ 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 },
{ path: '/tools-resource', exact: true, name: 'Tools Resource', component: ResourceTools },
{ path: '/control-monitoring', exact: true, name: 'Control Monitoring', component: ControlMonitoring },
{ path: '/control-monitoring-gantt', exact: true, name: 'Control Monitoring Gantt', component: ControlMonitoringGantt },
{ path: '/presensi-resource', exact: true, name: 'Presensi Resource', component: Presensi },
{ path: '/absensi-resource', exact: true, name: 'Absensi Resource', component: Absensi },
{ path: '/laporan-k3', exact: true, name: 'Laporan K3', component: K3 },
{ path: '/broadcast', exact: true, name: 'Broadcast', component: Broadcast },
{ path: '/panic-button', exact: true, name: 'Tombol Darurat', component: PanicButton },
{ path: '/closing', exact: true, name: 'Closing', component: Closing },
{ path: '/menu', exact: true, name: 'Menu', component: Menu },
{ path: '/roles', exact: true, name: 'Roles', component: Roles },
{ path: '/project-role', exact: true, name: 'Project Role', component: ProjectRole },
{ path: '/project-type', exact: true, name: 'Project Type', component: ProjectType },
{ path: '/divisi', exact: true, name: 'Divisi', component: Divisi },
{ path: '/satuan', exact: true, name: 'Satuan', component: Satuan },
{ path: '/config-alert', exact: true, name: 'Config Alert', component: ConfigAlert },
{ path: '/checklist-k3', exact: true, name: 'Checklist K3', component: ChecklistK3 },
{ path: '/absensi', exact: true, name: 'Absensi', component: Absensi },
{ path: '/divisi-karyawan', exact: true, name: 'Divisi Karyawan', component: DivisiKaryawan },
{ path: '/izin', exact: true, name: 'Izin', component: Izin },
{ path: '/laporan-alert', exact: true, name: 'Laporan Alert', component: LaporanAlert },
{ path: '/laporan-tugas-karyawan', exact: true, name: 'Laporan Tugas Karyawan', component: LaporanTugas },
{ path: '/lembur', exact: true, name: 'Lembur', component: Lembur },
{ path: '/map/baselayers', exact: true, name: 'Base Layers', component: BaseLayers },
{ path: '/map/config', exact: true, name: 'Config', component: MapConfig },
{ path: '/map/layers', exact: true, name: 'Layers', component: Layers },
{ path: '/map/layers/:id', exact: true, name: 'Layer Details', component: Layer },
{ path: '/office-hours', exact: true, name: 'Jam Kerja', component: OfficeHours },
{ path: '/organization', exact: true, name: 'Organisasi', component: Organization },
{ path: '/planning-harian', exact: true, name: 'Planning Harian', component: PlanningHarian },
{ path: '/presensi', exact: true, name: 'Presensi', component: Presensi },
{ path: '/proyek', exact: true, name: 'Created Project', component: Proyek },
{ path: '/proyek-gantt', exact: true, name: 'Gantt Chart Proyek', component: TestGantt },
{ path: '/rate-cost', exact: true, name: 'Rate Cost', component: RateCost },
{ path: '/schedule-shift', exact: true, name: 'Schedule Shift', component: ScheduleShift },
{ path: '/user-admin', exact: true, name: 'User Admin', component: UserAdmin },
{ path: '/user-shift', exact: true, name: 'Shift', component: UserShift },
{ path: '/working-hour', exact: true, name: 'Working Hour', component: Shift },
];
export default routes;

128
src/views/DashboardPMO/Dashboard.css

@ -0,0 +1,128 @@
.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

@ -0,0 +1,41 @@
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;

152
src/views/DashboardPMO/index.js

@ -0,0 +1,152 @@
import '../../../node_modules/react-grid-layout/css/styles.css';
import '../../../node_modules/react-resizable/css/styles.css';
import './Dashboard.css';
import PieChart from './PieChart';
import { BASE_OSPRO } from '../../const/ApiConst';
import ContentLoader from "react-content-loader"
import React, { useEffect, useState } from 'react';
import axios from 'axios'
import moment from 'moment';
import numeral from 'numeral';
import { Table, Tree, Row, Col, Space, Card} from 'antd';
import { Pie } from '@ant-design/plots';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { formatRupiah, DATE_TIME_FORMAT } from '../../const/CustomFunc.js';
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"Access-Control-Allow-Origin": "*"
}
}
const Dashboard = () => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
}
}
const [dataTable, setDataTable] = useState([])
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) {
NotificationManager.error('Belum ada data proyek!', 'Failed');
}
console.log("res ", result.data.data)
// const arr = result.data.data.map((res) => {
// console.log("insd", res)
// return res
// });
setDataTable(result.data.data);
}
const columns = [
{
title: 'Project',
dataIndex: 'nama',
key: 'nama',
render: (text) => <a>{text}</a>,
},
{
title: 'Planned Interval',
dataIndex: 'plannedInterval',
key: 'plannedInterval',
},
{
title: 'Planned Cost',
dataIndex: 'plannedCost',
key: 'plannedCost',
},
{
title: 'Actual Cost',
dataIndex: 'actualCost',
key: 'actualCost',
},
{
title: 'Cost Variance',
dataIndex: 'costVariance',
key: 'costVariance',
},
{
title: 'Cost Health',
dataIndex: 'costHealth',
key: 'costHealth',
},
{
title: 'Schedule Health',
dataIndex: 'scheduleHealth',
key: 'scheduleHealth',
},
{
title: 'Progress',
dataIndex: 'progress',
key: 'progress',
},
];
useEffect(() => {
getProjects();
}, [])
return (
<>
<Row gutter={[16, 16]}>
<Col span={6} >
<Card
size="small"
title="Total Project"
align="center"
style={{
width: 300,
}}
>
<p align="center">5</p>
</Card>
</Col>
<Col span={6} >
<Card
size="small"
title="Total Project Cost"
align="center"
style={{
width: 300,
}}
>
<p align="center">5</p>
</Card>
</Col>
<Col span={6} >
<Card
size="small"
title="Cost Variance"
align="center"
style={{
width: 300,
}}
>
<p align="center">5</p>
</Card>
</Col>
<Col span={6} >
<PieChart />
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={24}>
<Table columns={columns} dataSource={dataTable} />
</Col>
</Row>
</>
);
}
export default Dashboard;
Loading…
Cancel
Save