diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0ee6dac
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,10 @@
+# FROM node:8.10-alpine
+FROM node:12
+WORKDIR /usr/src/app
+COPY package.json ./
+# RUN apt install git python3
+RUN npm install --only=production
+RUN npm i react@16.14.0
+RUN npm audit fix
+COPY . .
+CMD [ "npm", "start" ]
\ No newline at end of file
diff --git a/README.md b/README.md
index 69c10f8..a020c70 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,17 @@
-## GeoHR Installation
+## ADW-FrontEnd Installation
``` bash
# clone the repo
-$ git clone https://git.oslog.id/iu/GeoHR-website.git
+$ git clone https://git.oslog.id/OSPRO/ADW-FrontEnd
# go into app's directory
-$ cd GeoHR-website
+$ cd ADW-FrontEnd
# install app's dependencies
$ npm install
# fix dependency
-$ npm fix audit
+$ npm audit fix
# start project
$ npm start
@@ -21,7 +21,7 @@ $ npm start
Here is the [API Documentation](https://git.oslog.id/iu/GeoHR-website/src/branch/master/API_GeoHR_docs.md).
-## GeoHR Build to Production
+## ADW-FrontEnd Build to Production
``` bash
# build the project
@@ -47,11 +47,18 @@ Archive: build.zip
replace favicon.ico? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
inflating: favicon.ico
...
-
+
# remove build.zip file
$ rm -rf build.zip
# DONE !
# Open siopas.co.id/geohr
# Don't forget to shift+reload on browser
+```
+
+## Docker
+
+```bash
+docker build --tag react .
+docker run -it -p 3000:3000 react:latest
```
\ No newline at end of file
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/const/CustomFunc.js b/src/const/CustomFunc.js
index 9fdff08..ad8a75a 100644
--- a/src/const/CustomFunc.js
+++ b/src/const/CustomFunc.js
@@ -340,3 +340,8 @@ export const renderLabelStatus = (text) => {
}
return label;
}
+
+export const formatRibuanDecimal = (n) => {
+ let parts=n.toString().split(".");
+ return "Rp. " + parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ".") + (parts[1] ? "," + parts[1] : "");
+}
diff --git a/src/routes.js b/src/routes.js
index b5851ca..570b4ae 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: '/dashboardold', name: 'Dashboard', component: DashboardSimpro },
+ { path: '/dashboard', 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..822d80c
--- /dev/null
+++ b/src/views/DashboardPMO/index.js
@@ -0,0 +1,114 @@
+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 { formatRibuanDecimal, DATE_TIME_FORMAT } from '../../const/CustomFunc.js';
+import { Badge } from 'reactstrap';
+
+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)
+ 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',
+ render: (text) => { formatRibuanDecimal(text) },
+ },
+ {
+ title: 'Actual Cost',
+ dataIndex: 'actualCost',
+ key: 'actualCost',
+ render: (text) => { formatRibuanDecimal(text) },
+ },
+ {
+ title: 'Cost Variance',
+ dataIndex: 'costVariance',
+ key: 'costVariance',
+ render: (text) => { formatRibuanDecimal(text) },
+ },
+ {
+ title: 'Cost Health',
+ dataIndex: 'costHealth',
+ key: 'costHealth',
+ render: (text) => {
+ if(text == "on-budget") {
+ return On Budget
+ } else if(text == "warning") {
+ return Warning
+ } else {
+ return Danger
+ }
+ }
+ },
+ {
+ title: 'Progress',
+ dataIndex: 'progress',
+ key: 'progress',
+ },
+ ];
+
+ useEffect(() => {
+ getProjects();
+ }, [])
+
+
+ return (
+ <>
+
+
+
+
+
+ >
+
+ );
+}
+
+export default Dashboard;