From 27fd6ee8dd01275907834a082ea4df5cfce4fbaf Mon Sep 17 00:00:00 2001 From: Yusuf Date: Tue, 26 Jul 2022 23:05:09 +0700 Subject: [PATCH] WIP: Dashboard all project summary --- package.json | 2 + src/routes.js | 198 ++++++++++++++------------- src/views/DashboardPMO/Dashboard.css | 128 +++++++++++++++++ src/views/DashboardPMO/PieChart.js | 41 ++++++ src/views/DashboardPMO/index.js | 152 ++++++++++++++++++++ 5 files changed, 423 insertions(+), 98 deletions(-) create mode 100644 src/views/DashboardPMO/Dashboard.css create mode 100644 src/views/DashboardPMO/PieChart.js create mode 100644 src/views/DashboardPMO/index.js diff --git a/package.json b/package.json index 42aeab6..58a2258 100644 --- a/package.json +++ b/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", diff --git a/src/routes.js b/src/routes.js index b5851ca..d350796 100644 --- a/src/routes.js +++ b/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; diff --git a/src/views/DashboardPMO/Dashboard.css b/src/views/DashboardPMO/Dashboard.css new file mode 100644 index 0000000..e1d4e91 --- /dev/null +++ b/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; +} diff --git a/src/views/DashboardPMO/PieChart.js b/src/views/DashboardPMO/PieChart.js new file mode 100644 index 0000000..a24d3a6 --- /dev/null +++ b/src/views/DashboardPMO/PieChart.js @@ -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 ; +}; + +export default PieChart; diff --git a/src/views/DashboardPMO/index.js b/src/views/DashboardPMO/index.js new file mode 100644 index 0000000..63d2d24 --- /dev/null +++ b/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) => {text}, + }, + { + 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 ( + <> + + + +

5

+
+ + + +

5

+
+ + + +

5

+
+ + + + +
+ + + + + + + + ); +} + +export default Dashboard;