root 1 year ago
parent
commit
8e76953919
  1. 4
      src/routes.js
  2. 20
      src/views/Dashboard/DashboardBOD.js
  3. 977
      src/views/Dashboard/DashboardProjectCarousell.js
  4. 4
      src/views/SimproV2/CreatedProyek/DialogFormProyek.js
  5. 18
      src/views/SimproV2/CreatedProyek/index.js
  6. 2
      src/views/SimproV2/Gantt/GanttFrame.js

4
src/routes.js

@ -47,16 +47,16 @@ const UserShift = React.lazy(() => import('./views/SimproV2/UserShift'));
const DashboardBOD = React.lazy(() => import('./views/Dashboard/DashboardBOD')); const DashboardBOD = React.lazy(() => import('./views/Dashboard/DashboardBOD'));
const DashboardCustomer = React.lazy(() => import('./views/Dashboard/DashboardCustomer')); const DashboardCustomer = React.lazy(() => import('./views/Dashboard/DashboardCustomer'));
const DashboardProject = React.lazy(() => import('./views/Dashboard/DashboardProject')); const DashboardProject = React.lazy(() => import('./views/Dashboard/DashboardProject'));
const DashboardProjectCarousell = React.lazy(() => import('./views/Dashboard/DashboardProjectCarousell'));
const MapMonitoring = React.lazy(() => import('./views/MapMonitoring')); const MapMonitoring = React.lazy(() => import('./views/MapMonitoring'));
const Settings = React.lazy(() => import('./views/SimproV2/Settings')); const Settings = React.lazy(() => import('./views/SimproV2/Settings'));
const CompanyManagement = React.lazy(() => import('./views/Master/MasterCompany')) const CompanyManagement = React.lazy(() => import('./views/Master/MasterCompany'))
const routes = [ const routes = [
{ path: '/', exact: true, name: 'Home' }, { path: '/', exact: true, name: 'Home' },
// { path: '/dashboard', name: 'Dashboard', component: Dashboard},
{ path: '/dashboard', name: 'DashboardBOD', component: DashboardBOD }, { path: '/dashboard', name: 'DashboardBOD', component: DashboardBOD },
// { path: '/dashboard-customer/:PROJECT_ID/:GANTT_ID', name: 'DashboardCustomer', component: DashboardCustomer },
{ path: '/dashboard-customer/:PROJECT_ID/:GANTT_ID/:SCURVE', name: 'DashboardCustomer', component: DashboardCustomer }, { path: '/dashboard-customer/:PROJECT_ID/:GANTT_ID/:SCURVE', name: 'DashboardCustomer', component: DashboardCustomer },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID', exact: true, name: 'Dashboard Project', component: DashboardProject }, { path: '/dashboard-project/:PROJECT_ID/:GANTT_ID', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/dashboard-project-carousell', exact: true, name: 'Dashboard Project Carousell', component: DashboardProjectCarousell },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID/:SCURVE', exact: true, name: 'Dashboard Project', component: DashboardProject }, { path: '/dashboard-project/:PROJECT_ID/:GANTT_ID/:SCURVE', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek }, { path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },
{ path: '/projects/:id/import/activity', exact: true, name: 'Gantt Import Activity', component: GanttImportActivity }, { path: '/projects/:id/import/activity', exact: true, name: 'Gantt Import Activity', component: GanttImportActivity },

20
src/views/Dashboard/DashboardBOD.js

@ -12,6 +12,7 @@ import ContentLoader from 'react-content-loader';
import toRupiah from '@develoka/angka-rupiah-js'; import toRupiah from '@develoka/angka-rupiah-js';
import Icon from '@iconify/react'; import Icon from '@iconify/react';
import { HealthByBudget, HealthBySchedule } from './Components'; import { HealthByBudget, HealthBySchedule } from './Components';
import { Link } from 'react-router-dom';
const DashboardBOD = (props) => { const DashboardBOD = (props) => {
let role_id = '', user_id='',isLogin='',token=''; let role_id = '', user_id='',isLogin='',token='';
@ -20,13 +21,11 @@ const DashboardBOD = (props) => {
user_id = props.location.state.user_id; user_id = props.location.state.user_id;
token = props.location.state.token; token = props.location.state.token;
isLogin = props.location.state.isLogin; isLogin = props.location.state.isLogin;
console.log('props.location.state success');
} else { } else {
role_id = localStorage.getItem("role_id"); role_id = localStorage.getItem("role_id");
user_id = localStorage.getItem("user_id"); user_id = localStorage.getItem("user_id");
token = localStorage.getItem("token"); token = localStorage.getItem("token");
isLogin = localStorage.getItem("isLogin"); isLogin = localStorage.getItem("isLogin");
console.error('undefined in props.location.state');
} }
const HEADER = { const HEADER = {
headers: { headers: {
@ -427,11 +426,20 @@ const DashboardBOD = (props) => {
<div style={{ color: '#888888', fontSize: 12 }}>Total Project Expenditure from on-going project.</div> <div style={{ color: '#888888', fontSize: 12 }}>Total Project Expenditure from on-going project.</div>
</div> </div>
{PROJECT_EXPENDITURE ? {PROJECT_EXPENDITURE ?
<div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }} onClick={handleGetDetailExpenditure}> <>
<div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, cursor: 'pointer', fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}> <div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }} onClick={handleGetDetailExpenditure}>
Detailed View <div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, cursor: 'pointer', fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}>
Detailed View
</div>
</div> </div>
</div> <div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Link to="/dashboard-project-carousell" style={{ textDecoration: 'none' }}>
<div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, cursor: 'pointer', fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}>
View All Gantt
</div>
</Link>
</div>
</>
: :
<div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }}> <div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}>Detailed View</div> <div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}>Detailed View</div>

977
src/views/Dashboard/DashboardProjectCarousell.js

@ -0,0 +1,977 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import axios from "axios";
import { Row, Col, Button, Input,Spin } from "antd";
import {
CardDashboard,
CardExpenditure,
CardScheduleHealthPerDivision,
} from "../../components/CardDashboard/CardDashboard";
import L from "leaflet";
import "../../assets/css/customscroll.css";
import moment from "moment";
import { renderFormatRupiah } from "../../const/CustomFunc";
import { BASE_OSPRO, BASE_OSPRO_FE, VERSION_GANTT_SEARCH } from "../../const/ApiConst";
import { SendOutlined } from "@ant-design/icons";
import {
NotificationContainer,
NotificationManager,
} from "react-notifications";
import {
Carousel,
CarouselItem,
CarouselControl,
CarouselIndicators,
CarouselCaption,
} from 'reactstrap';
import ContentLoader from "react-content-loader";
import {
BehindTaskItem,
Comment,
HealthByBudget,
HealthBySchedule,
ListLoader,
PopupContent,
ProgressActualBar,
ProgressPlanningBar,
SingleTextLoader,
} from "./Components";
import { Fab, Action } from "react-tiny-fab";
import "react-tiny-fab/dist/styles.css";
import { useHistory, useLocation, useParams } from "react-router-dom";
const { TextArea } = Input;
const styles = {
cardContainer: {
backgroundColor: "#F8F8F8",
margin: 2,
paddingLeft: 20,
paddingRight: 20,
paddingTop: 10,
},
cardHeaderContainer: {
display: "flex",
flexDirection: "row",
marginBottom: 10,
},
cardChartContainer: {
position: "relative",
height: "21vh",
margin: "auto",
paddingBottom: 10,
justifyContent: "center",
},
cardTitle: { color: "#444444", fontSize: 16, fontWeight: "bold" },
cardSubtitle: { color: "#888888", fontSize: 12 },
};
const center = {
lat: -6.2,
lng: 106.816666,
};
const DashboardProject = (args) => {
const token = localStorage.getItem("token");
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
const { PROJECT_ID } = useParams();
const mapRef = useRef();
const [mymap, setMymap] = useState(null);
const [activeTabIdx, setActiveTabIdx] = useState(0);
const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0);
const [planningProgress, setPlanningProgress] = useState(0);
const [actualProgress, setActualProgress] = useState(0);
const [isReadyComments, setIsReadyComments] = useState(false);
const [isSendingComment, setIsSendingComment] = useState(false);
const [isReadyProjectDetail, setIsReadyProjectDetail] = useState(false);
const [isReadySCurve, setIsReadySCurve] = useState(false);
const [isReadyGantt, setIsReadyGantt] = useState(false);
const [reportDistribution, setReportDistribution] = useState([]);
const [isReadyOverdueActivities, setIsReadyOverdueActivities] =
useState(false);
const [healthBySchedule, setHealthBySchedule] = useState("-");
const [allDataMaster, sourceData] = useState([]);
const [isHierarchy, setIsHierarchy] = useState(false);
let history = useHistory();
// Carousell
const [activeIndex, setActiveIndex] = useState(0);
const [animating, setAnimating] = useState(false);
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
getAllData();
},[]);
useEffect(() => {
if (activeTabIdx === 1) {
initMap();
}
}, [activeTabIdx]);
const getAllData = async () => {
setIsReadyProjectDetail(false);
setIsReadySCurve(false)
setIsReadySCurve(false);
const URL = `${BASE_OSPRO}/api/project-carausell`;
const result = await axios
.get(URL, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (!result) {
NotificationManager.error(`Could not connect to internet.`, "Failed");
setIsReadyProjectDetail(true);
setIsReadySCurve(true);
setLoading(false);
return;
}
if (result.status !== 200) {
NotificationManager.error(
`Get project detail failed, ${result.data.message}`,
"Failed"
);
setIsReadyProjectDetail(true);
setIsReadySCurve(true);
setLoading(false);
return;
} else if (result.status == 200 && result.data.data) {
const dataResault = result.data.data;
console.log("Resault Data",dataResault);
sourceData(dataResault);
setIsReadyGantt(true);
setIsReadyProjectDetail(true);
// // SCurve
// let statusHealthBySchedule = "on-schedule";
// let selisihProgress = 0;
// dataResault.map((item, idx) => {
// item.SCurve.map((itemSCurve, idx) => {
// let planningProgress = 0;
// let actualProgress = 0;
// let now = new Date().toISOString().slice(0, 10);
// let dates = itemSCurve.data?.date;
// let n = dates.findIndex(
// (element) => new Date(now) < new Date(element)
// );
// if (
// itemSCurve.length > 0 &&
// itemSCurve.data?.percentagePlan &&
// itemSCurve.data?.percentagePlan.length > 0
// ) {
// planningProgress = itemSCurve.data?.percentagePlan[n];
// if (n < 0) {
// planningProgress = 100;
// }
// setPlanningProgress(planningProgress);
// }
// if (
// itemSCurve.length > 0 &&
// itemSCurve.data?.percentageReal &&
// itemSCurve.data?.percentageReal.length > 0
// ) {
// actualProgress =
// itemSCurve.data?.percentageReal[
// itemSCurve.data?.percentageReal.length - 1
// ];
// setActualProgress(actualProgress);
// }
// });
// });
// selisihProgress = planningProgress - actualProgress;
// if (selisihProgress > 0 && selisihProgress <= 5) {
// statusHealthBySchedule = "warning";
// } else if (selisihProgress > 5) {
// statusHealthBySchedule = "danger";
// }
// setHealthBySchedule(statusHealthBySchedule);
setIsReadySCurve(true);
// setHierarchy
setIsHierarchy(true);
// Get Overdue
setIsReadyOverdueActivities(true);
// Distribution
setReportDistribution(dataResault);
// loading
setLoading(false);
}
};
const initMap = () => {
let mymap = L.map("map-area", {
center: center,
zoom: 13,
});
setMymap(mymap);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(mymap);
};
useEffect(() => {
if (mymap) {
reportDistribution.map((item, idx) => {
if (item.report_distribution.length > 0) {
item.report_distribution.map((itemDistribution, idx) => {
L.marker([itemDistribution.lat, itemDistribution.lon])
.addTo(mymap)
.bindPopup(PopupContent(itemDistribution));
})
}
});
}
}, [mymap, reportDistribution]);
useEffect(() => {
// Add event listener for receiving messages from the iframe
window.addEventListener("message", handleIframeMessage);
// Clean up the event listener on component unmount
return () => {
window.removeEventListener("message", handleIframeMessage);
};
}, []);
const handleIframeMessage = (event) => {
if (event.data && event.data.action === "getUrl") {
const childUrl = window.location.href;
// Send the URL back to the iframe
event.source.postMessage(
{ action: "sendUrl", url: childUrl, isHierarchy: isHierarchy },
event.origin
);
}
};
const next = () => {
if (animating) return;
const nextIndex = activeIndex === allDataMaster.length - 1 ? 0 : activeIndex + 1;
setActiveIndex(nextIndex);
};
const previous = () => {
if (animating) return;
const nextIndex = activeIndex === 0 ? allDataMaster.length - 1 : activeIndex - 1;
setActiveIndex(nextIndex);
};
const goToIndex = (newIndex) => {
if (animating) return;
setActiveIndex(newIndex);
};
const slides = allDataMaster.map((item, index) => {
let URL_GANTT = "";
let version_gantt = "";
item.project.gantt.map((itemGantt, index) => {
URL_GANTT = `http://localhost:8444/adw-gantt/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${itemGantt.gantt_id}&proyek_id=${itemGantt.proyek_id}&token=${token}&ro=1`;
version_gantt = itemGantt.name_version
});
const today = moment();
const assignedList = item.assigned
.filter((itemAssigned) =>
today.isBetween(moment(itemAssigned.start_date), moment(itemAssigned.end_date))
)
.map((itemMap) => itemMap.user_id);
// SCurve
let statusHealthBySchedule = "on-schedule";
let selisihProgress = 0;
let SetplanningProgress = 0;
let SetactualProgress = 0;
let now = new Date().toISOString().slice(0, 10);
let dates = item.SCurve[0].data?.date;
let n = dates.findIndex(
(element) => new Date(now) < new Date(element)
);
if (
item.SCurve[0].length > 0 &&
item.SCurve[0].data?.percentagePlan &&
item.SCurve[0].data?.percentagePlan.length > 0
) {
SetplanningProgress = item.SCurve[0].data?.percentagePlan[n];
if (n < 0) {
SetplanningProgress = 100;
}
}
if (
item.SCurve[0].length > 0 &&
item.SCurve[0].data?.percentageReal &&
item.SCurve[0].data?.percentageReal.length > 0
) {
SetactualProgress =
item.SCurve[0].data?.percentageReal[
item.SCurve[0].data?.percentageReal.length - 1
];
}
selisihProgress = SetplanningProgress - SetactualProgress;
if (selisihProgress > 0 && selisihProgress <= 5) {
statusHealthBySchedule = "warning";
} else if (selisihProgress > 5) {
statusHealthBySchedule = "danger";
}
return (
<CarouselItem
onExiting={() => setAnimating(true)}
onExited={() => setAnimating(false)}
key={parseInt(item.key)}>
<Row>
<Col span={18}>
<Row>
<Col span={8}>
<div
style={{
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
padding: 10,
margin: 2,
}}
>
<div
style={{
display: "flex",
flexDirection: "row",
marginBottom: 10,
}}
>
<div
style={{
flex: 20,
display: "flex",
flexDirection: "column",
}}
>
<div
style={{
fontSize: 16,
fontWeight: "bold",
marginBottom: 10,
}}
>
Project
</div>
<div style={{ fontSize: 14 }}>
{isReadyProjectDetail &&
isReadyGantt ? (
(() => {
let parentNames = "";
if (item.hierarchy.length > 0)
{
for ( let i = item.hierarchy.length - 1; i >= 0; i--) {
parentNames += " - ";
parentNames += item.hierarchy[i].name;
}
}
return item.project.nama +
parentNames +
" - " +
version_gantt
})()
) : (
<SingleTextLoader />
)}
</div>
</div>
<div>
<i
className="fa fa-check-square"
style={{ fontSize: 28 }}
></i>
</div>
</div>
</div>
</Col>
<Col span={8}>
<div
style={{
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
padding: 10,
margin: 2,
}}
>
<div
style={{
display: "flex",
flexDirection: "row",
marginBottom: 10,
}}
>
<div
style={{
flex: 20,
display: "flex",
flexDirection: "column",
}}
>
<div
style={{
fontSize: 16,
fontWeight: "bold",
marginBottom: 10,
}}
>
Project Manager
</div>
<div style={{ fontSize: 14 }}>
{isReadyProjectDetail ? (
item.project_manager
) : (
<SingleTextLoader />
)}
</div>
</div>
<div>
<i className="fa fa-user" style={{ fontSize: 28 }}></i>
</div>
</div>
</div>
</Col>
<Col span={8}>
<div
style={{
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
padding: 10,
margin: 2,
}}
>
<div
style={{
display: "flex",
flexDirection: "row",
marginBottom: 10,
}}
>
<div
style={{
flex: 20,
display: "flex",
flexDirection: "column",
}}
>
<div
style={{
fontSize: 16,
fontWeight: "bold",
marginBottom: 10,
}}
>
Customer
</div>
<div style={{ fontSize: 14 }}>
{isReadyProjectDetail ? (
item.project.company
) : (
<SingleTextLoader />
)}
</div>
</div>
<div>
<i className="fa fa-home" style={{ fontSize: 28 }}></i>
</div>
</div>
</div>
</Col>
</Row>
<Row>
<Col span={10}>
<div
style={{
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
padding: 10,
margin: 2,
}}
>
<div
style={{
display: "flex",
flexDirection: "column",
marginBottom: 10,
}}
>
<div>
<div
style={{
fontSize: 16,
fontWeight: "bold",
marginBottom: 10,
}}
>
Schedule
</div>
</div>
<div>
<Row>
<Col
span={12}
style={{ fontSize: 11, fontWeight: "bold" }}
>
<i
className="fa fa-calendar"
style={{ marginRight: 8 }}
></i>
Planned Start
</Col>
<Col span={12} style={{ fontSize: 11 }}>
{isReadyProjectDetail ? (
item.activity.planned_start ? (
moment(item.activity.planned_start).format("D MMMM YYYY")
) : (
"-"
)
) : (
<SingleTextLoader width={100} height={10} />
)}
</Col>
</Row>
<Row>
<Col
span={12}
style={{ fontSize: 11, fontWeight: "bold" }}
>
<i
className="fa fa-calendar"
style={{ marginRight: 8 }}
></i>
Actual Start
</Col>
<Col span={12} style={{ fontSize: 11 }}>
{isReadyProjectDetail ? (
item.activity.start_date ? (
moment(item.activity.start_date).format("D MMMM YYYY")
) : (
"-"
)
) : (
<SingleTextLoader width={100} height={10} />
)}
</Col>
</Row>
<Row>
<Col
span={12}
style={{ fontSize: 11, fontWeight: "bold" }}
>
<i
className="fa fa-calendar"
style={{ marginRight: 8 }}
></i>
Planned Finish
</Col>
<Col span={12} style={{ fontSize: 11 }}>
{isReadyProjectDetail ? (
item.activity.planned_end ? (
moment(item.activity.planned_end).format("D MMMM YYYY")
) : (
"-"
)
) : (
<SingleTextLoader width={100} height={10} />
)}
</Col>
</Row>
<Row>
<Col
span={12}
style={{ fontSize: 11, fontWeight: "bold" }}
>
<i
className="fa fa-calendar"
style={{ marginRight: 8 }}
></i>
Estimated Finish
</Col>
<Col span={12} style={{ fontSize: 11 }}>
{isReadyProjectDetail ? (
item.activity.end_date ? (
moment(item.activity.end_date).format("D MMMM YYYY")
) : (
"-"
)
) : (
<SingleTextLoader width={100} height={10} />
)}
</Col>
</Row>
</div>
</div>
</div>
</Col>
</Row>
<div
style={{
margin: 2,
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
}}
>
<Row>
<Col span={12}>
<div
style={{
backgroundColor: activeTabIdx === 0 ? "#FFFFFF" : "#D9D9D9",
padding: 8,
fontWeight: "bold",
cursor: "pointer",
color: activeTabIdx === 0 ? "#000000" : "#4E4C4C",
}}
onClick={() => setActiveTabIdx(0)}
>
S Curve
</div>
</Col>
<Col span={12}>
<div
style={{
backgroundColor: activeTabIdx === 1 ? "#FFFFFF" : "#D9D9D9",
padding: 8,
fontWeight: "bold",
cursor: "pointer",
color: activeTabIdx === 1 ? "#000000" : "#4E4C4C",
}}
onClick={() => setActiveTabIdx(1)}
>
Maps
</div>
</Col>
</Row>
<Row>
<Col span={24}>
<div style={{ maxHeight: "55vh" }}>
<div
style={{
height: "56vh",
width: "100%",
display: activeTabIdx === 0 ? "block" : "none",
}}
>
<iframe
id="frame-gantt"
src={URL_GANTT}
style={{
width: "100%",
height: "100%",
}}
scrolling="no"
frameBorder="0"
allow="fullscreen"
></iframe>
</div>
{activeTabIdx === 1 && (
<div
id="map-area"
style={{ height: "56vh" }}
ref={mapRef}
></div>
)}
</div>
</Col>
</Row>
</div>
</Col>
<Col span={6}>
<div style={{ margin: 2 }}>
<Row>
<Col span={24}>
<div
style={{
backgroundColor: "#222222",
padding: 10,
marginBottom: 5,
}}
>
<div
style={{
color: "#FFFFFF",
textAlign: "center",
marginBottom: 10,
fontWeight: "bold",
}}
>
Progress
</div>
{isReadySCurve ? (
<ProgressPlanningBar
progress={SetplanningProgress > 100 ? 100 : SetplanningProgress}
/>
) : (
<SingleTextLoader width={"100%"} height={30} />
)}
<div style={{ marginTop: 10, marginBottom: 10 }}></div>
{isReadySCurve ? (
<ProgressActualBar
progress={
SetplanningProgress > 100 || SetactualProgress > 100
? parseFloat(
(SetactualProgress / SetplanningProgress) * 100
).toFixed(0)
: SetactualProgress
}
/>
) : (
<SingleTextLoader width={"100%"} height={30} />
)}
</div>
</Col>
</Row>
<Row>
<Col span={12}>
<div
style={{
background: "#FFF",
padding: 10,
border: "1px solid #DDD",
marginRight: 2,
}}
>
{isReadyOverdueActivities && (
<HealthByBudget status={item.project.budget_health} />
)}
{isReadySCurve && (
<HealthBySchedule status={statusHealthBySchedule} />
)}
</div>
</Col>
<Col span={12}>
<Row style={{ height: "50%" }}>
<Col span={24}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
background: "#FFF",
padding: 10,
border: "1px solid #DDD",
marginBottom: 5,
marginRight: 2,
}}
>
Manpower : {item.manpower}
</div>
</Col>
</Row>
<Row style={{ height: "50%" }}>
<Col span={12}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
background: "#FFF",
padding: 10,
border: "1px solid #DDD",
marginBottom: 5,
marginRight: 2,
}}
>
Assigned: {item.assigned && assignedList.length}
</div>
</Col>
<Col span={12}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
background: "#FFF",
padding: 10,
border: "1px solid #DDD",
marginBottom: 5,
marginRight: 2,
}}
>
Actual : {item.actual}
</div>
</Col>
</Row>
</Col>
</Row>
<Row>
<Col span={24}>
<div
style={{
border: "solid",
borderWidth: 1,
borderColor: "#DDDDDD",
}}
>
<Row style={{ alignItems: "center", marginBottom: 5 }}>
<Col span={12}>
<div
style={{
backgroundColor:
activeTabCommentIdx === 0 ? "#FFFFFF" : "#D9D9D9",
fontWeight: 500,
textAlign: "center",
fontSize: 12,
padding: 2,
cursor: "pointer",
color:
activeTabCommentIdx === 0 ? "#000000" : "#4E4C4C",
}}
onClick={() => setActiveTabCommentIdx(0)}
>
Behind Task
</div>
</Col>
<Col span={12}>
<div
style={{
backgroundColor:
activeTabCommentIdx === 1 ? "#FFFFFF" : "#D9D9D9",
fontWeight: 500,
textAlign: "center",
fontSize: 12,
padding: 2,
cursor: "pointer",
color:
activeTabCommentIdx === 1 ? "#000000" : "#4E4C4C",
}}
onClick={() => setActiveTabCommentIdx(1)}
>
Comment From Customer
</div>
</Col>
</Row>
<div
className="custom-scroll"
style={{ maxHeight: "37vh", overflow: "auto" }}
>
{activeTabCommentIdx === 0 && (
<div>
{isReadyOverdueActivities && item.overdueActivities != [] && item.overdueActivities.length > 0 ? (
item.overdueActivities.map((overdueItem, idx) => {
let end_date;
let planned_end;
let diffDays = 0;
let message = "";
if (overdueItem.end_date && overdueItem.end_date !== null) {
end_date = moment(overdueItem.end_date);
planned_end = moment(overdueItem.planned_end);
diffDays = end_date.diff(planned_end, "days");
if (isNaN(diffDays)) {
return null;
} else {
if (diffDays > 0) {
message = `Overdue by ${diffDays + 1} days`;
} else {
return null;
}
}
}
return <BehindTaskItem key={idx} name={overdueItem.name} message={message} />;
})
) : (
<div
style={{
flex: 1,
textAlign: "center",
color: "#E80053",
marginTop: 50,
marginBottom: 50,
}}
>
No overdue activity found.
</div>
)}
</div>
)}
{activeTabCommentIdx === 1 &&(
<div>
{item.project_comment && item.project_comment != [] ? (
item.project_comment.map((commentItem, idx) => {
return <Comment
key={idx}
name={""}
comment={commentItem.comment}
created_at={commentItem.created_at}
/>
})
) : (
<div
style={{
flex: 1,
textAlign: "center",
color: "#E80053",
marginTop: 50,
marginBottom: 50,
}}
>
No comments found.
</div>
)}
</div>
)}
</div>
</div>
</Col>
</Row>
</div>
</Col>
</Row>
<CarouselCaption/>
</CarouselItem>
);
});
return (
<div style={{ marginLeft: -25, marginRight: -25 }}>
<NotificationContainer />
<Row>
<Col span={24}>
<Spin tip="Loading..." spinning={loading} style={{ marginTop:120 }}>
<Carousel
activeIndex={activeIndex}
next={next}
previous={previous}
{...args}
>
<CarouselIndicators
items={allDataMaster}
activeIndex={activeIndex}
onClickHandler={goToIndex}
/>
{slides}
<CarouselControl
direction="prev"
directionText="Previous"
onClickHandler={previous}
/>
<CarouselControl
direction="next"
directionText="Next"
onClickHandler={next}
/>
</Carousel >
</Spin>
</Col>
</Row>
</div>
);
};
export default DashboardProject;

4
src/views/SimproV2/CreatedProyek/DialogFormProyek.js

@ -1455,8 +1455,8 @@ const DialogFormProyek = ({
<Col md={3}> <Col md={3}>
<Input <Input
type="text" type="text"
value={item.tittle ? item.tittle : item.tittle} value={item.tittle ? item.tittle : ""}
name="title" name="tittle"
onChange={(e) => handleInputChangeApproval(e, index)} onChange={(e) => handleInputChangeApproval(e, index)}
/> />
</Col> </Col>

18
src/views/SimproV2/CreatedProyek/index.js

@ -96,20 +96,19 @@ const url = "";
const format = "DD-MM-YYYY"; const format = "DD-MM-YYYY";
const CreatedProyek = ({ params, ...props }) => { const CreatedProyek = ({ params, ...props }) => {
let role_id = '', user_id='',proyek_id='',isLogin='',token=''; let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '';
if (props.location.state && props.location.state.role_id && props.location.state.user_id) { if (props.location.state && props.location.state.role_id && props.location.state.user_id) {
role_id = props.location.state.role_id; role_id = props.location.state.role_id;
user_id = props.location.state.user_id; user_id = props.location.state.user_id;
token = props.location.state.token; token = props.location.state.token;
isLogin = props.location.state.isLogin; isLogin = props.location.state.isLogin;
console.log('props.location.state success');
} else { } else {
role_id = localStorage.getItem("role_id"); role_id = localStorage.getItem("role_id");
proyek_id = localStorage.getItem("proyek_id"); proyek_id = localStorage.getItem("proyek_id");
user_id = localStorage.getItem("user_id"); user_id = localStorage.getItem("user_id");
token = localStorage.getItem("token"); token = localStorage.getItem("token");
isLogin = localStorage.getItem("isLogin"); isLogin = localStorage.getItem("isLogin");
console.error('Undefined in props.location.state');
} }
const history = useHistory(); const history = useHistory();
const HEADER = { const HEADER = {
@ -210,7 +209,10 @@ const CreatedProyek = ({ params, ...props }) => {
}, [openDialogProyek]); }, [openDialogProyek]);
useEffect(() => { useEffect(() => {
parseInt(role_id) !== 44 ? getDataProyek() : getDataProyekByCustomer(); if (parseInt(role_id) === 44) {
getDataProyekByCustomer()
}
getDataProyek();
}, [search, rowsPerPage, currentPage]); }, [search, rowsPerPage, currentPage]);
useEffect(() => { useEffect(() => {
@ -714,7 +716,7 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code === 200) { if (result && result.data && result.data.code === 200) {
setLoading(false) setLoading(false)
setProjectImage(result.data.data); setProjectImage(result.data.data);
}else{ } else {
setLoading(false) setLoading(false)
} }
} }
@ -1090,7 +1092,7 @@ const CreatedProyek = ({ params, ...props }) => {
const request = data.map((res) => { const request = data.map((res) => {
const payload = { const payload = {
proyek_id: parseInt(id), proyek_id: parseInt(id),
tittle: res.title, tittle: res.tittle,
name: res.name, name: res.name,
date_approval: res.date, date_approval: res.date,
}; };
@ -1275,7 +1277,7 @@ const CreatedProyek = ({ params, ...props }) => {
const request = data.map((res) => { const request = data.map((res) => {
const payload = { const payload = {
proyek_id: parseInt(id), proyek_id: parseInt(id),
tittle: res.tittle ? res.tittle : res.title, tittle: res.tittle ? res.tittle : res.tittle,
name: res.name, name: res.name,
date_approval: res.date ? res.date : res.date_approval, date_approval: res.date ? res.date : res.date_approval,
}; };
@ -1631,7 +1633,7 @@ const CreatedProyek = ({ params, ...props }) => {
dataIndex: "", dataIndex: "",
key: "x", key: "x",
render: (text, record) => render: (text, record) =>
parseInt(role_id) == 44 ? ( parseInt(role_id) == 44 ? (
<> <>
<Tooltip title="Dashboard Project"> <Tooltip title="Dashboard Project">
<Button <Button

2
src/views/SimproV2/Gantt/GanttFrame.js

@ -19,7 +19,7 @@ const GanttFrame = React.memo((props) => {
console.error('Undefined in props.location.state'); console.error('Undefined in props.location.state');
} }
const history = useHistory(); const history = useHistory();
const { versionGanttId, idProject, token, ro, timestamp } = props; const { versionGanttId, idProject, ro, timestamp } = props;
const iframeSrc = `https://konstruksi-gantt.ospro.id/edit-mode/index.html?base_url=${BASE_SIMPRO_LUMEN}&gantt_id=${versionGanttId}&proyek_id=${idProject}&token=${token}&ro=${ro}&timestamp=${timestamp}`; const iframeSrc = `https://konstruksi-gantt.ospro.id/edit-mode/index.html?base_url=${BASE_SIMPRO_LUMEN}&gantt_id=${versionGanttId}&proyek_id=${idProject}&token=${token}&ro=${ro}&timestamp=${timestamp}`;
const [batchEntityData, setBatchEntityData] = useState(null); const [batchEntityData, setBatchEntityData] = useState(null);

Loading…
Cancel
Save