Compare commits

...

23 Commits

Author SHA1 Message Date
farhantock 14e56f2bed Merge pull request 'staging' (#14) from staging into master 3 months ago
farhantock 557df6795a Merge pull request '[Refactor] Menghilangkan menu gantt pada projek multi location' (#13) from Dev-Fuad into staging 4 months ago
farhantock d39f415a5b Merge pull request 'dev-wahyun' (#12) from dev-wahyun into staging 4 months ago
wahyun 2f8a76758c fix: Anggaran Biaya <-> Nilai Kontrak & Income Year 4 months ago
wahyun b20d6b26a9 fix: Anggaran Biaya <-> Nilai Kontrak 4 months ago
wahyun bbfe5c0f3a fix: project expenditure & komen command 4 months ago
farhantock fc4c967a57 Merge pull request 'staging' (#11) from staging into master 4 months ago
farhantock 968c0fee11 Merge pull request 'dev-wahyun' (#10) from dev-wahyun into staging 4 months ago
wahyun 54f538496a fix: change nilai kontrak <-> anggaran biaya & typo 4 months ago
wahyun abebd77212 Merge branch 'staging' of https://git.oslog.id/ordo/surveyor_indonesia_frontend into dev-wahyun 4 months ago
wahyun 7411c64e67 feat: add endpoint actual progress project 4 months ago
wahyun cea23eebc0 feat: add Total Progress in project information 4 months ago
wahyun 3d1d7f6b4a fix: assigned 4 months ago
wahyun 2be284cee1 fix: update kolom anggaran biaya <-> nilai kontrak 4 months ago
wahyun dfe0ef2bba fix: project expenditure label 4 months ago
farhantock 64fbaac553 Merge pull request 'fix: add condition payload proyek search' (#9) from dev-wahyun into staging 4 months ago
wahyun b77786c5f1 fix: add condition payload proyek search 4 months ago
ibnu b2f0fcd776 Merge pull request 'staging' (#8) from staging into master 4 months ago
ibnu 575ecf41c6 Merge pull request 'dev-wahyun' (#7) from dev-wahyun into staging 4 months ago
wahyun 289deecd65 fix: company_id 4 months ago
wahyun 9c474018ba feat: add button back dashboard project 4 months ago
farhantock e66e18ddb8 Merge pull request 'staging' (#6) from staging into master 4 months ago
farhantock a5d140e176 Merge pull request 'dev-wahyun' (#5) from dev-wahyun into staging 4 months ago
  1. 58
      src/containers/DefaultLayout/DefaultLayout.js
  2. 2
      src/routes.js
  3. 85
      src/views/Dashboard/DashboardBOD.js
  4. 133
      src/views/Dashboard/DashboardProject.js
  5. 8
      src/views/Master/MasterCompany/index.js
  6. 4
      src/views/SimproV2/CreatedProyek/DialogFormProyek.js
  7. 11
      src/views/SimproV2/CreatedProyek/ViewProject.js
  8. 31
      src/views/SimproV2/CreatedProyek/index.js

58
src/containers/DefaultLayout/DefaultLayout.js

@ -67,6 +67,7 @@ class DefaultLayout extends Component {
if (!localStorage.getItem("token")) {
this.signOut();
}
this.getQueryParams();
window.myData = "Data dari komponen React";
try {
const storedData = localStorage.getItem('configApp');
@ -133,6 +134,12 @@ class DefaultLayout extends Component {
LayoutHelper.sidebarToggle(!this.state.minimized);
};
getQueryParams() {
const searchParams = new URLSearchParams(this.props.location.search);
const dashboardGantt = searchParams.get('dashboardGantt');
this.setState({ dashboardGantt });
}
setFinalRoutes = () => {
const { routes2 } = this.state;
if (routes2) {
@ -263,7 +270,7 @@ class DefaultLayout extends Component {
}
getAppBreadcrumb = () => {
const { u_group } = this.state;
const { u_group, dashboardGantt } = this.state;
if (u_group == 'kominfo') {
routes.map((route, idx) => {
if (route.path == '/dashboard-kominfo') {
@ -275,7 +282,7 @@ class DefaultLayout extends Component {
});
}
else {
if (!window.location.href.includes("dashboard")) {
if (!window.location.href.includes("dashboard") || window.location.href.includes("dashboard-project") && !dashboardGantt) {
return <AppBreadcrumb appRoutes={this.state.finalRoutes} router={router} />
}
}
@ -295,12 +302,11 @@ class DefaultLayout extends Component {
const { location } = this.props;
const { pathname } = location;
let renderSidebar = false
const isDashboardProject = this.props.location.pathname.startsWith('/dashboard-project/');
if (pathname.includes("/dashboard-project")) {
// Remove the base URL and hash
const path = pathname.replace("/dashboard-project/", "");
// Split the remaining path by "/"
// Split the remaining path by "/"
const parts = path.split("/");
if (parts[2] == "1") {
renderSidebar = true
@ -309,37 +315,33 @@ class DefaultLayout extends Component {
return (
<div className="app">
{!window.location.href.includes("false-header") && (
<AppHeader fixed>
<DefaultHeader />
</AppHeader>
)
}
<div className="app-body">
{!window.location.href.includes("dashboard-project") || renderSidebar ? (
<AppSidebar minimized={this.state.minimized} fixed display="lg">
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{(isDashboardProject ? true : !window.location.href.includes("dashboard-project")) || renderSidebar ? (
(!this.state.dashboardGantt ? (
<AppSidebar minimized={this.state.minimized} fixed display="lg">
<hr />
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{this.getMenu()}
</Suspense>
<AppSidebarFooter />
{this.state.minimized ? null :
</Suspense>
<AppSidebarFooter />
{this.state.minimized ? null :
<UncontrolledDropdown direction="down">
<DropdownToggle nav>
<i className="nav-icon fa fa-user-circle"></i> {localStorage.getItem('user_name')}
<i className="nav-icon fa fa-user-circle"></i> {localStorage.getItem('user_name')}
</DropdownToggle>
<DropdownMenu right>
<DropdownItem color="primary" size="sm" onClick={() => handleChangeLng("id")}>ID</DropdownItem>
<DropdownItem color="success" size="sm" onClick={() => handleChangeLng("en")}>EN</DropdownItem>
<DropdownItem href="#/settings"><i className="fa fa-user"></i>Profile</DropdownItem>
<DropdownItem onClick={e => this.signOut(e)}><i className="fa fa-sign-out"></i> Logout</DropdownItem>
<DropdownItem color="primary" size="sm" onClick={() => handleChangeLng("id")}>ID</DropdownItem>
<DropdownItem color="success" size="sm" onClick={() => handleChangeLng("en")}>EN</DropdownItem>
<DropdownItem href="#/settings"><i className="fa fa-user"></i>Profile</DropdownItem>
<DropdownItem onClick={e => this.signOut(e)}><i className="fa fa-sign-out"></i> Logout</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>}
<button className='sidebar-minimizer mt-auto' type='button' onClick={this.toggleMinimized}>
</button>
</AppSidebar>
<button className='sidebar-minimizer mt-auto' type='button' onClick={this.toggleMinimized}>
</button>
</AppSidebar>
) : null)
) : null}
<main className="main">
{this.state.breadrCrumbReady ? this.getAppBreadcrumb() : null}

2
src/routes.js

@ -68,7 +68,7 @@ const routes = [
{ path: '/dashboard', name: 'DashboardBOD', component: DashboardBOD },
{ path: '/dashboard-dyna', name: 'DashboardBOD', component: DashboardDyna },
{ path: '/dashboard-customer/:PROJECT_ID/:GANTT_ID/:SCURVE', name: 'DashboardCustomer', component: DashboardCustomer },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID/:Header', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/dashboard-perproject', exact: true, name: 'Dashboard Project Carousell', component: DashboardProjectCarousell },
{ path: '/dashboard-project/:PROJECT_ID/:GANTT_ID/:SCURVE', exact: true, name: 'Dashboard Project', component: DashboardProject },
{ path: '/projects', exact: true, name: 'Projects', component: CreatedProyek },

85
src/views/Dashboard/DashboardBOD.js

@ -61,6 +61,7 @@ const DashboardBOD = (props) => {
const [READY_TABLE_DETAIL_EXPENDITURE, SET_READY_TABLE_DETAIL_EXPENDITURE] = useState(false);
const [DATA_DETAIL_EXPENDITURE, SET_DATA_DETAIL_EXPENDITURE] = useState([]);
useEffect(() => {
// actualProgressProject();
getCompanyCashFlow(); // expenditure
getCompanyExpenditureColor(); // expenditure Color
getCompanyFinancialHealthColor(); // financial health Color
@ -111,6 +112,11 @@ const DashboardBOD = (props) => {
SET_PROJECT_EXPENDITURE_COLOR(result.data.data)
}
const actualProgressProject = async () => {
const URL = `${BASE_OSPRO}/api/project/actual-progress-project-command`;
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
}
const getCompanyFinancialHealthColor = async () => {
const URL = `${BASE_OSPRO}/api/dashboard/get-detail-financial-health-color/${role_name}`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
@ -437,20 +443,11 @@ const DashboardBOD = (props) => {
<div style={{ color: '#888888', fontSize: 12 }}>Total Project Expenditure from on-going project.</div>
</div>
{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' }}>
Detailed View
</div>
</div>
{/* <div style={{ flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Link to="/dashboard-perproject" style={{ textDecoration: 'none' }}>
<div style={{ backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, cursor: 'pointer', fontSize: 12, textAlign: 'center', lineHeight: 'normal' }}>
All Dashboard
</div>
</Link>
</div> */}
</>
:
<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>
@ -476,11 +473,33 @@ const DashboardBOD = (props) => {
ticks: {
autoSkip: false,
stepSize: 2,
// callback: function (value) {
// if (value === 0 || value === null || value === undefined) {
// return '';
// }
// }
maxRotation: 0,
minRotation: 0,
callback: function (value) {
const label = this.getLabelForValue(value);
const maxLength = 30;
const splitLabel = (label) => {
if (label.length <= maxLength) {
return [label];
}
const words = label.split(' ');
let lines = [];
let currentLine = '';
words.forEach((word) => {
if (currentLine.length + word.length + 1 <= maxLength) {
currentLine += word + ' ';
} else {
lines.push(currentLine.trim());
currentLine = word + ' ';
}
});
if (currentLine.length > 0) {
lines.push(currentLine.trim());
}
return lines;
};
return splitLabel(label);
},
}
}
},
@ -501,38 +520,41 @@ const DashboardBOD = (props) => {
data={{
labels: [
`Target Pendapatan ${moment().format('YYYY')}`,
'Realisasi Pendapatan',
'Realisasi Cash In',
'Anggaran Biaya',
'Realisasi Anggaran Biaya',
'Laba'
'Total Nilai Kontrak Yang Sedang Berjalan',
'Target Pendapatan Berdasarkan Kontrak 2024'
// 'Anggaran Biaya',
// 'Realisasi Anggaran Biaya',
// 'Laba'
],
datasets: [
{
label: '',
data: [
PROJECT_EXPENDITURE?.total_budget || 0,
PROJECT_EXPENDITURE?.total_expenditure || 0,
PROJECT_EXPENDITURE?.total_invoice ? Math.floor(PROJECT_EXPENDITURE.total_invoice) : 0,
PROJECT_EXPENDITURE?.total_paid_invoice || 0,
PROJECT_EXPENDITURE?.total_paid_invoice || 0,
PROJECT_EXPENDITURE?.total_paid_invoice || 0
// PROJECT_EXPENDITURE?.total_budget || 0,
// PROJECT_EXPENDITURE?.total_expenditure || 0,
// PROJECT_EXPENDITURE?.total_invoice ? Math.floor(PROJECT_EXPENDITURE.total_invoice) : 0,
// PROJECT_EXPENDITURE?.total_paid_invoice || 0,
// PROJECT_EXPENDITURE?.total_paid_invoice || 0,
// PROJECT_EXPENDITURE?.total_paid_invoice || 0
98000000000,
PROJECT_EXPENDITURE?.total_value_proyek || 0,
PROJECT_EXPENDITURE?.total_income_year || 0
],
borderColor: [
PROJECT_EXPENDITURE_COLOR?.total_budget || '#480ca8',
PROJECT_EXPENDITURE_COLOR?.total_expenditure || '#b5179e',
PROJECT_EXPENDITURE_COLOR?.total_invoice || '#a26a16',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#4c4747',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#e00000',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#033a37'
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#4c4747',
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#e00000',
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#033a37'
],
backgroundColor: [
PROJECT_EXPENDITURE_COLOR?.total_budget || '#480ca8',
PROJECT_EXPENDITURE_COLOR?.total_expenditure || '#b5179e',
PROJECT_EXPENDITURE_COLOR?.total_invoice || '#a26a16',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#4c4747',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#e00000',
PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#033a37'
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#4c4747',
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#e00000',
// PROJECT_EXPENDITURE_COLOR?.total_paid_invoice || '#033a37'
],
borderRadius: 5,
borderSkipped: false
@ -540,7 +562,6 @@ const DashboardBOD = (props) => {
],
}}
/>
:
<NoDataChart />
:

133
src/views/Dashboard/DashboardProject.js

@ -31,34 +31,15 @@ import {
import { Fab, Action } from "react-tiny-fab";
import "react-tiny-fab/dist/styles.css";
import { useHistory, useLocation, useParams } from "react-router-dom";
import { Icon } from '@iconify/react';
import arrowLeft from '@iconify/icons-ion/ios-arrow-back';
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 = (props) => {
let role_id = 0, user_id = 0, isLogin = false, token = '', all_project = null, role_name = '', hierarchy = [], user_name = '';
if (props && props.role_id && props.user_id) {
@ -72,12 +53,14 @@ const DashboardProject = (props) => {
hierarchy = props.hierarchy;
user_name = props.user_name;
}
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
const { PROJECT_ID, GANTT_ID, SCURVE } = useParams();
const URL_GANTT = `https://project-gantt.ospro.id/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1&role_name=${role_name}`;
// const URL_GANTT = `http://localhost:8444/generic-ospro-gantt/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1&role_name=${role_name}`;
@ -97,6 +80,7 @@ const DashboardProject = (props) => {
const [activeTabIdx, setActiveTabIdx] = useState(0);
const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0);
const [planningProgress, setPlanningProgress] = useState(0);
const [planningProgressToDay, setPlanningProgressToDay] = useState(0);
const [actualProgress, setActualProgress] = useState(0);
const [currentBudget, setCurrentBudget] = useState(null);
const [addCostToComplete, setAddCostToComplete] = useState(null);
@ -134,6 +118,7 @@ const DashboardProject = (props) => {
const [isReadyGanttParents, setIsReadyGanttParents] = useState(false);
const [calculationStatus, setCalculationStatus] = useState(false);
const [isHierarchy, setIsHierarchy] = useState(null);
const [dashboardGantt, setDashboardStatus] = useState(false);
let history = useHistory();
useEffect(() => {
getProjectDetail();
@ -142,9 +127,11 @@ const DashboardProject = (props) => {
getComments();
getGantt();
getGanttParents();
getQueryParams();
return () => {
};
}, []);
useEffect(() => {
if (isHierarchy != null) {
getSCurve();
@ -154,21 +141,23 @@ const DashboardProject = (props) => {
window.removeEventListener("message", handleIframeMessage);
};
}, [isHierarchy]);
useEffect(() => {
if (activeTabIdx === 1) {
initMap();
}
}, [activeTabIdx]);
useEffect(() => {
async function fetchData() {
await Promise.all([
getManpower(),
getAssignedHR(),
...(assignedHr.length > 0 ? [getActualHR()] : []),
getAssignedHR()
]);
}
fetchData();
}, []);
useEffect(() => {
let deviation = 0;
if (plannedCost && totalCost) {
@ -176,9 +165,11 @@ const DashboardProject = (props) => {
}
setRemToComplete(deviation.toString());
}, [plannedCost, totalCost]);
const handleRedirect = () => {
history.push("/projects/" + GANTT_ID + "/" + PROJECT_ID + "/gantt");
};
const getManpower = async () => {
const url = `${BASE_OSPRO}/api/project/manpower/${PROJECT_ID}`;
try {
@ -187,6 +178,7 @@ const DashboardProject = (props) => {
} catch (error) {
}
};
const getGantt = async () => {
setIsReadyGantt(false);
const url = `${BASE_OSPRO}/api/version-gantt/edit/${GANTT_ID}`;
@ -203,6 +195,7 @@ const DashboardProject = (props) => {
setIsReadyGantt(true);
}
};
const getGanttParents = async () => {
setIsReadyGanttParents(false);
const url = `${BASE_OSPRO}/api/hierarchy-ftths/tree-gantt/${GANTT_ID}`;
@ -214,6 +207,7 @@ const DashboardProject = (props) => {
setIsReadyGanttParents(true);
}
};
const getAssignedHR = async () => {
const url = `${BASE_OSPRO}/api/project/manpower/assigned/${GANTT_ID}`;
try {
@ -224,11 +218,16 @@ const DashboardProject = (props) => {
today.isBetween(moment(item.start_date), moment(item.end_date))
)
.map((item) => item.user_id);
setAssignedHrCount(assignedList.length);
setAssignedHr(assignedList);
const uniqueUserIds = new Set(assignedList);
setAssignedHrCount(uniqueUserIds.size);
if (assignedList.length > 0) {
getActualHR(assignedList)
}
} catch (error) {
console.error("Failed to get assigned HR:", error);
}
};
const getActualHR = async () => {
const dateStart = moment().startOf("day").toDate();
const dateEnd = moment().endOf("day").toDate();
@ -268,6 +267,7 @@ const DashboardProject = (props) => {
console.error("Failed to get actual HR:", error);
}
};
const getProjectDetail = async () => {
setIsReadyProjectDetail(false);
let URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`;
@ -352,6 +352,7 @@ const DashboardProject = (props) => {
}
}
};
const getSCurve = async () => {
setIsReadySCurve(false);
let URL = `${BASE_OSPRO}/api/project/get-s-curve`;
@ -384,6 +385,7 @@ const DashboardProject = (props) => {
let selisihProgress = 0;
let planningProgress = 0;
let actualProgress = 0;
let progressPlanToDay = 0;
let statusHealthBySchedule = "behind-schedule";
if (
result.data.data.length > 0 &&
@ -423,6 +425,14 @@ const DashboardProject = (props) => {
planningProgress = result.data.data[0].data?.percentagePlan[n];
setPlanningProgress(planningProgress);
}
if (
result.data.data.length > 0 &&
result.data.data[0].data?.progressPlanToDay &&
result.data.data[0].data?.progressPlanToDay != null
) {
progressPlanToDay = result.data.data[0].data?.progressPlanToDay;
setPlanningProgressToDay(+(Math.round(progressPlanToDay + "e+2") + "e-2"));
}
if (
result.data.data.length > 0 &&
result.data.data[0].data?.percentageReal &&
@ -432,7 +442,7 @@ const DashboardProject = (props) => {
result.data.data[0].data?.percentageReal[
result.data.data[0].data?.percentageReal.length - 1
];
setActualProgress(actualProgress);
setActualProgress(+(Math.round(actualProgress + "e+2") + "e-2"));
}
selisihProgress = planningProgress - actualProgress;
if (selisihProgress > 0 && selisihProgress <= 20) {
@ -444,6 +454,7 @@ const DashboardProject = (props) => {
setIsReadySCurve(true);
}
};
const getOverdueActivities = async () => {
setIsReadyOverdueActivities(false);
const URL = `${BASE_OSPRO}/api/project/get-overdue-activities`;
@ -477,6 +488,7 @@ const DashboardProject = (props) => {
setIsReadyOverdueActivities(true);
}
};
const getIntegrationInvoice = async (kode_sortname, id, gantt_id = null) => {
setIsReadyIntegrationInvoice(false);
const URL = `${BASE_OSPRO}/api/project/get-integration-invoice`;
@ -497,10 +509,10 @@ const DashboardProject = (props) => {
return;
}
if (result.status !== 200) {
NotificationManager.error(
`Get integration invoice failed, ${result.data.message}`,
"Failed"
);
// NotificationManager.error(
// `Get integration invoice failed, ${result.data.message}`,
// "Failed"
// );
setIsReadyIntegrationInvoice(true);
return;
} else if (result.status == 200 && result.data.data) {
@ -520,6 +532,7 @@ const DashboardProject = (props) => {
setIsReadyIntegrationInvoice(true);
}
};
const getReportDistribution = async () => {
setIsReadyReportDistribution(false);
const URL = `${BASE_OSPRO}/api/project/get-report-distribution`;
@ -552,6 +565,7 @@ const DashboardProject = (props) => {
setIsReadyReportDistribution(true);
}
};
const getComments = async () => {
setIsReadyComments(false);
const URL = `${BASE_OSPRO}/api/project-comment/search`;
@ -580,6 +594,7 @@ const DashboardProject = (props) => {
orders: { columns: ["created_at"], ascending: false },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(URL, payload, HEADER)
.then((res) => res)
@ -601,6 +616,7 @@ const DashboardProject = (props) => {
setIsReadyComments(true);
}
};
const handleSendComment = async () => {
setIsSendingComment(true);
if (comment === "") {
@ -640,10 +656,23 @@ const DashboardProject = (props) => {
getComments();
}
};
const resetInputComment = () => {
setComment("");
setIsSendingComment(false);
};
const getQueryParams = () => {
const searchParams = new URLSearchParams(props.location.search);
const dashboardGantt = searchParams.get('dashboardGantt');
setDashboardStatus(dashboardGantt);
}
const handleBack = async () => {
const domainUrl = window.location.origin;
!SCURVE ? (dashboardGantt ? window.parent.location.reload() : window.location.replace(`${domainUrl}/#/projects/${GANTT_ID}/${PROJECT_ID}/gantt`)) : window.history.go(-1);
};
const initMap = () => {
let mymap = L.map("map-area", {
center: center,
@ -655,6 +684,7 @@ const DashboardProject = (props) => {
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(mymap);
};
useEffect(() => {
if (mymap) {
if (reportDistribution.length > 0) {
@ -666,6 +696,7 @@ const DashboardProject = (props) => {
}
}
}, [mymap, reportDistribution]);
useEffect(() => {
// Add event listener for receiving messages from the iframe
window.addEventListener("message", handleIframeMessage);
@ -674,6 +705,7 @@ const DashboardProject = (props) => {
window.removeEventListener("message", handleIframeMessage);
};
}, []);
const handleIframeMessage = (event) => {
if (event.data && event.data.action === "getUrl") {
const childUrl = window.location.href;
@ -684,6 +716,7 @@ const DashboardProject = (props) => {
);
}
};
const RenderGantt = useMemo(
() => (
<iframe
@ -700,6 +733,7 @@ const DashboardProject = (props) => {
),
[activeTabIdx]
);
const RenderComments = useMemo(() => {
return (
<>
@ -803,12 +837,25 @@ const DashboardProject = (props) => {
);
}, [overdueActivities, isReadyOverdueActivities]);
return (
<div style={{ marginLeft: -25, marginRight: -25 }}>
<div style={{ marginLeft: dashboardGantt ? -80 : -25, marginRight: -25 }}>
<NotificationContainer />
<Row>
<Col span={18}>
<Row>
<Col span={8}>
<Col span={2}>
<Button
style={{
height: "100%",
width: "100%",
fontSize: "18px"
}}
onClick={handleBack}
type="primary"
>
<Icon icon={arrowLeft} style={{ fontSize: "20px" }} /> Back
</Button>
</Col>
<Col span={6}>
<div
style={{
border: "solid",
@ -857,14 +904,14 @@ const DashboardProject = (props) => {
}
return SCURVE && SCURVE == "1"
? projectName
? calculationStatus
? projectName + " - S-Curve Ready"
: projectName + " - S-Curve Loading"
: null
: projectName +
parentNames +
" - " +
dataGantt.data.data.name_version;
// ? calculationStatus
// ? projectName + " - S-Curve Ready"
// : projectName + " - S-Curve Loading"
// : null
: projectName
// + parentNames +
// " - " +
// dataGantt.data.data.name_version;
})()
) : (
<SingleTextLoader />
@ -1415,7 +1462,7 @@ const DashboardProject = (props) => {
</div>
{isReadySCurve ? (
<ProgressPlanningBar
progress={planningProgress > 100 ? 100 : planningProgress}
progress={planningProgressToDay > 100 ? 100 : planningProgressToDay}
/>
) : (
<SingleTextLoader width={"100%"} height={30} />

8
src/views/Master/MasterCompany/index.js

@ -443,7 +443,7 @@ const MasterCompany = ({ params }) => {
// Delete Image Function
const deleteImageHeader = async (id) => {
const URL = IMAGE_DELETE(id, 'company_logo_header', companyID != '' ? companyID : 'undifined');
const URL = IMAGE_DELETE(id, 'company_logo_header');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -452,7 +452,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageLogin = async (id) => {
const URL = IMAGE_DELETE(id, 'company_logo_login', companyID != '' ? companyID : 'undifined');
const URL = IMAGE_DELETE(id, 'company_logo_login');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -461,7 +461,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageFavicon = async (id) => {
const URL = IMAGE_DELETE(id, 'company_favicon', companyID != '' ? companyID : 'undifined');
const URL = IMAGE_DELETE(id, 'company_favicon');
await axios
.delete(URL, HEADER)
.then(res => res)
@ -470,7 +470,7 @@ const MasterCompany = ({ params }) => {
};
const deleteImageSlider = async (id) => {
const URL = IMAGE_MULTIPLE_DELETE(id, 'company_slider_login', companyID != '' ? companyID : 'undifined');
const URL = IMAGE_MULTIPLE_DELETE(id, 'company_slider_login');
await axios
.delete(URL, HEADER)
.then(res => res)

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

@ -765,7 +765,7 @@ const DialogFormProyek = ({
<Col md={6}>
<FormGroup>
<Label className="capitalize" style={{ fontWeight: "bold" }}>
Nilai Kontrak<span style={{ color: "red" }}>*</span>
Anggaran Biaya<span style={{ color: "red" }}>*</span>
</Label>
<Row>
<Col md={4}>
@ -807,7 +807,7 @@ const DialogFormProyek = ({
<Col md={6}>
<FormGroup>
<Label className="capitalize" style={{ fontWeight: "bold" }}>
Anggaran Biaya<span style={{ color: "red" }}>*</span>
Nilai Kontrak<span style={{ color: "red" }}>*</span>
</Label>
<Input

11
src/views/SimproV2/CreatedProyek/ViewProject.js

@ -25,6 +25,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
const [durasi, setDurasiProyek] = useState("")
const [mulaiProyek, setMulaiProyek] = useState("")
const [valueProyek, setValueProyek] = useState("")
const [incomeYearly, setIncomeYearly] = useState("")
const [scoupeProyek, setScoupeProyek] = useState("")
const [sponsorProyek, setSponsorProyek] = useState("")
const [lateProyek, setLateConsequenceProyek] = useState("")
@ -67,6 +68,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
setDurasiProyek("")
setMulaiProyek("")
setValueProyek("")
setIncomeYearly("")
setScoupeProyek("")
setSponsorProyek("")
setLateConsequenceProyek("")
@ -99,6 +101,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
setDurasiProyek(projectCharter.durasi_proyek);
setMulaiProyek(projectCharter.mulai_proyek);
setValueProyek(projectCharter.value_proyek);
setIncomeYearly(projectCharter.income_year);
setScoupeProyek(projectCharter.scoupe_of_work);
setSponsorProyek(projectCharter.nama_divisi);
setLateConsequenceProyek(projectCharter.late_consequence);
@ -433,7 +436,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
const renderForm = () => {
return (
<div id="pdf-content" style={paddingTable}>
<h3>Indentitas Proyek</h3>
<h3>Identitas Proyek</h3>
<table style={tableStyle} className="a">
<tbody>
<tr>
@ -494,7 +497,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
<p style={pStyle}>Nilai Kontrak</p>
</td>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{valueProyek ?? '-'}</p>
<p>&nbsp;{currency}. {formatThousand(budget)}</p>
</td>
</tr>
<tr>
@ -502,7 +505,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
<p style={pStyle}>Pendapatan Pertahun</p>
</td>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{valueProyek ?? '-'}</p>
<p>&nbsp;{currency}. {formatThousand(incomeYearly) ?? '-'}</p>
</td>
</tr>
<tr>
@ -510,7 +513,7 @@ const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCha
<p style={pStyle}>Anggaran Biaya</p>
</td>
<td colSpan="2" style={tdStyle}>
<p style={{ ...pStyle, fontWeight: 'normal' }}>{currency}. {formatThousand(budget)}</p>
<p>&nbsp;{currency}. {formatThousand(valueProyek) ?? '-'}</p>
</td>
</tr>
<tr>

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

@ -378,6 +378,7 @@ const CreatedProyek = ({ params, ...props }) => {
"value_proyek",
"income_year",
"deleted_at",
"persentase_progress",
"deleted_by_id"
],
joins: [
@ -395,10 +396,11 @@ const CreatedProyek = ({ params, ...props }) => {
orders: { columns: ["nama"], ascending: true },
paging: { start: start, length: rowsPerPage },
};
payload.columns.push(
{ name: "created_by_id", logic_operator: "IN", value: [JSON.parse(hierarchy)], operator: "AND" }
);
if (all_project === 'false' || all_project === 'null') {
payload.columns.push(
{ name: "created_by_id", logic_operator: "IN", value: [JSON.parse(hierarchy)], operator: "AND" }
);
}
const result = await axios
.post(PROYEK_SEARCH, payload, HEADER)
@ -669,8 +671,8 @@ const CreatedProyek = ({ params, ...props }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
const { value_proyek, area_kerja, scoupe_of_work, kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when } = result.data.data;
const dataToSend = { value_proyek, area_kerja, scoupe_of_work, kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when };
const { value_proyek, area_kerja, scoupe_of_work, kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when, income_year } = result.data.data;
const dataToSend = { value_proyek, area_kerja, scoupe_of_work, kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when, income_year };
setProjectCharter(dataToSend);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
@ -1474,11 +1476,11 @@ const CreatedProyek = ({ params, ...props }) => {
const data = resData.map((elt) => [
elt.nama,
`Rp. ${formatThousand(elt.rencana_biaya)}`,
`Rp. ${formatThousand(elt.income_year)}`,
`Rp. ${formatThousand(elt.value_proyek)}`,
elt.join_second_name,
elt.join_first_name,
`${moment(elt.mulai_proyek).format(format)} - ${moment(
elt.akhir_proyek
).format(format)}`,
`${moment(elt.mulai_proyek).format(format)} - ${moment(elt.akhir_proyek).format(format)}`,
]);
// Or use javascript directly:
doc.text(4, 15, "Project Charter");
@ -1526,7 +1528,7 @@ const CreatedProyek = ({ params, ...props }) => {
<span className="menu-icon">
<i className="fa fa-eye"></i>
</span>
<span className="menu-text">Indentitas Proyek</span>
<span className="menu-text">Identitas Proyek</span>
</div>
<div className="menu-list" onClick={() => handleOpenDokumen(text)}>
<span className="menu-icon">
@ -1741,7 +1743,7 @@ const CreatedProyek = ({ params, ...props }) => {
},
},
{
title: "Nilai Kontrak", dataIndex: "value_proyek",
title: "Anggaran Biaya", dataIndex: "value_proyek",
key: "value_proyek",
render: (text, record) => {
const valueProyek = text ?? '-';
@ -1751,7 +1753,7 @@ const CreatedProyek = ({ params, ...props }) => {
},
},
{
title: "Anggaran Biaya",
title: "Nilai Kontrak",
dataIndex: "rencana_biaya",
key: "rencana_biaya",
render: (text, record) => {
@ -1760,6 +1762,11 @@ const CreatedProyek = ({ params, ...props }) => {
: `${formatThousand(text)}`;
},
},
{
title: "Total Progress (%)", dataIndex: "persentase_progress", key: "persentase_progress", render: (text, record) => {
return text ? +(Math.round(text + "e+2") + "e-2") + '%' : 0 + '%'
}
},
{
title: "Project Type",
dataIndex: "color_progress",

Loading…
Cancel
Save