Browse Source

Merge branch 'staging' of https://git.oslog.id/ordo/adw-frontend into dev-wahyun

pull/1/head
wahyuun 1 year ago
parent
commit
bfe360c50f
  1. 654
      src/containers/DefaultLayout/DefaultLayout.js
  2. 650
      src/views/SimproV2/CreatedProyek/DialogForm.js
  3. 123
      src/views/SimproV2/CreatedProyek/DialogFormAnalysis.js
  4. 116
      src/views/SimproV2/CreatedProyek/ReportAnalysis.js

654
src/containers/DefaultLayout/DefaultLayout.js

@ -1,327 +1,327 @@
import React, { Component, Suspense, Divider } from 'react';
import { Redirect, Route, Switch, withRouter } from 'react-router-dom';
import * as router from 'react-router-dom';
import { Button, Container, UncontrolledDropdown, DropdownItem, DropdownMenu, DropdownToggle, Nav, NavItem } from 'reactstrap';
import axios from 'axios';
import { ALERTUSER_SEARCH, ALERT_SEARCH, MENU_SEARCH, ROLEMENU_SEARCH, ALERTUSER_STATUSVIEW, ALERT_STATUSVIEW, MENU_MANAGEMENT, CONTROL_MONITORING_SEARCH } from '../../const/ApiConst';
import { handleChangeLng } from "../../utils/LangUtils";
import {
AppAside,
AppFooter,
AppHeader,
AppSidebar,
AppSidebarFooter,
AppSidebarForm,
AppSidebarHeader,
AppSidebarMinimizer,
AppBreadcrumb2 as AppBreadcrumb,
AppSidebarNav2 as AppSidebarNav,
} from '@coreui/react';
import LayoutHelper from '../../../node_modules/@coreui/react/lib/Shared/layout/layout';
import navigation from '../../_nav';
import routes from '../../routes';
import { emptyConstants } from '../../const/MapConst.js';
const countErr = localStorage.getItem('countErr');
const token = window.localStorage.getItem('token');
const DefaultAside = React.lazy(() => import('./DefaultAside'));
const DefaultFooter = React.lazy(() => import('./DefaultFooter'));
const DefaultHeader = React.lazy(() => import('./DefaultHeader'));
let errorCount = 0;
const config = {
headers:
{
Authorization: `Bearer ${token}`,
"Content-type": `application/json`
}
};
class DefaultLayout extends Component {
constructor(props) {
super(props);
this.state = {
role_id: localStorage.getItem('role_id'),
token: localStorage.getItem('token'),
menu: { items: [] },
routes2: routes,
finalRoutes: [],
breadrCrumbReady: false,
minimized: true
}
}
async componentDidMount() {
const menu = localStorage.getItem("menu_login")
if (menu) this.setMenu(JSON.parse(menu))
this.getAppBreadcrumb();
if (!localStorage.getItem("token")) {
this.signOut();
}
}
componentDidUpdate(prevProps, prevState) {
const menu = localStorage.getItem("menu_login")
const { pathname } = this.props.location;
if (this.state.token !== prevState.token) {
this.setMenu(JSON.parse(menu))
}
if (this.state.role_id !== prevState.role_id) {
this.setMenu(JSON.parse(menu))
}
if (this.state.menu !== prevState.menu) {
this.setFinalRoutes()
}
}
toggleMinimized = () => {
this.setState((prevState) => ({ minimized: !prevState.minimized }));
LayoutHelper.sidebarToggle(!this.state.minimized);
};
setFinalRoutes = () => {
const { routes2 } = this.state;
if (routes2) {
const newRouter2 = routes2;
this.state.routes2.map((val, index) => {
let indexRes = this.state.menu.items.findIndex(x => x.url === val.path);
if (indexRes >= 0) {
let obj = newRouter2[index]
obj['name'] = this.state.menu.items[indexRes].name
newRouter2[index] = obj
}
})
this.setState({ finalRoutes: newRouter2 }, () => {
this.setState({ breadrCrumbReady: true })
});
}
}
loading = () => <div className="animated fadeIn pt-1 text-center">Loading...</div>
async signOut(e) {
if (e) {
e.preventDefault()
}
await localStorage.removeItem("role_id");
await window.localStorage.clear();
this.props.history.replace('/login')
}
getDataMenu = async () => {
errorCount++;
let url = MENU_MANAGEMENT(this.state.role_id)
const result = await axios
.get(url, config)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
window.localStorage.setItem('countErr', 0);
let resData = result.data.data
this.setMenu(resData)
} else {
if (errorCount < 4) {
this.getDataMenu();
} else {
if (countErr) {
await window.localStorage.setItem('countErr', countErr + 1);
} else {
await window.localStorage.setItem('countErr', 1);
}
if (countErr) {
if (parseInt(countErr) > 2) {
// this.signOut();
} else {
window.location.reload();
}
} else {
window.location.reload();
}
}
}
}
parseMenuChild = (data) => {
const menu = data.map(res => {
const obj = {
name: res.name,
url: res.url,
icon: res.icon
}
if (res.children.length > 0) {
obj.children = this.parseMenuChild(res.children)
} else {
delete obj.children
}
return obj
})
return menu
}
setMenu = data => {
const menu = data.map(res => {
const obj = {
name: res.name,
url: res.url,
icon: res.icon
}
if (res.children.length > 0) {
obj.children = this.parseMenuChild(res.children)
} else {
delete obj.children
}
return obj
})
this.setState({ menu: { items: menu } }, () => {
})
}
checkLocation = () => {
const { pathname } = this.props.location;
let getIndex = this.getIndexMenu(pathname);
if (getIndex < 0) {
this.props.history.push("/403");
}
}
getIndexMenu = (url) => {
let index = this.state.menu.items.findIndex(obj => obj.url === url);
return index
}
getMenu = () => {
const { u_group } = this.state;
if (u_group == 'kominfo') {
}
else {
return <AppSidebarNav navConfig={this.state.menu} {...this.props} router={router} />
}
}
getAppBreadcrumb = () => {
const { u_group } = this.state;
if (u_group == 'kominfo') {
routes.map((route, idx) => {
if (route.path == '/dashboard-kominfo') {
return <AppBreadcrumb appRoutes={routes} router={router} className="remove-gap-bs-breadcrumb" />
}
else {
return <AppBreadcrumb appRoutes={routes} router={router} />
}
});
}
else {
if (!window.location.href.includes("dashboard")) {
return <AppBreadcrumb appRoutes={this.state.finalRoutes} router={router} />
}
}
}
isKominfo = () => {
let u_group = localStorage.getItem('u_group');
if (u_group == 'kominfo') {
return true;
}
else {
return false;
}
}
render() {
const { location } = this.props;
const { pathname } = location;
let renderSidebar = false
if (pathname.includes("/dashboard-project")) {
// Remove the base URL and hash
const path = pathname.replace("/dashboard-project/", "");
// Split the remaining path by "/"
const parts = path.split("/");
if (parts[2] == "1") {
renderSidebar = true
}
}
return (
<div className="app">
<div className="app-body">
{!window.location.href.includes("dashboard-project") || renderSidebar ? (
<AppSidebar minimized={this.state.minimized} fixed display="lg">
{/* <div class="sidebar-header">
<Suspense fallback={this.loading()}>
<DefaultHeader history={this.props.history} onLogout={e => this.signOut(e)} />
</Suspense>
</div> */}
<hr />
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{this.getMenu()}
</Suspense>
<AppSidebarFooter />
{this.state.minimized ? null :
<UncontrolledDropdown direction="down">
<DropdownToggle nav>
<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>
</DropdownMenu>
</UncontrolledDropdown>}
<button className='sidebar-minimizer mt-auto' type='button' onClick={this.toggleMinimized}>
</button>
</AppSidebar>
) : null}
<main className="main">
{this.state.breadrCrumbReady ? this.getAppBreadcrumb() : null}
<Container fluid>
<Suspense fallback={this.loading()}>
<Switch>
{routes.map((route, idx) => {
return route.component ? (
<Route
key={idx}
path={route.path}
exact={route.exact}
name={route.name}
render={props => (
<route.component params={{ name: route.name }} {...props} />
)} />
) : (null);
})}
<Redirect from="/" to="/dashboard" />
</Switch>
</Suspense>
</Container>
</main>
<AppAside fixed>
<Suspense fallback={this.loading()}>
<DefaultAside />
</Suspense>
</AppAside>
</div>
{!this.isKominfo ?
(
<AppFooter>
<Suspense fallback={this.loading()}>
<DefaultFooter />
</Suspense>
</AppFooter>
) : null
}
</div>
);
}
}
export default withRouter(DefaultLayout);
import React, { Component, Suspense, Divider } from 'react';
import { Redirect, Route, Switch, withRouter } from 'react-router-dom';
import * as router from 'react-router-dom';
import { Button, Container, UncontrolledDropdown, DropdownItem, DropdownMenu, DropdownToggle, Nav, NavItem } from 'reactstrap';
import axios from 'axios';
import { ALERTUSER_SEARCH, ALERT_SEARCH, MENU_SEARCH, ROLEMENU_SEARCH, ALERTUSER_STATUSVIEW, ALERT_STATUSVIEW, MENU_MANAGEMENT, CONTROL_MONITORING_SEARCH } from '../../const/ApiConst';
import { handleChangeLng } from "../../utils/LangUtils";
import {
AppAside,
AppFooter,
AppHeader,
AppSidebar,
AppSidebarFooter,
AppSidebarForm,
AppSidebarHeader,
AppSidebarMinimizer,
AppBreadcrumb2 as AppBreadcrumb,
AppSidebarNav2 as AppSidebarNav,
} from '@coreui/react';
import LayoutHelper from '../../../node_modules/@coreui/react/lib/Shared/layout/layout';
import navigation from '../../_nav';
import routes from '../../routes';
import { emptyConstants } from '../../const/MapConst.js';
const countErr = localStorage.getItem('countErr');
const token = window.localStorage.getItem('token');
const DefaultAside = React.lazy(() => import('./DefaultAside'));
const DefaultFooter = React.lazy(() => import('./DefaultFooter'));
const DefaultHeader = React.lazy(() => import('./DefaultHeader'));
let errorCount = 0;
const config = {
headers:
{
Authorization: `Bearer ${token}`,
"Content-type": `application/json`
}
};
class DefaultLayout extends Component {
constructor(props) {
super(props);
this.state = {
role_id: localStorage.getItem('role_id'),
token: localStorage.getItem('token'),
menu: { items: [] },
routes2: routes,
finalRoutes: [],
breadrCrumbReady: false,
minimized: true
}
}
async componentDidMount() {
const menu = localStorage.getItem("menu_login")
if (menu) this.setMenu(JSON.parse(menu))
this.getAppBreadcrumb();
if (!localStorage.getItem("token")) {
this.signOut();
}
}
componentDidUpdate(prevProps, prevState) {
const menu = localStorage.getItem("menu_login")
const { pathname } = this.props.location;
if (this.state.token !== prevState.token) {
this.setMenu(JSON.parse(menu))
}
if (this.state.role_id !== prevState.role_id) {
this.setMenu(JSON.parse(menu))
}
if (this.state.menu !== prevState.menu) {
this.setFinalRoutes()
}
}
toggleMinimized = () => {
this.setState((prevState) => ({ minimized: !prevState.minimized }));
LayoutHelper.sidebarToggle(!this.state.minimized);
};
setFinalRoutes = () => {
const { routes2 } = this.state;
if (routes2) {
const newRouter2 = routes2;
this.state.routes2.map((val, index) => {
let indexRes = this.state.menu.items.findIndex(x => x.url === val.path);
if (indexRes >= 0) {
let obj = newRouter2[index]
obj['name'] = this.state.menu.items[indexRes].name
newRouter2[index] = obj
}
})
this.setState({ finalRoutes: newRouter2 }, () => {
this.setState({ breadrCrumbReady: true })
});
}
}
loading = () => <div className="animated fadeIn pt-1 text-center">Loading...</div>
async signOut(e) {
if (e) {
e.preventDefault()
}
await localStorage.removeItem("role_id");
await window.localStorage.clear();
this.props.history.replace('/login')
}
getDataMenu = async () => {
errorCount++;
let url = MENU_MANAGEMENT(this.state.role_id)
const result = await axios
.get(url, config)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
window.localStorage.setItem('countErr', 0);
let resData = result.data.data
this.setMenu(resData)
} else {
if (errorCount < 4) {
this.getDataMenu();
} else {
if (countErr) {
await window.localStorage.setItem('countErr', countErr + 1);
} else {
await window.localStorage.setItem('countErr', 1);
}
if (countErr) {
if (parseInt(countErr) > 2) {
// this.signOut();
} else {
window.location.reload();
}
} else {
window.location.reload();
}
}
}
}
parseMenuChild = (data) => {
const menu = data.map(res => {
const obj = {
name: res.name,
url: res.url,
icon: res.icon
}
if (res.children.length > 0) {
obj.children = this.parseMenuChild(res.children)
} else {
delete obj.children
}
return obj
})
return menu
}
setMenu = data => {
const menu = data.map(res => {
const obj = {
name: res.name,
url: res.url,
icon: res.icon
}
if (res.children.length > 0) {
obj.children = this.parseMenuChild(res.children)
} else {
delete obj.children
}
return obj
})
this.setState({ menu: { items: menu } }, () => {
})
}
checkLocation = () => {
const { pathname } = this.props.location;
let getIndex = this.getIndexMenu(pathname);
if (getIndex < 0) {
this.props.history.push("/403");
}
}
getIndexMenu = (url) => {
let index = this.state.menu.items.findIndex(obj => obj.url === url);
return index
}
getMenu = () => {
const { u_group } = this.state;
if (u_group == 'kominfo') {
}
else {
return <AppSidebarNav navConfig={this.state.menu} {...this.props} router={router} />
}
}
getAppBreadcrumb = () => {
const { u_group } = this.state;
if (u_group == 'kominfo') {
routes.map((route, idx) => {
if (route.path == '/dashboard-kominfo') {
return <AppBreadcrumb appRoutes={routes} router={router} className="remove-gap-bs-breadcrumb" />
}
else {
return <AppBreadcrumb appRoutes={routes} router={router} />
}
});
}
else {
if (!window.location.href.includes("dashboard")) {
return <AppBreadcrumb appRoutes={this.state.finalRoutes} router={router} />
}
}
}
isKominfo = () => {
let u_group = localStorage.getItem('u_group');
if (u_group == 'kominfo') {
return true;
}
else {
return false;
}
}
render() {
const { location } = this.props;
const { pathname } = location;
let renderSidebar = false
if (pathname.includes("/dashboard-project")) {
// Remove the base URL and hash
const path = pathname.replace("/dashboard-project/", "");
// Split the remaining path by "/"
const parts = path.split("/");
if (parts[2] == "1") {
renderSidebar = true
}
}
return (
<div className="app">
<div className="app-body">
{!window.location.href.includes("dashboard-project") || renderSidebar ? (
<AppSidebar minimized={this.state.minimized} fixed display="lg">
{/* <div class="sidebar-header">
<Suspense fallback={this.loading()}>
<DefaultHeader history={this.props.history} onLogout={e => this.signOut(e)} />
</Suspense>
</div> */}
<hr />
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{this.getMenu()}
</Suspense>
<AppSidebarFooter />
{this.state.minimized ? null :
<UncontrolledDropdown direction="down">
<DropdownToggle nav>
<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>
</DropdownMenu>
</UncontrolledDropdown>}
<button className='sidebar-minimizer mt-auto' type='button' onClick={this.toggleMinimized}>
</button>
</AppSidebar>
) : null}
<main className="main">
{this.state.breadrCrumbReady ? this.getAppBreadcrumb() : null}
<Container fluid>
<Suspense fallback={this.loading()}>
<Switch>
{routes.map((route, idx) => {
return route.component ? (
<Route
key={idx}
path={route.path}
exact={route.exact}
name={route.name}
render={props => (
<route.component params={{ name: route.name }} {...props} />
)} />
) : (null);
})}
<Redirect from="/" to="/dashboard" />
</Switch>
</Suspense>
</Container>
</main>
<AppAside fixed>
<Suspense fallback={this.loading()}>
<DefaultAside />
</Suspense>
</AppAside>
</div>
{!this.isKominfo ?
(
<AppFooter>
<Suspense fallback={this.loading()}>
<DefaultFooter />
</Suspense>
</AppFooter>
) : null
}
</div>
);
}
}
export default withRouter(DefaultLayout);

650
src/views/SimproV2/CreatedProyek/DialogForm.js

@ -1,325 +1,325 @@
import React, { useEffect, useState } from "react";
import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap";
import { DatePicker, Tooltip, Select } from "antd";
import axios from "../../../const/interceptorApi";
import moment from "moment";
import {
NotificationContainer,
NotificationManager,
} from "react-notifications";
import "antd/dist/antd.css";
import { formatNumber } from "../../../const/CustomFunc";
import {
TYPE_PROYEK,
USER_LIST,
BASE_SIMPRO_LUMEN,
} from "../../../const/ApiConst";
const { Option } = Select;
const DialogForm = ({
openDialog,
closeDialog,
toggleDialog,
idTask,
dataTypeProyek,
dataPM,
}) => {
const token = localStorage.getItem("token");
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
const [id, setId] = useState(0);
const [name, setName] = useState("");
const [shortName, setShortName] = useState("");
const [description, setDescription] = useState("");
const [biaya, setBiaya] = useState("");
const [typeProject, setTypeproject] = useState(null);
const [sdm, setSdm] = useState(0);
const [pic, setPic] = useState(null);
const [startDate, setStartDate] = useState(moment());
const [endDate, setEndDate] = useState(moment());
const [workArea, setWorkArea] = useState("");
const [finance, setFinance] = useState("");
const [investor, setInvestor] = useState("");
const [company, setCompany] = useState("");
const handleGetdataIdproyek = async (id) => {
const URL = `${BASE_SIMPRO_LUMEN}/project/edit/${id}`;
const result = await axios
.get(URL, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
const val = result.data.data;
setName(val.nama);
setShortName(val.kode_sortname);
setDescription(val.keterangan);
setBiaya(val.rencana_biaya ? formatNumber(val.rencana_biaya) : "");
setTypeproject(val.type_proyek_id);
setPic(val.pm_id);
setStartDate(moment(val.mulai_proyek));
setEndDate(moment(val.akhir_proyek));
setWorkArea(val.area_kerja);
setInvestor(val.investor);
setCompany(val.company);
setFinance(val.finance);
} else {
NotificationManager.error(`Data proyek gagal di edit`, `Failed!!`);
}
};
const handleCLearData = () => {
setName("");
setShortName("");
setBiaya("");
setTypeproject(null);
setPic(null);
setStartDate(moment());
setEndDate(moment());
setDescription("");
setInvestor("");
setFinance("");
setWorkArea("");
setCompany("");
};
useEffect(() => {
if (idTask && idTask > 0) {
handleGetdataIdproyek(idTask);
} else {
handleCLearData();
}
}, [openDialog]);
const handleSave = () => {
let data = "";
if (idTask) {
data = {
id: idTask,
nama: name,
kode_sortname: shortName,
rencana_biaya: biaya.replace(".", ""),
mulai_proyek: startDate,
akhir_proyek: endDate,
type_proyek_id: parseInt(typeProject),
pm_id: pic,
investor,
finance,
company,
area_kerja: workArea,
keterangan: description,
};
closeDialog("edit", data);
} else {
data = {
nama: name,
kode_sortname: shortName,
rencana_biaya: biaya.replace(".", ""),
mulai_proyek: startDate,
akhir_proyek: endDate,
type_proyek_id: parseInt(typeProject),
pm_id: pic,
investor,
finance,
company,
area_kerja: workArea,
keterangan: description,
};
closeDialog("add", data);
}
handleCLearData();
};
const handleCancel = () => {
closeDialog("cancel", "none");
handleCLearData();
};
const onChangeTypeProject = (val) => {
setTypeproject(val);
};
const onChangePm = (val) => {
setPic(val);
};
const handleDatePickerStart = (date, dateString) => {
setStartDate(date);
};
const handleDatePickerEnd = (date, dateString) => {
setEndDate(date);
};
const renderForm = () => {
return (
<Form>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Project Name</Label>
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={`Input project name...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Code / Short Name</Label>
<Input
type="text"
value={shortName}
onChange={(e) => setShortName(e.target.value)}
placeholder={`Input code / short name...`}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Project Type</Label>
<Select
showSearch
value={typeProject}
defaultValue={typeProject}
onChange={onChangeTypeProject}
placeholder="Select project type"
style={{ width: "100%" }}
>
{dataTypeProyek.map((res) => (
<Option key={res.id} value={res.id}>
{res.name}
</Option>
))}
</Select>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">PM</Label>
<Select
showSearch
value={pic}
defaultValue={pic}
onChange={onChangePm}
placeholder="Select PM"
style={{ width: "100%" }}
>
{dataPM.map((res) => (
<Option key={res.id} value={res.id}>
{res.name}
</Option>
))}
</Select>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Start Date</Label>
<DatePicker
style={{ width: "100%" }}
value={startDate}
onChange={handleDatePickerStart}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">End Date</Label>
<DatePicker
style={{ width: "100%" }}
value={endDate}
onChange={handleDatePickerEnd}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Work Area</Label>
<Input
type="text"
value={workArea}
onChange={(e) => setWorkArea(e.target.value)}
placeholder={`Input work area...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Company</Label>
<Input
type="text"
value={company}
onChange={(e) => setCompany(e.target.value)}
placeholder={`Input company...`}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Budget</Label>
<Input
type="text"
value={biaya}
onChange={(e) => setBiaya(formatNumber(e.target.value))}
placeholder={`Input planning cost...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input
type="textarea"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder={`Input description...`}
/>
</FormGroup>
</Col>
</Row>
</Form>
);
};
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
{idTask ? `Update` : "Add"} Project
</ModalHeader>
<ModalBody>{renderForm()}</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>
{idTask ? `Save` : "Add"}
</Button>{" "}
<Button
className="capitalize"
color="secondary"
onClick={() => handleCancel()}
>
Cancel
</Button>
</ModalFooter>
</Modal>
</>
);
};
export default DialogForm;
import React, { useEffect, useState } from "react";
import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap";
import { DatePicker, Tooltip, Select } from "antd";
import axios from "../../../const/interceptorApi";
import moment from "moment";
import {
NotificationContainer,
NotificationManager,
} from "react-notifications";
import "antd/dist/antd.css";
import { formatNumber } from "../../../const/CustomFunc";
import {
TYPE_PROYEK,
USER_LIST,
BASE_SIMPRO_LUMEN,
} from "../../../const/ApiConst";
const { Option } = Select;
const DialogForm = ({
openDialog,
closeDialog,
toggleDialog,
idTask,
dataTypeProyek,
dataPM,
}) => {
const token = localStorage.getItem("token");
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
const [id, setId] = useState(0);
const [name, setName] = useState("");
const [shortName, setShortName] = useState("");
const [description, setDescription] = useState("");
const [biaya, setBiaya] = useState("");
const [typeProject, setTypeproject] = useState(null);
const [sdm, setSdm] = useState(0);
const [pic, setPic] = useState(null);
const [startDate, setStartDate] = useState(moment());
const [endDate, setEndDate] = useState(moment());
const [workArea, setWorkArea] = useState("");
const [finance, setFinance] = useState("");
const [investor, setInvestor] = useState("");
const [company, setCompany] = useState("");
const handleGetdataIdproyek = async (id) => {
const URL = `${BASE_SIMPRO_LUMEN}/project/edit/${id}`;
const result = await axios
.get(URL, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
const val = result.data.data;
setName(val.nama);
setShortName(val.kode_sortname);
setDescription(val.keterangan);
setBiaya(val.rencana_biaya ? formatNumber(val.rencana_biaya) : "");
setTypeproject(val.type_proyek_id);
setPic(val.pm_id);
setStartDate(moment(val.mulai_proyek));
setEndDate(moment(val.akhir_proyek));
setWorkArea(val.area_kerja);
setInvestor(val.investor);
setCompany(val.company);
setFinance(val.finance);
} else {
NotificationManager.error(`Data proyek gagal di edit`, `Failed!!`);
}
};
const handleCLearData = () => {
setName("");
setShortName("");
setBiaya("");
setTypeproject(null);
setPic(null);
setStartDate(moment());
setEndDate(moment());
setDescription("");
setInvestor("");
setFinance("");
setWorkArea("");
setCompany("");
};
useEffect(() => {
if (idTask && idTask > 0) {
handleGetdataIdproyek(idTask);
} else {
handleCLearData();
}
}, [openDialog]);
const handleSave = () => {
let data = "";
if (idTask) {
data = {
id: idTask,
nama: name,
kode_sortname: shortName,
rencana_biaya: biaya.replace(".", ""),
mulai_proyek: startDate,
akhir_proyek: endDate,
type_proyek_id: parseInt(typeProject),
pm_id: pic,
investor,
finance,
company,
area_kerja: workArea,
keterangan: description,
};
closeDialog("edit", data);
} else {
data = {
nama: name,
kode_sortname: shortName,
rencana_biaya: biaya.replace(".", ""),
mulai_proyek: startDate,
akhir_proyek: endDate,
type_proyek_id: parseInt(typeProject),
pm_id: pic,
investor,
finance,
company,
area_kerja: workArea,
keterangan: description,
};
closeDialog("add", data);
}
handleCLearData();
};
const handleCancel = () => {
closeDialog("cancel", "none");
handleCLearData();
};
const onChangeTypeProject = (val) => {
setTypeproject(val);
};
const onChangePm = (val) => {
setPic(val);
};
const handleDatePickerStart = (date, dateString) => {
setStartDate(date);
};
const handleDatePickerEnd = (date, dateString) => {
setEndDate(date);
};
const renderForm = () => {
return (
<Form>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Project Name</Label>
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={`Input project name...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Code / Short Name</Label>
<Input
type="text"
value={shortName}
onChange={(e) => setShortName(e.target.value)}
placeholder={`Input code / short name...`}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Project Type</Label>
<Select
showSearch
value={typeProject}
defaultValue={typeProject}
onChange={onChangeTypeProject}
placeholder="Select project type"
style={{ width: "100%" }}
>
{dataTypeProyek.map((res) => (
<Option key={res.id} value={res.id}>
{res.name}
</Option>
))}
</Select>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">PM</Label>
<Select
showSearch
value={pic}
defaultValue={pic}
onChange={onChangePm}
placeholder="Select PM"
style={{ width: "100%" }}
>
{dataPM.map((res) => (
<Option key={res.id} value={res.id}>
{res.name}
</Option>
))}
</Select>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Start Date</Label>
<DatePicker
style={{ width: "100%" }}
value={startDate}
onChange={handleDatePickerStart}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">End Date</Label>
<DatePicker
style={{ width: "100%" }}
value={endDate}
onChange={handleDatePickerEnd}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Work Area</Label>
<Input
type="text"
value={workArea}
onChange={(e) => setWorkArea(e.target.value)}
placeholder={`Input work area...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Company</Label>
<Input
type="text"
value={company}
onChange={(e) => setCompany(e.target.value)}
placeholder={`Input company...`}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Budget</Label>
<Input
type="text"
value={biaya}
onChange={(e) => setBiaya(formatNumber(e.target.value))}
placeholder={`Input planning cost...`}
/>
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input
type="textarea"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder={`Input description...`}
/>
</FormGroup>
</Col>
</Row>
</Form>
);
};
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
{idTask ? `Update` : "Add"} Project
</ModalHeader>
<ModalBody>{renderForm()}</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>
{idTask ? `Save` : "Add"}
</Button>{" "}
<Button
className="capitalize"
color="secondary"
onClick={() => handleCancel()}
>
Cancel
</Button>
</ModalFooter>
</Modal>
</>
);
};
export default DialogForm;

123
src/views/SimproV2/CreatedProyek/DialogFormAnalysis.js

@ -0,0 +1,123 @@
import React, { useEffect, useState } from "react";
import { Modal, ModalHeader, ModalBody, ModalFooter, Card, CardBody } from "reactstrap";
import { Button } from "reactstrap";
import axios from "../../../const/interceptorApi";
import {
NotificationManager,
} from "react-notifications";
import { BASE_SIMPRO_LUMEN } from "../../../const/ApiConst";
import { Table } from 'antd';
import "antd/dist/antd.css";
const DialogFormAnalysis = ({
openDialog,
closeDialog,
toggleDialog,
dataDetail
}) => {
const token = localStorage.getItem("token");
const [dataTable, setDatatable] = useState([]);
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
useEffect(() => {
if (dataDetail) {
getReportActivityMaterial();
}
}, [openDialog]);
const columns = [
{title: "Human Resource", dataIndex: "join_first_name", key: "join_first_name"},
{title: "Report Date", dataIndex: "report_date", key: "report_date"},
{title: "Volume Plan", dataIndex: "join_second_qty_planning", key: "join_second_qty_planning"},
{title: "Volume Actual", dataIndex: "qty", key: "qty"},
{title: "Keterangan", dataIndex: "description", key: "description"},
]
const getReportActivityMaterial = async () => {
const payload = {
columns: [
{
name: "assign_material_id",
logic_operator: "=",
value: dataDetail.join_third_id,
operator: "AND",
}
],
joins: [
{
name: "m_users",
column_join: "user_id",
column_results: ["name"]
},
{
name: "assign_material_to_activity",
column_join: "assign_material_id",
column_results: ["qty_planning"]
},
],
orders: { columns: ["id"], ascending: false },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(`${BASE_SIMPRO_LUMEN}/report-activity-material/search`, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data || [];
setDatatable(dataRes);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const handleCLearData = () => {
};
const handleCancel = () => {
closeDialog("cancel", "none");
console.log(dataDetail)
handleCLearData();
};
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
Detail Report Analysis
</ModalHeader>
<ModalBody>
<Card>
<CardBody>
<Table
size="small"
columns={columns}
dataSource={dataTable}
pagination={false}
rowKey={"id"}
/>
</CardBody>
</Card>
</ModalBody>
<ModalFooter>
<Button
className="capitalize"
color="secondary"
onClick={() => handleCancel()}
>
Cancel
</Button>
</ModalFooter>
</Modal>
</>
);
};
export default DialogFormAnalysis;

116
src/views/SimproV2/CreatedProyek/ReportAnalysis.js

@ -9,13 +9,17 @@ import {
import { BASE_SIMPRO_LUMEN } from "../../../const/ApiConst";
import 'antd/dist/antd.css';
import './style.css'
import { Select, Table } from 'antd';
import { Select, Table, Tooltip } from 'antd';
import DialogFormAnalysis from './DialogFormAnalysis';
const { Option } = Select
const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) => {
const token = localStorage.getItem("token");
const [activeTab, setActiveTab] = useState('1');
const [search, setSearch] = useState('');
const [openDialogFormAnalysis, setOpenDialogFormAnalysis] = useState(false);
const [dataDetail, setDataDetail] = useState(null);
const [avgActivityHr, setAvgActivityHr] = useState(0);
const [avgActivity, setAvgActivity] = useState(0);
const [dataTable, setDatatable] = useState([]);
const [dataTableActivityToHr, setDataTableActivityToHr] = useState([]);
@ -26,6 +30,20 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
if (activeTab !== tab) {
setActiveTab(tab);
}
switch (tab) {
case '1':
setAvgActivityHr(0);
setSelectedHr(null);
setDataTableActivityToHr([]);
break;
case '2':
setAvgActivity(0);
setSearch('');
setDatatable([])
break;
default:
break;
}
};
const HEADER = {
@ -43,12 +61,29 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
]
const columnActivityToHr = [
{title: "Activity", dataIndex: "join_third_name", key: "join_third_name"},
{title: "Human Resource", dataIndex: "join_second_name", key: "join_second_name"},
{title: "Report Date", dataIndex: "report_date", key: "report_date"},
{title: "Volume Actual", dataIndex: "qty", key: "qty"},
{title: "Volume Planned", dataIndex: "join_first_qty_planning", key: "join_first_qty_planning"},
{title: "Description", dataIndex: "description", key: "description"}
{title: "Activity", dataIndex: "join_second_name", key: "join_second_name"},
{title: "Gantt", dataIndex: "join_fourth_name_version", key: "join_fourth_name_version"},
{title: "Assign HR", dataIndex: "join_first_name", key: "join_first_name"},
{title: "Material Plan", dataIndex: "join_third_qty_planning", key: "join_third_qty_planning",
render: (text, record) =>
<>
{text ? text : 0}
</>
},
{title: "Progress (%)", dataIndex: "join_second_persentase_progress", key: "persentase_progress"},
{
title: 'Action',
dataIndex: '',
key: 'id',
className: "nowrap",
render: (text, record) =>
<>
<Tooltip title="Detail Activity">
<Button size={"sm"} color='primary' onClick={() => handleDetail(text)}><i className="fa fa-eye"></i></Button>
</Tooltip>{" "}
</>
,
},
]
useEffect(() => {
@ -72,6 +107,29 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
setSearch(value);
};
const handleDetail = (data) => {
setOpenDialogFormAnalysis(true);
setDataDetail(data);
}
const closeDialogForm = (status) => {
if (status == "Save") {
// getdataGantt()
NotificationManager.success(`Gantt berhasil dibuat!`, 'Success!!');
}else if (status == "Edit") {
// getdataGantt()
NotificationManager.success(`Gantt berhasil dibubah!`, 'Failed!!');
}else if (status == "failed") {
NotificationManager.error(`Gantt gagal dibuat!`, 'Failed!!');
}
setDataDetail(null)
setOpenDialogFormAnalysis(false)
}
const toggleDialogForm = () => {
setOpenDialogFormAnalysis(!openDialogFormAnalysis)
}
const getDataHr = async () => {
const result = await axios
.get(`${BASE_SIMPRO_LUMEN}/human-resource/list`, HEADER)
@ -86,7 +144,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
}
}
const getDataActivityToHr = async () => {
setAvgActivity(0);
setAvgActivityHr(0);
let sum = 0;
const payload = {
columns: [
@ -105,11 +163,6 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
}
],
joins: [
{
name: "assign_material_to_activity",
column_join: "assign_material_id",
column_results: ["qty_planning"]
},
{
name: "m_users",
column_join: "user_id",
@ -119,14 +172,28 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
name: "m_activity",
column_join: "activity_id",
column_results: ["name", "persentase_progress"]
}
},
{
name1: "m_activity",
name: "assign_material_to_activity",
column_join: "id",
column_self:"activity_id",
column_results: ["id", "qty_planning"]
},
{
name1: "m_activity",
name: "m_version_gantt",
column_join: "version_gantt_id",
column_self:"id",
column_results: ["name_version"]
},
],
orders: { columns: ["id"], ascending: false },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(`${BASE_SIMPRO_LUMEN}/report-activity-material/search`, payload, HEADER)
.post(`${BASE_SIMPRO_LUMEN}/user-to-activity/search-analysis`, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
@ -135,7 +202,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
dataRes.forEach(element => {
element.join_third_persentase_progress ? sum += parseInt(element.join_third_persentase_progress) : sum += 0;
});
setAvgActivity(sum / dataRes.length);
setAvgActivityHr(sum / dataRes.length);
setDataTableActivityToHr(dataRes);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
@ -184,7 +251,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
return (
<>
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>Project</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>Report Analysis</ModalHeader>
<ModalBody>
<div>
<Nav tabs>
@ -252,7 +319,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
<Col>
<Select showSearch value={selectedHr} onChange={(val) => setSelectedHr(val)} placeholder="Select Human Resource" filterOption={(input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
} style={{ width: '100%' }}>
} style={{ width: 200 }}>
{hrList && hrList.map(res => (
<Option key={res.id} value={res.id}>{`${res.name}`}</Option>
))}
@ -261,13 +328,6 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
</Row>
</CardHeader>
<CardBody>
<div style={{ textAlign: 'center' }}>
<h1>
{
selectedHr && avgActivity ? `Activity user ini adalah ${avgActivity.toFixed(2)} %` : null
}
</h1>
</div>
<Table
size="small"
columns={columnActivityToHr}
@ -285,6 +345,12 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
<Button color="primary" onClick={closeDialog}>Close</Button>
</ModalFooter>
</Modal>
<DialogFormAnalysis
openDialog={openDialogFormAnalysis}
toggleDialog={toggleDialogForm}
closeDialog={closeDialogForm}
dataDetail={dataDetail}
/>
</>
)

Loading…
Cancel
Save