Browse Source

Merge pull request 'staging' (#117) from staging into master

Reviewed-on: ordo/adw-frontend#117
pull/2/head
ibnu 1 year ago
parent
commit
3fda8d42dc
  1. 2
      package.json
  2. 58
      src/const/ApiConst.js
  3. 4
      src/views/Dashboard/DashboardBOD.js
  4. 24
      src/views/Dashboard/DashboardProject.js
  5. 22
      src/views/Master/MasterBroadcast/DialogDetail.js
  6. 101
      src/views/Master/MasterBroadcast/index.js
  7. 37
      src/views/Master/MasterMenu/DialogForm.js
  8. 14
      src/views/Master/MasterMenu/index.js
  9. 32
      src/views/Master/MasterRoles/DialogForm.js
  10. 12
      src/views/Master/MasterRoles/index.js
  11. 10
      src/views/SimproV2/ChecklistK3/index.js
  12. 131
      src/views/SimproV2/CreatedProyek/AsignCustProject.js
  13. 90
      src/views/SimproV2/CreatedProyek/DialogAssignCust.js
  14. 71
      src/views/SimproV2/CreatedProyek/DialogFormGantt.js
  15. 687
      src/views/SimproV2/CreatedProyek/DialogFormProyek.js
  16. 25
      src/views/SimproV2/CreatedProyek/DialogGantt.js
  17. 672
      src/views/SimproV2/CreatedProyek/ViewProject.js
  18. 461
      src/views/SimproV2/CreatedProyek/index.js
  19. 32
      src/views/SimproV2/Divisi/DialogForm.js
  20. 34
      src/views/SimproV2/Divisi/index.js
  21. 4
      src/views/SimproV2/PanicButton/index.js
  22. 27
      src/views/SimproV2/ResourceWorker/DialogForm.js
  23. 16
      src/views/SimproV2/Satuan/index.js

2
package.json

@ -13,6 +13,8 @@
},
"dependencies": {
"@ant-design/plots": "^1.1.1",
"@ckeditor/ckeditor5-build-classic": "^39.0.2",
"@ckeditor/ckeditor5-react": "^6.1.0",
"@coreui/coreui": "^2.1.12",
"@coreui/icons": "0.3.0",
"@coreui/react": "^2.5.1",

58
src/const/ApiConst.js

@ -117,7 +117,7 @@ export const TOKEN_ADW =
// export let BASE_OSPRO = "https://ospro-api.ospro.id";
export let BASE_OSPRO = "https://adw-api.ospro.id";
// export let BASE_OSPRO = "http://localhost:8444";
// export let BASE_OSPRO = "http://localhost:8444/adw-backend";
// export let BASE_OSPRO = "http://103.73.125.81:8444"; // ip public adw
export let BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
export let BASE_SIMPRO_LUMEN_IMAGE = `${BASE_OSPRO}/assets/image`;
@ -363,6 +363,55 @@ export const PROYEK_ADD = `${BASE_SIMPRO_LUMEN}/project/add`;
export const PROYEK_LIST = `${BASE_SIMPRO_LUMEN}/project/list`;
export const PROYEK_SEARCH = `${BASE_SIMPRO_LUMEN}/project/search`;
export const PROYEK_SEARCH_DETAIL = `${BASE_SIMPRO_LUMEN}/project/search`;
// Checklist
export const PROJECT_CHECKLIST_ADD = `${BASE_SIMPRO_LUMEN}/project-checklists/add`;
export const PROJECT_CHECKLIST_SEARCH = `${BASE_SIMPRO_LUMEN}/project-checklists/search`;
export const PROJECT_CHECKLIST_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/update/${id}`;
};
export const PROJECT_CHECKLIST_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/delete/${id}`;
};
export const PROJECT_CHECKLIST_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/delete-by-proyek/${id}`;
};
export const PROJECT_CHECKLIST_LIST = `${BASE_SIMPRO_LUMEN}/project-checklists/list`;
export const PROJECT_CHECKLIST_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/${where}/${id}`;
};
// Issue
export const PROJECT_ISSUE_ADD = `${BASE_SIMPRO_LUMEN}/project-issues/add`;
export const PROJECT_ISSUE_SEARCH = `${BASE_SIMPRO_LUMEN}/project-issues/search`;
export const PROJECT_ISSUE_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/update/${id}`;
};
export const PROJECT_ISSUE_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/delete/${id}`;
};
export const PROJECT_ISSUE_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/delete-by-proyek/${id}`;
};
export const PROJECT_ISSUE_LIST = `${BASE_SIMPRO_LUMEN}/project-issues/list`;
export const PROJECT_ISSUE_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/${where}/${id}`;
};
// Potential Risk
export const PROJECT_RISK_ADD = `${BASE_SIMPRO_LUMEN}/project-risks/add`;
export const PROJECT_RISK_SEARCH = `${BASE_SIMPRO_LUMEN}/project-risks/search`;
export const PROJECT_RISK_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/update/${id}`;
};
export const PROJECT_RISK_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/delete/${id}`;
};
export const PROJECT_RISK_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/delete-by-proyek/${id}`;
};
export const PROJECT_RISK_LIST = `${BASE_SIMPRO_LUMEN}/project-risks/list`;
export const PROJECT_RISK_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/${where}/${id}`;
};
// export const PROYEK_SEARCH_BY_USER = (id) => {
// return `${BASE_SIMPRO_LUMEN}/project-by-customer/${id}`;
// };
@ -608,6 +657,7 @@ export const CHECKLIST_K3_DELETE = (id) => {
export const CHECKLIST_K3_LIST = `${BASE_SIMPRO_LUMEN}/checklist-k3/list`;
export const ASSIGN_HR_PROJECT_ADD = `${BASE_SIMPRO_LUMEN}/user-to-proyek/add`;
export const ASSIGN_HR_PROJECT_ADD_MULTIPLE = `${BASE_SIMPRO_LUMEN}/user-to-proyek/add-multiple`;
export const ASSIGN_HR_PROJECT_SEARCH = `${BASE_SIMPRO_LUMEN}/user-to-proyek/search`;
export const ASSIGN_HR_PROJECT_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/user-to-proyek/update/${id}`;
@ -676,3 +726,9 @@ export const HIERARCHY_FTTH_TREE = (id) => {
return `${BASE_SIMPRO_LUMEN}/hierarchy-ftths/tree/${id}`;
};
export const WAYPOINT_SEARCH = `${BASE_SIMPRO_LUMEN}/waypoint/search`;
export const IMAGE_UPLOAD = `${BASE_SIMPRO_LUMEN}/image/upload`;
export const IMAGE_DELETE = (id, category) => {
return `${BASE_SIMPRO_LUMEN}/image/delete/${id}/${category}`;
}

4
src/views/Dashboard/DashboardBOD.js

@ -245,7 +245,9 @@ const DashboardBOD = () => {
}
if (result.status == 200 && result.data.data) {
SET_PROJECT_PER_DIVISION(result.data.data);
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.parent === null);
SET_PROJECT_PER_DIVISION(filteredData);
}
SET_READY_PROJECT_PER_DIVISION(true);
}

24
src/views/Dashboard/DashboardProject.js

@ -268,7 +268,13 @@ const DashboardProject = () => {
const getProjectDetail = async () => {
setIsReadyProjectDetail(false);
const URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`;
let URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`;
if (GANTT_ID) {
URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}/${GANTT_ID}`;
}
if (SCURVE) {
URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}/${GANTT_ID}/${SCURVE}`;
}
const result = await axios
.get(URL, HEADER)
.then((res) => res)
@ -298,10 +304,22 @@ const DashboardProject = () => {
result.data.data.company ? result.data.data.company : "-"
);
setPlannedStart(
result.data.data?.mulai_proyek ? result.data.data.mulai_proyek : null
SCURVE
? result.data.data.mulai_proyek
? result.data.data.mulai_proyek
: null
: result.data.data.header?.planned_start
? result.data.data.header?.planned_start
: null
);
setPlannedFinish(
result.data.data?.akhir_proyek ? result.data.data.akhir_proyek : null
SCURVE
? result.data.data.akhir_proyek
? result.data.data.akhir_proyek
: null
: result.data.data.header?.planned_end
? result.data.data.header?.planned_end
: null
);
setActualStart(
result.data.data.header?.start_date

22
src/views/Master/MasterBroadcast/DialogDetail.js

@ -4,7 +4,7 @@ import moment from 'moment';
import { Button, Table, FormFeedback, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
import Select from 'react-select';
import axios from 'axios';
import { BASE_SIMPRO_LUMEN, BASE_URL_GEOHR_API } from '../../../const/ApiConst';
import { BASE_SIMPRO_LUMEN, USER_LIST } from '../../../const/ApiConst';
import { Transfer } from 'antd';
import { withTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
@ -42,11 +42,25 @@ class DialogDetail extends Component {
id: dataDetail.id
}, () => {
this.getDataDetail();
this.getDataUsers();
this.setState({ isParentClick: false });
});
}
}
getDataUsers = async () => {
const result = await axios
.get(USER_LIST, config)
.then(res => res)
.catch((error) => error.response);
console.log('Get Data User', result)
if (result && result.data && result.status == 200) {
this.setState({ dataUser: result.data.data }, () => {
});
}
}
getDataDetail = async () => {
countError++;
let url = BASE_SIMPRO_LUMEN + `/broadcast/search`;
@ -70,6 +84,7 @@ class DialogDetail extends Component {
} else {
if (countError < 6) {
this.getDataDetail();
this.getDataUsers();
}
}
}
@ -81,8 +96,8 @@ class DialogDetail extends Component {
handleCloseDialog = () => {
this.props.closeDialog()
}
render() {
const dataUser = this.state.dataUser || [];
return (
<Modal size="xl" isOpen={this.props.openDialog} toggle={this.props.toggleDialog}>
<ModalHeader toggle={this.handleCloseDialog}>{this.props.t('broadcastDetail')}</ModalHeader>
@ -93,17 +108,20 @@ class DialogDetail extends Component {
<th>{this.props.t('statusSend')}</th>
<th>{this.props.t('dateSend')}</th>
<th>{this.props.t('description')}</th>
<th>{this.props.t('receiver')}</th>
<th>{this.props.t('titleNotification')}</th>
<th>{this.props.t('messageNotification')}</th>
</tr>
</thead>
<tbody>
{this.state.dataListDetail.map((val, index) => {
const matchedUser = dataUser.find(item => item.id == val.send_to_id);
return (
<tr key={index}>
<td>{val.status_send === "" ? "-" : val.status_send}</td>
<td>{val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")}</td>
<td>{val.description === "" ? "-" : val.description}</td>
<td>{ matchedUser ? matchedUser.name : "-" }</td>
<td>{val.title_notif === "" ? "-" : val.title_notif}</td>
<td>{val.message_notif === "" ? "-" : val.message_notif}</td>
</tr>

101
src/views/Master/MasterBroadcast/index.js

@ -5,7 +5,7 @@ import React, { Component } from 'react';
import SweetAlert from 'react-bootstrap-sweetalert';
import axios from 'axios';
import moment from 'moment';
import { API_BROADCAST_SIMPRO, BASE_SIMPRO, BASE_SIMPRO_LUMEN, BASE_URL_GEOHR_API2 } from '../../../const/ApiConst';
import { USER_LIST, BASE_SIMPRO_LUMEN } from '../../../const/ApiConst';
import { Button, Card, CardBody, CardHeader, DropdownItem, DropdownMenu, DropdownToggle, Input, InputGroup, InputGroupButtonDropdown, Table, Row, Col } from 'reactstrap';
import { DatePicker, Pagination } from 'antd';
import { NotificationContainer, NotificationManager } from 'react-notifications';
@ -51,7 +51,7 @@ class index extends Component {
page: 0,
rowsPerPage: LENGTH_DATA,
search: "",
searchDetail: "Judul",
searchDetail: "Title",
searchDetailField: "title_notif",
splitButtonOpen: false,
startDate: moment(moment().format("YYYY-M-D")),
@ -84,17 +84,29 @@ class index extends Component {
this.setState({ search: value, currentPage: 1 })
};
getDataUsers = async () => {
const result = await axios
.get(USER_LIST, config)
.then(res => res)
.catch((error) => error.response);
console.log('Get Data User', result)
if (result && result.data && result.status == 200) {
this.setState({ dataUser: result.data.data }, () => {
});
}
}
getDataBroadcast = async () => {
let url = BASE_SIMPRO_LUMEN + `/broadcast/search`;
const { searchDetail } = this.state
const { searchDetailField, search, currentPage, rowsPerPage, startDate, endDate } = this.state
let start = 0;
if (this.state.currentPage !== 1 && this.state.currentPage > 1) {
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00");
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59");
let dateStart = moment(startDate).format("YYYY-MM-DD 00:00:00");
let dateEnd = moment(endDate).format("YYYY-MM-DD 23:59:59");
const payload = {
"columns": [
@ -107,9 +119,9 @@ class index extends Component {
},
{
"logic_operator": "ilike",
"name": "title_notif",
"name": searchDetailField,
"operator": "AND",
"value": ""
"value": search
}
],
"orders": {
@ -134,6 +146,7 @@ class index extends Component {
if (result && result.data) {
if (result.data.code === 200) {
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord });
this.getDataUsers()
} else {
NotificationManager.error('Failed retreiving data!!', 'Failed');
}
@ -161,7 +174,7 @@ class index extends Component {
onConfirmBroadcast = async () => {
const { idSend, statusSend } = this.state
let url = `${API_BROADCAST_SIMPRO}/edit-status-send/${idSend}`;
let url = BASE_SIMPRO_LUMEN + `/broadcast/update/${idSend}`;
let payload = {
"status_send": statusSend
}
@ -311,50 +324,15 @@ class index extends Component {
}
handleExportExcel = async () => {
let url = BASE_SIMPRO + `/broadcast.php?act=get_data&role_name=${roleName}`;
const { searchDetail } = this.state
let start = 0;
if (this.state.currentPage !== 1) {
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage
}
let dateStart = this.state.startDate;
let dateEnd = this.state.endDate;
const formData = new FormData();
formData.append("startDate", dateStart.format("YYYY-M-D") + " 00:00:00");
formData.append("endDate", dateEnd.format("YYYY-M-D") + " 23:59:59");
formData.append('field', this.state.searchDetailField);
formData.append("start", start);
formData.append("length", "all");
if (this.state.search !== "" && this.state.search !== null) {
formData.append('value', this.state.search);
}
const result = await axios
.post(url, formData)
.then(res => res)
.catch((error) => error.response);
if (result && result.data) {
if (result.data.code_status === 200) {
this.setState({ dataExport: result.data.data }, () => {
this.exportExcel();
});
} else {
}
} else {
}
}
exportExcel = () => {
const dataExcel = this.state.dataExport || [];
const dataExcel = this.state.dataTable || [];
const dataUser = this.state.dataUser || [];
const dataExport = [];
dataExcel.map((val) => {
const matchedUser = dataUser.find(item => item.id == val.send_to_id);
let row = {
"Tanggal Broadcast": moment(val.created_date).format("YYYY-MM-DD HH:mm:ss"),
"Penerima": val.employee_name,
"Tanggal Broadcast": moment(val.created_at).format("YYYY-MM-DD HH:mm:ss"),
"Judul": val.title_notif,
"Penerima": matchedUser ? matchedUser.name : "-",
"Pesan": val.message_notif,
"Deskripsi": val.description,
"Status": val.status_send
@ -415,19 +393,22 @@ class index extends Component {
{ name: this.props.t('title') },
{ name: this.props.t('message') },
{ name: this.props.t('description') },
{ name: this.props.t('receiver') },
{ name: "Status" },
{ name: this.props.t('date') },
]
const t = this.props
const dataTable2 = this.state.dataTable || [];
const dataUser = this.state.dataUser || [];
return (
<tbody>
{dataTable2.length !== 0 ? dataTable2.map((n) => {
const matchedUser = dataUser.find(item => item.id == n.send_to_id);
return (
<tr key={n.id}>
<td width={93}>
<Row>
{n.status_send === 'completed' || n.status_send === 'failed' || n.status_send === 'send' ?
{n.status_send === 'completed' || n.status_send === 'failed' || n.status_send === 'send' || n.status_send === 'resend' ?
this.renderBtnResend(n.id) :
this.renderBtnSend(n.id)
}
@ -437,16 +418,15 @@ class index extends Component {
Detail
</Tooltip>
</Col>
</Row>
</td>
</Row> </td>
<td>{n.title_notif}</td>
<td>{n.message_notif !== "" ? n.message_notif : "-"}</td>
<td>{n.description !== "" ? n.description : "-"}</td>
<td>{ matchedUser ? matchedUser.name : "-" }</td>
<td>{n.status_send !== "" ? n.status_send : "-"}</td>
<td>{n.created_date !== "" ? moment.utc(n.created_date).format("DD-MM-YYYY HH:mm:ss") : "-"}</td>
<td>{n.created_at !== "" ? moment.utc(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"}</td>
</tr>
)
);
}) : <tr>
<td colSpan={column.length} align="center">{this.props.t('noData')}</td>
</tr>
@ -504,6 +484,7 @@ class index extends Component {
{ name: this.props.t('title') },
{ name: this.props.t('message') },
{ name: this.props.t('description') },
{ name: this.props.t('receiver') },
{ name: "Status" },
{ name: this.props.t('date') },
]
@ -553,7 +534,7 @@ class index extends Component {
{this.props.t('broadcastAdd')}
</Tooltip>
<Tooltip placement="right" isOpen={tooltipExport} target="TooltipExport" toggle={() => this.toggle("export")}>
{this.props.t('exprotExcel')}
{this.props.t('exportExcel')}
</Tooltip>
</Col>
</Row>
@ -570,7 +551,7 @@ class index extends Component {
</div>
<div style={{}}>
<RangePicker format={"DD-MM-YYYY"} size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker} />{' '}
<Button color="primary" onClick={() => this.getDataPanicButton()}>{this.props.t('search')}</Button>
<Button color="primary" onClick={() => this.getDataBroadcast()}>{this.props.t('search')}</Button>
</div>
</div>
<InputGroup style={{ maxWidth: "200px" }}>

37
src/views/Master/MasterMenu/DialogForm.js

@ -39,8 +39,29 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
}
}, [dataEdit, openDialog])
const validation = () => {
if (!name || name === "") {
alert("Menu Name cannot be empty!");
return true;
}
if (!url || url === "") {
alert("URL cannot be empty!");
return true;
}
if (!icon || icon === "") {
alert("Icon cannot be empty!");
return true;
}
if (sequence < 0) {
alert("Order cannot be empty!");
return true;
}
}
const handleSave = () => {
let data = '';
const err = validation();
if (!err) {
if (typeDialog === "Save") {
data = {
name,
@ -79,6 +100,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
setSequence(0)
setAliasName('')
}
}
const handleCancel = () => {
closeDialog('cancel', 'none')
@ -110,25 +132,30 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
const renderForm = () => {
return (
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
<Row>
<Col>
<FormGroup>
<Label className="capitalize">{t('name')} Menu</Label>
<Label className="capitalize">{t('name')} Menu<span style={{ color: "red" }}>*</span></Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">URL</Label>
<Label className="capitalize">URL<span style={{ color: "red" }}>*</span></Label>
<Input type="text" value={url} onChange={(e) => setUrl(e.target.value)} placeholder={t('inputUrl')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">{t('icon')} </Label>
<Label className="capitalize">{t('icon')}<span style={{ color: "red" }}>*</span> </Label>
<Input type="text" value={icon} onChange={(e) => setIcon(e.target.value)} placeholder={t('inputIcon')} />
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label className="capitalize">{t('order')}</Label>
<Input type="number" value={sequence} onChange={(e) => setSequence(e.target.value)} placeholder={t('inputOrder')} />
<Label className="capitalize">{t('order')}<span style={{ color: "red" }}>*</span></Label>
<Input type="text" min="0" value={sequence} onChange={(e) => setSequence(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputOrder')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">{t('parentMenu')}</Label>

14
src/views/Master/MasterMenu/index.js

@ -49,12 +49,6 @@ const Index = ({ params }) => {
}
};
useEffect(() => {
getDataMenu();
getDataAllMenu();
}, [])
useEffect(() => {
getDataMenu();
}, [search, currentPage, rowsPerPage])
@ -173,9 +167,9 @@ const Index = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataMenu();
getDataAllMenu();
NotificationManager.success(`Data menu berhasil ditambah`, 'Success!!');
NotificationManager.success(`Data menu berhasil ditambahkan`, 'Success!!');
} else {
NotificationManager.error(`${result.data.message}`, 'Failed!!');
NotificationManager.error(`Data menu gagal ditambahkan`, 'Failed!!');
}
}
@ -189,9 +183,9 @@ const Index = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataMenu();
NotificationManager.success(`Data menu berhasil diedit`, 'Success!!');
NotificationManager.success(`Data menu berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data menu gagal di edit`, `Failed!!`);
NotificationManager.error(`Data menu gagal diubah`, `Failed!!`);
}
}

32
src/views/Master/MasterRoles/DialogForm.js

@ -1,5 +1,5 @@
import React, { Component } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col } from 'reactstrap';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import 'antd/dist/antd.css';
import { withTranslation } from 'react-i18next';
@ -45,6 +45,16 @@ class DialogForm extends Component {
this.setState({ isParentClick: true });
}
validation = () => {
if (!this.state.name || this.state.name === "") {
alert("Role Name cannot be empty!");
return true;
}
if (!this.state.description || this.state.description === "") {
alert("Description cannot be empty!");
return true;
}
}
handleSave = () => {
const {
@ -54,6 +64,8 @@ class DialogForm extends Component {
} = this.state
let data = '';
const err = this.validation();
if(!err) {
if (this.props.typeDialog === "Save") {
data = {
id,
@ -69,8 +81,9 @@ class DialogForm extends Component {
}
this.props.closeDialog('edit', data);
}
this.setState({ id: 0 });
}
}
@ -82,14 +95,25 @@ class DialogForm extends Component {
const { t } = this.props;
return (
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
<Row>
<Col md={12}>
<FormGroup>
<Label>{this.props.t('nameRole')}</Label>
<Label>{this.props.t('nameRole')}<span style={{ color: "red" }}>*</span></Label>
<Input type="text" value={this.state.name} onChange={(e) => this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} />
</FormGroup>
</Col>
<Col md={12}>
<FormGroup>
<Label>{this.props.t('description')}</Label>
<Label>{this.props.t('description')}<span style={{ color: "red" }}>*</span></Label>
<Input type="text" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} />
</FormGroup>
</Col>
</Row>
</Form>
)
}

12
src/views/Master/MasterRoles/index.js

@ -165,8 +165,8 @@ class index extends Component {
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
this.deleteCurrentRoleMenu(idDelete)
this.getDataRoles()
await this.deleteCurrentRoleMenu(idDelete);
this.getDataRoles();
this.setState({ idDelete: 0, alertDelete: false })
NotificationManager.success(`Data role berhasil dihapus`, 'Success!!');
} else {
@ -188,9 +188,9 @@ class index extends Component {
if (result && result.data && result.data.code === 200) {
this.getDataRoles();
NotificationManager.success(`Data role berhasil ditambah`, 'Success!!');
NotificationManager.success(`Data role berhasil ditambahkan`, 'Success!!');
} else {
NotificationManager.error(`${result.data.message}`, 'Failed!!');
NotificationManager.error(`Data role gagal ditambahkan`, 'Failed!!');
}
}
@ -207,9 +207,9 @@ class index extends Component {
if (result && result.data && result.data.code === 200) {
this.getDataRoles();
NotificationManager.success(`Data role berhasil diedit`, 'Success!!');
NotificationManager.success(`Data role berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data role gagal di edit`, `Failed!!`);
NotificationManager.error(`Data role gagal diubah`, `Failed!!`);
}
}

10
src/views/SimproV2/ChecklistK3/index.js

@ -180,7 +180,7 @@ const ChecklistK3 = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataChecklistK3()
NotificationManager.success(`Data project type berhasil ditambah`, 'Success!!');
NotificationManager.success(`Checklist K3 berhasil disimpan!`, 'Success!!');
} else {
NotificationManager.error(`${result.data.message}`, 'Failed!!');
}
@ -196,9 +196,9 @@ const ChecklistK3 = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataChecklistK3();
NotificationManager.success(`Data project type berhasil diedit`, 'Success!!');
NotificationManager.success(`Checklist K3 berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data project type gagal di edit`, `Failed!!`);
NotificationManager.error(`Checklist K3 gagal diubah`, `Failed!!`);
}
}
@ -217,11 +217,11 @@ const ChecklistK3 = ({ params }) => {
getDataChecklistK3()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data project type berhasil dihapus!`, 'Success!!');
NotificationManager.success(`Checklist K3 berhasil dihapus!`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data project type gagal dihapus!}`, 'Failed!!');
NotificationManager.error(`Checklist K3 gagal dihapus!}`, 'Failed!!');
}
}

131
src/views/SimproV2/CreatedProyek/AsignCustProject.js

@ -4,14 +4,16 @@ import { Button, Form } from 'reactstrap';
import { Table, Tooltip } from 'antd';
import 'antd/dist/antd.css';
import moment from 'moment';
import { API_ADW, TOKEN_ADW, ASSIGN_HR_PROJECT_SEARCH, ASSIGN_HR_PROJECT_DELETE, USER_LIST, PROJECT_ROLE_SEARCH, ASSIGN_HR_PROJECT_ADD, ASSIGN_HR_PROJECT_EDIT } from '../../../const/ApiConst';
import {
ASSIGN_HR_PROJECT_SEARCH,
ASSIGN_HR_PROJECT_DELETE
} from '../../../const/ApiConst';
import axios from "../../../const/interceptorApi"
import { NotificationContainer, NotificationManager } from 'react-notifications';
import SweetAlert from 'react-bootstrap-sweetalert';
import FormAsignCust from './DialogAssignCust';
import { formatThousand } from '../../../const/CustomFunc';
const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsResource, proyekName }) => {
const AssignCustProject = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName }) => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
@ -23,9 +25,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
const [alertDelete, setAlertDelete] = useState(false)
const [idDelete, setIdDelete] = useState(0)
const [openDialogFormTools, setOpenDialogFormTools] = useState(false)
const [dataEdit, setDataEdit] = useState(null)
const [listUser, setListUser] = useState([])
const [listRole, setListRole] = useState([])
useEffect(() => {
if (idTask > 0) {
@ -35,8 +34,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
useEffect(() => {
if (openDialog) {
getDataProjectRole();
getDataUser();
}
}, [dataUserToProject])
@ -76,52 +73,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
}
}
const getDataUser = async () => {
const HEADER_ADW = {
headers: {
"Authorization": `${TOKEN_ADW}`
}
}
const result = await axios
.get(USER_LIST, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.data.length != 0) {
let dataRes = result.data.data
setListUser(dataRes)
}
}
const getDataProjectRole = async () => {
const payload = {
"paging": {
"start": 0,
"length": -1
},
"columns": [
{ "name": "created_by", "logic_operator": "ilike", "value": "" },
],
"joins": [],
"orders": {
"columns": [
"id"
],
"ascending": false
}
}
const result = await axios
.post(PROJECT_ROLE_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data || []
setListRole(dataRes);
} else {
}
}
const handleDelete = (id) => {
setIdDelete(id)
setAlertDelete(true)
@ -142,11 +93,11 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
getDataAssignHr()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data assign human resource berhasil dihapus`, 'Success!!');
NotificationManager.success(`Data assign customer berhasil dihapus`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data assign human resource gagal dihapus`, 'Failed!!');
NotificationManager.error(`Data assign customer gagal dihapus`, 'Failed!!');
}
}
@ -167,18 +118,11 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
dataIndex: '',
key: 'x',
className: "nowrap",
render: (text, record) => <><Tooltip title="Delete Request Resource">
render: (text, record) => <><Tooltip title={`Delete Request Resource ${text.id}`}>
<Button size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button>
</Tooltip>{" "}</>,
},
{ title: 'Name Human Resource', dataIndex: 'join_first_name', key: 'join_first_name', className: "nowrap" },
{ title: 'Role Human Resource', dataIndex: 'join_second_name', key: 'join_second_name', className: "nowrap" },
{ title: 'Percentage Available User', dataIndex: 'max_used', key: 'max_used', className: "nowrap", render: (text, record) => record.max_used ? formatThousand(record.max_used) : '-' },
{ title: 'Standard Rate', dataIndex: 'standart_rate', key: 'standart_rate', className: "nowrap", render: (text, record) => record.standart_rate ? formatThousand(record.standart_rate) : '-' },
{ title: 'UOM Standard Rate', dataIndex: 'uom_standart_rate', key: 'uom_standart_rate', className: "nowrap" },
{ title: 'Overtime Rate', dataIndex: 'overtime_rate', key: 'overtime_rate', className: "nowrap", render: (text, record) => record.overtime_rate ? formatThousand(record.overtime_rate) : '-' },
{ title: 'UOM Overtime Rate', dataIndex: 'uom_overtime_rate', key: 'uom_overtime_rate', className: "nowrap" },
{ title: 'Name Human Resource', dataIndex: 'join_first_name', key: 'join_first_name', className: "nowrap" }
];
return (
@ -200,52 +144,23 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
}
const handleCloseDialogFormTools = (type, data) => {
if(type=="add"){
addDataAssignHr(data);
}else if(type=="edit"){
editDataAssignHr(data);
}else{
setDataEdit(null)
setOpenDialogFormTools(false)
}
}
const addDataAssignHr = async (payload) => {
const result = await axios
.post(ASSIGN_HR_PROJECT_ADD, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
getDataAssignHr();
NotificationManager.success('assign human resource berhasil!!', 'Success');
setDataEdit(null)
setOpenDialogFormTools(false)
} else {
NotificationManager.error('assign human resource gagal!!', 'Failed');
if (type === "add") getDataAssignHr();
if (type === "success") {
NotificationManager.success(
`Assign Customer Project berhasil disimpan!`,
"Success!!"
);
} else if (type === "failed") {
NotificationManager.error(
`Assign Customer Project gagal disimpan!`,
"Failed!!"
);
}
}
const editDataAssignHr = async (payload) => {
let url = ASSIGN_HR_PROJECT_EDIT(payload.id)
const result = await axios
.put(url, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
getDataAssignHr();
NotificationManager.success('assign human resource berhasil diedit!!', 'Success');
setDataEdit(null)
setOpenDialogFormTools(false)
} else {
NotificationManager.error('assign human resource gagal diedit!!', 'Failed');
}
}
const toogleDialogFormTools = () => {
if (openDialogFormTools) {
setDataEdit(null)
}
setOpenDialogFormTools(!openDialogFormTools)
}
@ -281,14 +196,10 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
closeDialog={handleCloseDialogFormTools}
toggleDialog={toogleDialogFormTools}
idTask={idTask}
dataEdit={dataEdit}
dataHr={listUser}
dataRole={listRole}
dataCurrentHr={dataUserToProject}
/>
</>
)
}
export default AssignHrProject;
export default AssignCustProject;

90
src/views/SimproV2/CreatedProyek/DialogAssignCust.js

@ -2,12 +2,17 @@ import React, { useEffect, useState } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button, Form } from 'reactstrap';
import axios from "../../../const/interceptorApi";
import { USER_VERSION_GANTT_ADDS, USER_VERSION_GANTT_SEARCH, USER_LIST} from '../../../const/ApiConst';
import {
USER_LIST,
ASSIGN_HR_PROJECT_SEARCH,
ASSIGN_HR_PROJECT_ADD_MULTIPLE
} from '../../../const/ApiConst';
import { Transfer } from 'antd';
import 'antd/dist/antd.css';
import { NotificationManager } from 'react-notifications';
const role_id = localStorage.getItem('role_id');
const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) => {
const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idTask }) => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
@ -15,29 +20,24 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
"Authorization": `Bearer ${token}`
}
}
const [id, setId] = useState(0)
const [targetKeys, setTargetKeys] = useState([])
const [assignCustomer, setAssignCustomer] = useState([])
const handleCLearData = () => {
setId(0)
setTargetKeys([])
}
useEffect(() => {
if(!openDialog){
handleCLearData()
if (!openDialog) {
handleCLearData();
closeDialog('add');
} else {
getDataAssignCustomer();
getCustProject();
}
}, [openDialog])
}, [openDialog]);
useEffect(() => {
if(idGantt && idGantt > 0){
getUserGantt()
}
}, [idGantt])
const getDataAssignCustomer = async () => {
const result = await axios
@ -49,8 +49,6 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.role_id === 44);
setTransferUser(filteredData);
} else {
}
}
@ -66,51 +64,23 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
setAssignCustomer(finalData)
}
const getUserGantt = async () => {
const payload = {
"columns": [
{ "name": "version_gantt_id", "logic_operator": "=", "value": idGantt, "operator": "AND" }
]
}
const result = await axios
.post(USER_VERSION_GANTT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek resource get user gantt",result.data.data)
setUserGantt(result.data.data);
}else{
}
}
const setUserGantt = (data) => {
let newTargetKeys = []
data.map((val,index)=> {
newTargetKeys.push(val.user_id)
});
setTargetKeys(newTargetKeys)
}
const handleSave = async () => {
await saveVersionGantt()
await saveCustProject()
handleCLearData()
}
const saveVersionGantt= async () => {
const saveCustProject= async () => {
const formData = {
user_id:targetKeys,
version_gantt_id:idGantt
user_id: targetKeys,
proyek_id: idTask
}
const result = await axios
.post(USER_VERSION_GANTT_ADDS, formData, HEADER)
.post(ASSIGN_HR_PROJECT_ADD_MULTIPLE, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
closeDialog('success')
}else{
@ -120,13 +90,37 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
const handleCancel = () => {
closeDialog('cancel')
handleCLearData()
handleCLearData();
}
const handleChange = targetKeys => {
setTargetKeys(targetKeys)
};
const getCustProject = async () => {
const payload = {
"columns": [
{ "name": "proyek_id", "logic_operator": "=", "value": idTask },
{"name": "is_customer", "logic_operator": "=", "value": "true"}
]
}
const result = await axios
.post(ASSIGN_HR_PROJECT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek get assign HR is custumer",result.data.data)
let data = result.data.data || []
let newTargetKeys = []
if (data.length > 0) {
data.map((val,index)=> {
newTargetKeys.push(val.user_id)
});
}
setTargetKeys(newTargetKeys)
}
}
const renderForm = () => {
return (
<div style={{

71
src/views/SimproV2/CreatedProyek/DialogFormGantt.js

@ -2,11 +2,11 @@ import React, { useEffect, useState } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap';
import axios from "../../../const/interceptorApi";
import { VERSION_GANTT_ADD } from '../../../const/ApiConst';
import { VERSION_GANTT_ADD, VERSION_GANTT_EDIT } from '../../../const/ApiConst';
import { Select } from 'antd';
import 'antd/dist/antd.css';
const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parentId }) => {
const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parentId, dataEdit, typeDialog}) => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
@ -23,15 +23,43 @@ const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parent
setName("")
setDesctription("")
}
const validation = () => {
if (!name || name === "") {
alert("Gantt Name cannot be empty!");
return true;
}
}
useEffect(() => {
if(typeDialog === "Edit")
{
setId(dataEdit.id);
setName(dataEdit.name_version);
setDesctription(dataEdit.description);
setCalculationType(dataEdit.calculation_type);
} else {
handleCLearData()
}, [openDialog])
}
}, [dataEdit, openDialog])
const handleSave = () => {
let data = '';
const err = validation();
if (!err) {
if (typeDialog === "Edit") {
data = {
id,
name,
description,
calculationType
};
editVersionGantt(data)
} else {
saveVersionGantt()
}
handleCLearData()
}
}
const saveVersionGantt = async () => {
@ -49,7 +77,29 @@ const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parent
.catch((error) => error.response);
if (result && result.status == 200) {
closeDialog('success')
closeDialog('Save')
} else {
closeDialog('failed')
}
}
const editVersionGantt = async (data) => {
const formData = {
name_version: data.name,
description:data.description,
calculation_type: data.calculationType,
proyek_id: idTask,
hierarchy_ftth_id: parentId
}
const url = VERSION_GANTT_EDIT(data.id);
const result = await axios.put(url, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.status == 200) {
closeDialog('Edit')
} else {
closeDialog('failed')
}
@ -65,17 +115,18 @@ const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parent
<Form>
<FormGroup>
<Label className="capitalize">Nama <span style={{ color: "red" }}>*</span> </Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder='' />
<Input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
</FormGroup>
<FormGroup>
<Label className="capitalize">Deskripsi </Label>
<Input type="textarea" value={description} onChange={(e) => setDesctription(e.target.value)} placeholder='' />
<Input type="textarea" value={description} onChange={(e) => setDesctription(e.target.value)}/>
</FormGroup>
<FormGroup>
<Label className="capitalize">Tipe Kalkulasi </Label>
<div>
<Select
defaultValue="detail"
value={calculationType}
defaultValue={calculationType}
style={{
width: 120,
}}
@ -106,12 +157,12 @@ const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parent
return (
<>
<Modal isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>Add Gantt Project</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Edit" ? "Edit" :"Tambah"} Gantt Project</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>Save</Button>{' '}
<Button color="primary" onClick={() => handleSave()}>{typeDialog == "Edit" ? "Update" :"Save"}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Cancel</Button>
</ModalFooter>
</Modal>

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

File diff suppressed because it is too large Load Diff

25
src/views/SimproV2/CreatedProyek/DialogGantt.js

@ -29,6 +29,8 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
const [idDelete, setIdDelete] = useState(0)
const [idGantt, setIdGantt] = useState(0)
const [humanResource, setHumanResource] = useState([])
const [dataEdit, setDataEdit] = useState([])
const [typeDialog, setTypeDialog] = useState('')
useEffect(() => {
if (openDialog && hierarchyId > 0 || idTask > 0 && !openDialogHierarchy) {
@ -104,6 +106,11 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
setAlertDelete(true)
}
const handleEdit = (data) => {
setDataEdit(data)
handleOpenDialogForm('Edit');
}
const handleUserGant = (id) => {
setIdGantt(id)
setOpenDialogUserGantt(true)
@ -121,6 +128,9 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
<Tooltip title="Delete Gantt">
<Button size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button>
</Tooltip>{" "}
<Tooltip title="Edit Gantt">
<Button size={"sm"} color='success' onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button>
</Tooltip>{" "}
<Tooltip title="Gantt Permission">
<Button size={"sm"} color='success' onClick={() => handleUserGant(text.id)}><i className="fa fa-users"></i></Button>
</Tooltip>{" "}
@ -181,8 +191,9 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
}
}
const handleOpenDialogForm = () => {
setOpenDialogForm(true)
const handleOpenDialogForm = async (type) => {
await setTypeDialog(type);
setOpenDialogForm(true);
}
const toggleDialogForm = () => {
@ -190,12 +201,16 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
}
const closeDialogForm = (status) => {
if (status == "success") {
if (status == "Save") {
getdataGantt()
NotificationManager.success(`Gantt berhasil dibuat!`, 'Success!!');
} else if (status == "failed") {
}else if (status == "Edit") {
getdataGantt()
NotificationManager.success(`Gantt berhasil dibubah!`, 'Failed!!');
}else if (status == "failed") {
NotificationManager.error(`Gantt gagal dibuat!`, 'Failed!!');
}
setDataEdit([])
setOpenDialogForm(false)
}
@ -260,6 +275,8 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName
openDialog={openDialogForm}
toggleDialog={toggleDialogForm}
closeDialog={closeDialogForm}
typeDialog={typeDialog}
dataEdit={dataEdit}
/>
<DialogUserGantt

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

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useState, useRef } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button } from 'reactstrap';
import moment from 'moment';
@ -6,32 +6,79 @@ import 'antd/dist/antd.css';
import _ from 'underscore'
import './style.css'
import { formatThousand, sortBy } from '../../../const/CustomFunc';
import { BASE_OSPRO, PROYEK_SEARCH} from "../../../const/ApiConst";
import { Tooltip } from 'antd';
import { useTranslation } from 'react-i18next';
import axios from "../../../const/interceptorApi"
import autoTable from "jspdf-autotable";
import jsPDF from "jspdf";
const createMarkup = (element) => {
return {__html: element};
}
const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectMilestone, projectApproval }) => {
const ViewProject = ({ idTask, openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectChecklist, projectIssue, projectRisk, projectMilestone, projectApproval, projectManager, projectK3, assignHR, projectImage }) => {
const [proyekName, setProyekName] = useState("")
const [description, setDescription] = useState("")
const [shortname, setKodeShortname] = useState("")
const [lokasi, setLokasiKantor] = useState("")
const [durasi, setDurasiProyek] = useState("")
const [mulaiProyek, setMulaiProyek] = useState("")
const [valueProyek, setValueProyek] = useState("")
const [scoupeProyek, setScoupeProyek] = useState("")
const [sponsorProyek, setSponsorProyek] = useState("")
const [lateProyek, setLateConsequenceProyek] = useState("")
const [assumtionProyek, setAssumtionProyek] = useState("")
const [objectives, setObjective] = useState("")
const [projectSuccess, setProjectSuccess] = useState("")
const [participants, setParticipants] = useState("")
const [checklists, setChecklists] = useState("")
const [risks, setRisks] = useState("")
const [issues, setIssues] = useState("")
const [image, setImage] = useState("")
const [budget, setBudget] = useState("")
const [currency, setCurrency] = useState("")
const [testing, setTesting] = useState("")
const [milestone, setMilestone] = useState("")
const [potentialRisks, setPotentialRisks] = useState("")
const [approval, setApproval] = useState("")
const [PM, setDataPM] = useState("")
const [K3Search, setDataK3Search] = useState("")
const [HR, setAssignHR] = useState("")
const formatDate = "DD-MM-YYYY";
const reportTemplateRef = useRef(null);
const { t } = useTranslation();
const token = localStorage.getItem("token");
const HEADER = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
useEffect(() => {
if(!openDialog){
setProyekName("")
setDescription("")
setKodeShortname("")
setLokasiKantor("")
setDurasiProyek("")
setMulaiProyek("")
setValueProyek("")
setScoupeProyek("")
setSponsorProyek("")
setLateConsequenceProyek("")
setAssumtionProyek("")
setObjective("")
setProjectSuccess("")
setParticipants([])
setChecklists([])
setIssues([])
setRisks([])
setDataK3Search([])
setAssignHR([])
setImage("")
setBudget("")
setCurrency("")
setTesting("")
@ -42,9 +89,18 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
}, [openDialog]);
useEffect(() => {
if(projectCharter && projectCharter!={}){
if (projectCharter && projectCharter != {}) {
setProyekName(projectCharter.nama);
setDescription(projectCharter.keterangan);
setKodeShortname(projectCharter.kode_sortname);
setLokasiKantor(projectCharter.lokasi_kantor);
setDurasiProyek(projectCharter.durasi_proyek);
setMulaiProyek(projectCharter.mulai_proyek);
setValueProyek(projectCharter.value_proyek);
setScoupeProyek(projectCharter.scoupe_of_work);
setSponsorProyek(projectCharter.nama_divisi);
setLateConsequenceProyek(projectCharter.late_consequence);
setAssumtionProyek(projectCharter.assumtion);
setObjective(projectCharter.project_objectives);
setProjectSuccess(projectCharter.considered_success_when);
setBudget(projectCharter.rencana_biaya);
@ -54,12 +110,36 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
}
}, [projectCharter]);
useEffect(() => {
if (projectImage && projectImage != {}) {
setImage(projectImage.image)
}
}, [projectImage]);
useEffect(() => {
if(projectParticipant && projectParticipant.length > 0){
setParticipants(projectParticipant)
}
}, [projectParticipant]);
useEffect(() => {
if(projectChecklist && projectChecklist.length > 0){
setChecklists(projectChecklist)
}
}, [projectChecklist]);
useEffect(() => {
if(projectIssue && projectIssue.length > 0){
setIssues(projectIssue)
}
}, [projectIssue]);
useEffect(() => {
if(projectRisk && projectRisk.length > 0){
setRisks(projectRisk)
}
}, [projectRisk]);
useEffect(() => {
if(projectMilestone && projectMilestone.length > 0){
setMilestone(projectMilestone)
@ -73,13 +153,47 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
}
}, [projectApproval]);
useEffect(() => {
if(projectManager && projectManager.length > 0){
console.log("cek data PM", projectManager)
setDataPM(projectManager)
}
}, [projectManager]);
useEffect(() => {
if(projectK3 && projectK3.length > 0){
setDataK3Search(projectK3)
}
}, [projectK3]);
useEffect(() => {
if(assignHR && assignHR.length > 0){
setAssignHR(assignHR)
}
}, [assignHR]);
const handleExportPdf = async () => {
const doc = new jsPDF({
orientation: 'landscape',
unit: 'px',
format: [1130, 1000]
});
doc.html(reportTemplateRef.current, {
async callback(doc) {
await doc.save('Project Charter');
},
});
};
const RenderParticipant = () => {
if(participants && participants.length > 0){
return (
participants.map((val, index) => {
return(
<tr key={index}>
<td className='plr-10'>{val.tittle ? val.tittle : val.title}</td>
<td style={{ fontWeight: 'bold' }} className='plr-10'>{val.tittle ? val.tittle : val.title}</td>
<td style={{ fontWeight: 'bold' }} className='plr-10'>:</td>
<td className='plr-10'>{val.name}</td>
</tr>
)
@ -90,28 +204,148 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
}
}
const RenderK3Project = () => {
if (K3Search && K3Search.length > 0) {
const number = "123456789";
return (
K3Search.map((val, index) => {
const K3Number = number[index];
return(
<tr key={index}>
<td style={{...tdStyle, width:50, textAlign:'center' }}><p style={pStyle}>{ K3Number }</p></td>
<td style={tdStyle} className='plr-10'><p style={pStyle}>{val.checklist_k3_name ? val.checklist_k3_name : "-"}</p></td>
</tr>
)
})
)
}else{
return (<tr><td><br></br></td></tr>)
}
}
const RenderChecklistProject = () => {
if (checklists && checklists.length > 0) {
const number = "123456789";
return (
checklists.map((val, index) => {
const ChecklistNumber = number[index];
return(
<tr key={index}>
<td style={{...tdStyle, width:50, textAlign:'center' }}><p style={pStyle}>{ ChecklistNumber }</p></td>
<td style={tdStyle} className='plr-10'><p style={pStyle}>{val.item ? val.item : "-"}</p></td>
<td style={tdStyle} className='plr-10'>
<p style={pStyle}>
{val.status_exist === true ? "Tersedia" : "Tidak tersedia"}
</p>
</td>
</tr>
)
})
)
}else{
return (<tr><td><br></br></td></tr>)
}
}
const RenderIssueProject = () => {
if (issues && issues.length > 0) {
return (
issues.map((val, index) => {
return(
<tr key={index}>
<td style={{ ...tdStyle, width:50, textAlign:'center' }} className='plr-10'>
<p style={pStyle}>
{val.level_issue ? val.level_issue : "-"}
</p>
</td>
<td style={tdStyle} className='plr-10'><p style={pStyle}>{val.description ? val.description : "-"}</p></td>
</tr>
)
})
)
}else{
return (<tr><td><br></br></td></tr>)
}
}
const RenderRiskProject = () => {
if (risks && risks.length > 0) {
return (
risks.map((val, index) => {
return(
<tr key={index}>
<td style={{ ...tdStyle, width:50, textAlign:'center' }} className='plr-10'>
<p style={pStyle}>
{val.level_risk ? val.level_risk : "-"}
</p>
</td>
<td style={tdStyle} className='plr-10'><p style={pStyle}>{val.description ? val.description : "-"}</p></td>
<td style={tdStyle} className='plr-10'><p style={pStyle}>{val.preventive_risk ? val.preventive_risk : "-"}</p></td>
</tr>
)
})
)
}else{
return (<tr><td><br></br></td></tr>)
}
}
const RenderAssignHR = () => {
if (HR && HR.length > 0) {
return (
HR.map((val, index) => {
return(
<tr key={index}>
<td style={tdStyle} className='plr-10'>
<p>{val.join_first_name ? val.join_first_name : val.join_first_name}</p>
</td>
<td style={tdStyle} className='plr-10'>
<p>{val.join_second_name ? val.join_second_name : val.join_second_name}</p>
</td>
<td style={tdStyle} className='plr-10'>
<p>{val.join_second_description ? val.join_second_description : val.join_second_description}</p>
</td>
</tr>
)
})
)
}else{
return (<tr><td><br></br></td></tr>)
}
}
const RenderMilestone = () => {
if(milestone && milestone.length > 0) {
if (milestone && milestone.length > 0) {
let milestoneSorted = sortBy(milestone, {
prop: "deadline",
desc: false,
});
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return (
milestoneSorted.map((val, index) => {
return(
const milestoneLetter = alphabet[index];
return (
<tr key={index}>
<td className='plr-10'>{val.status}</td>
{/* <td className='plr-10'>{moment(val.due_date).format(formatDate)}</td> */}
<td className='plr-10'>{moment(val.deadline).format(formatDate)}</td>
<td style={tdStyle}>
<p style={{ ...pStyle, textAlign:'center' }}>{milestoneLetter}</p>
</td>
<td className='plr-10' style={tdStyle}>
<p style={{ ...pStyle, color: '#000000' }}>{val.status}</p>
</td>
<td className='plr-10' style={{ ...tdStyle, textAlign:'center' }}>
<p>&nbsp;{moment(val.deadline).format(formatDate)}</p>
</td>
</tr>
)
);
})
)
}else{
return (<tr><td><br></br></td></tr>)
);
} else {
return (<tr><td><br></br></td></tr>);
}
}
const RenderApproval = () => {
if(approval && approval.length > 0){
return (
@ -129,124 +363,375 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
}
}
const tableStyle = {
border: '1px solid black',
borderSpacing: '0px',
width: '100%'
};
const thStyle = {
border: '1px solid black',
padding: '2pt',
backgroundColor: '#F2F2F2',
};
const tdStyle = {
border: '1px solid black',
width: "250px"
};
const pStyle = {
marginLeft: '5pt',
marginTop: '2pt',
marginBottom: '2pt',
fontSize: '10pt',
fontWeight: 'bold',
};
const emptyCellStyle = {
padding: '0',
};
const renderForm = () => {
return (
<div>
<table className='table-charter'>
<thead>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Project name:
<div id="pdf-content">
<table style={tableStyle} className="a">
<tbody>
<tr>
<td colSpan="3" bgcolor="#F2F2F2" style={tdStyle}>
<p style={{ ...pStyle, color: '#000000' }}>1.0 Identifikasi PROYEK</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Nama Proyek</p>
</td>
<td colSpan="2" style={tdStyle}>
<p style={{ ...pStyle, fontWeight: 'normal', fontStyle: 'italic' }}>{proyekName ?? '-'}</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Project description</p>
</td>
<td colSpan="2" style={tdStyle}>
<p style={{ ...pStyle, fontWeight: 'normal', fontStyle: 'italic' }}>{description ?? '-'}</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Nomor Proyek</p>
</td>
<td className='td-charter td-value plr-10'>
<div>{proyekName}</div>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{shortname ?? '-'}</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Project description:
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Lokasi Proyek</p>
</td>
<td className='td-charter td-value plr-10'>
<div>{description}</div>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{lokasi ?? '-' }</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Project objectives:
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Durasi Proyek</p>
</td>
<td className='td-charter td-value plr-10'>
<div>{objectives}</div>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{durasi ?? '-'}</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Project is considered successful when:
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Tanggal Mulai Proyek</p>
</td>
<td className='td-charter td-value plr-10'>
<div>{projectSuccess}</div>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{moment(mulaiProyek).format(formatDate) ?? "-"}</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Project participants:
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Nilai Kontrak Proyek</p>
</td>
<td className='td-charter td-value no-mp'>
<table className="table-participant" style={{width:"100%"}}>
<thead className='border-bottom'>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{valueProyek ?? '-'}</p>
</td>
</tr>
<tr>
<th className='plr-10'>Title:</th>
<th className='plr-10'>Name:</th>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Anggaran Proyek</p>
</td>
<td colSpan="2" style={tdStyle}>
<p style={{ ...pStyle, fontWeight: 'normal', fontStyle: 'italic' }}>{currency}. {formatThousand(budget)}</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Sponsor Proyek</p>
</td>
<td>
<p style={{ ...pStyle, fontWeight: 'normal', fontStyle: 'italic' }}>
{sponsorProyek ?? '-'}
</p>
</td>
<td>
<p>&nbsp;</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Project Manager</p>
</td>
<td colSpan="2" style={tdStyle}>
<p>&nbsp;{PM}</p>
</td>
</tr>
<tr>
<td bgcolor="#D8D8D8" style={tdStyle}>
<p style={ pStyle }>Sumber Daya Manusia Untuk Proyek</p>
</td>
<td>
<span style={{ ...pStyle, fontWeight: 'normal',width:'100%' }}><RenderParticipant /></span>
</td>
</tr>
</thead>
<tbody>
<RenderParticipant />
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a0">
<tbody>
<tr>
<td bgcolor="#F2F2F2" style={tdStyle}>
<p style={ pStyle }>2.0 OBJEKTIF PROYEK (TUJUAN)</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Budget:
</td>
<td className='td-charter td-value plr-10'>
<div>{currency} {formatThousand(budget)}</div>
<tr>
<td style={tdStyle}>
<p style={{ fontStyle: 'italic' }}>{objectives ?? '-'}</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Testing Environment:
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a1">
<tbody>
<tr>
<th style={thStyle}>
<p style={ pStyle }>3.0 RUANG LINGKUP PROYEK</p>
</th>
</tr>
<tr>
<td style={tdStyle}>
<ul>
<li style={pStyle}>{ scoupeProyek ?? '-' }</li>
</ul>
</td>
<td className='td-charter td-value plr-10'>
<div dangerouslySetInnerHTML={createMarkup(testing)}></div>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a2">
<tbody>
<tr>
<td colSpan="3" style={thStyle}>
<p style={ pStyle }>4.0 ANGGOTA PROYEK</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Milestones:
<tr>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold' }}>Nama</p>
</td>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', }}>Posisi</p>
</td>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold' }}>Tugas dan Tanggung Jawab</p>
</td>
<td className='td-charter td-value no-mp'>
<table className="table-participant" style={{width:"100%"}}>
<thead className='border-bottom'>
</tr>
< RenderAssignHR/>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a3">
<tbody>
<tr>
<th style={thStyle}>
<p style={ pStyle }>5.0 STRUKTUR ORGANISASI</p>
</th>
</tr>
<tr>
<th className='plr-10'>Status:</th>
{/* <th className='plr-10'>Due:</th> */}
<th className='plr-10'>Deadline:</th>
<th style={emptyCellStyle}>
<p>&nbsp;
{image ? (
<img src={`${BASE_OSPRO}/assets/image/` + image} style={{ width: "50px" }}></img>
) : (
'-'
)}
</p>
</th>
</tr>
</thead>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a4">
<tbody>
<tr>
<th colSpan="3" style={thStyle}>
<p style={ pStyle }>6.0 TARGET UTAMA &amp; MILESTONE PENCAPAIAN</p>
</th>
</tr>
<tr>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign:'center' }}>Item</p>
</td>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign:'center' }}>Event Besar / Milestone</p>
</td>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign:'center' }}>Tanggal</p>
</td>
</tr>
<RenderMilestone />
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a5">
<tbody>
<tr>
<td colSpan="2" style={thStyle}>
<p style={ pStyle }>7.0 ISU &amp; HAMBATAN UTAMA</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Potential risks:
<tr>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign: 'center' }}>Tingkat Kepelikan Isu</p>
</td>
<td className='td-charter td-value plr-10'>
<div dangerouslySetInnerHTML={createMarkup(potentialRisks)}></div>
<td style={thStyle}>
<p style={{ ...pStyle, fontWeight: 'bold', textAlign: 'center' }}>Penjelasan</p>
</td>
</tr>
<tr className='tr-charter'>
<td className='td-charter td-key plr-10'>
Approval:
<RenderIssueProject/>
</tbody>
</table>
<p style={{ ...pStyle, fontSize: '10pt', fontWeight: 'normal', fontStyle: 'italic' }}>*Skala 1 ke 7 (1 = kecil, 7 = besar)</p>
<p>&nbsp;</p>
<table style={tableStyle} className="a6">
<tbody>
<tr>
<td colSpan="3" style={thStyle}>
<p style={ pStyle }>8.0 RESIKO</p>
</td>
</tr>
<tr>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign: 'center' }}>Tingkat Dampak Resiko</p>
</td>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign: 'center' }}>Penjelasan</p>
</td>
<td className='td-charter td-value no-mp'>
<table className="table-participant" style={{width:"100%"}}>
<thead className='border-bottom'>
<td style={thStyle}>
<p style={{ ...pStyle, color: '#000000', fontWeight: 'bold', textAlign: 'center' }}>Pencegahan</p>
</td>
</tr>
<RenderRiskProject/>
</tbody>
</table>
<p style={{ ...pStyle, fontSize: '10pt', fontWeight: 'normal', fontStyle: 'italic' }}>*Skala 1 ke 7 (1 = kecil, 7 = besar)</p>
<p>&nbsp;</p>
<table style={tableStyle} className="a7">
<tbody>
<tr>
<th style={thStyle}>
<p style={pStyle}>9.0 KONSEKUENSI DARI KETERLAMBATAN</p>
</th>
</tr>
<tr>
<th className='plr-10'>Title and name:</th>
<th className='plr-10'>Date:</th>
<p dangerouslySetInnerHTML={createMarkup(lateProyek ?? '-')}></p>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a8">
<tbody>
<tr>
<th style={thStyle}>
<p style={pStyle}>10.0 KRITERIA SUSKSES DARI PROYEK (HARUS TERUKUR)</p>
</th>
</tr>
<tr>
<th>
<p style={pStyle}>{projectSuccess ?? '-'}</p>
</th>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="a9">
<tbody>
<tr>
<th style={thStyle}>
<p style={pStyle}>11.0 ASUMSI (SUMBERDAYA UTAMA)</p>
</th>
</tr>
<tr>
<td>
<p dangerouslySetInnerHTML={createMarkup(assumtionProyek ?? '-')}></p>
</td>
</tr>
</thead>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="aa">
<tbody>
<RenderApproval />
<tr>
<td colSpan="3" style={thStyle}>
<p style={pStyle}><span style={{ fontWeight: 'bold' }}>12.0 CHECK LIST KESIAPAN PROYEK</span><span style={{ fontStyle: 'italic' }}>** item utama yang paling kritikal</span></p>
</td>
</tr>
<tr>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={pStyle}><span style={{ fontWeight: 'bold' }}>NO</span></p>
</td>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={pStyle}><span style={{ fontWeight: 'bold' }}>ITEM</span></p>
</td>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={pStyle}><span style={{ fontWeight: 'bold' }}>KETERSEDIAAN</span></p>
</td>
</tr>
<RenderChecklistProject/>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="ab">
<tbody>
<tr>
<td colSpan="3" style={ thStyle }>
<p style={pStyle}>13.0 KESEHATAN & KESELAMATAN KERJA (K3)</p>
</td>
</tr>
<tr>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={pStyle}>NO</p>
</td>
<td style={{ ...thStyle, textAlign:'center' }}>
<p style={pStyle}>ITEM</p>
</td>
</tr>
</thead>
<RenderK3Project/>
</tbody>
</table>
<p>&nbsp;</p>
<table style={tableStyle} className="ac">
<tbody>
<tr>
<th style={thStyle}>
<p style={pStyle}><b>13.0 KOMITMEN DISEPAKATI OLEH</b></p>
</th>
</tr>
<tr>
<RenderApproval/>
</tr>
</tbody>
</table>
</div>
)
@ -254,10 +739,23 @@ const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, pr
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>Project</ModalHeader>
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div>
Project
</div>
<div>
<Tooltip title={t('Export PDF')}>
<Button style={{ marginLeft: "5px" }} onClick={(e) => handleExportPdf()}><i className="fa fa-print"></i></Button>
</Tooltip>
</div>
</div>
</ModalHeader>
<ModalBody>
<div ref={reportTemplateRef}>
{renderForm()}
</div>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={closeDialog}>Close</Button>

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

@ -25,6 +25,9 @@ import {
PROJECT_APPROVAL_ADD,
PROJECT_APPROVAL_EDIT,
PROJECT_PARTICIPANT_ADD,
PROJECT_CHECKLIST_ADD,
PROJECT_ISSUE_ADD,
PROJECT_RISK_ADD,
PROJECT_PARTICIPANT_EDIT,
PROJECT_MILESTONE_ADD,
PROJECT_MILESTONE_EDIT,
@ -37,12 +40,19 @@ import {
PROYEK_SEARCH,
PROYEK_SEARCH_BY_USER,
PROYEK_EDIT,
ASSIGN_HR_PROJECT_SEARCH,
PROJECT_CHECKLIST_SEARCH,
PROYEK_DELETE,
TOOLS_RESOURCE_SEARCH,
MATERIAL_RESOURCE_SEARCH,
USER_SEARCH,
PROJECT_CHARTER_SEARCH,
HIERARCHY_FTTH_SEARCH,
PROJECT_ISSUE_SEARCH,
PROJECT_RISK_SEARCH,
PROJECT_CHECKLIST_DELETE_BY_PROYEK,
PROJECT_ISSUE_DELETE_BY_PROYEK,
PROJECT_RISK_DELETE_BY_PROYEK,
TOOLS_RESOURCE_LIST,
MATERIAL_RESOURCE_LIST,
PROYEK_GET_ID,
@ -54,6 +64,9 @@ import {
PHASE_PROYEK,
DIVISI_LIST,
BASE_OSPRO,
IMAGE_UPLOAD,
IMAGE_GET_BY_ID,
IMAGE_DELETE,
} from "../../../const/ApiConst";
import {
formatNumber,
@ -95,6 +108,13 @@ const CreatedProyek = ({ params, ...props }) => {
},
};
const HEADER_MULTIPART = {
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
};
const [idTask, setidTask] = useState(0);
const [dataTable, setDatatable] = useState([]);
const [search, setSearch] = useState("");
@ -130,8 +150,15 @@ const CreatedProyek = ({ params, ...props }) => {
// project charter
const [projectCharter, setProjectCharter] = useState(null);
const [projectParticipant, setProjectParticipant] = useState(null);
const [projectChecklist, setProjectChecklist] = useState(null);
const [projectIssue, setProjectIssue] = useState(null);
const [projectRisk, setProjectRisk] = useState(null);
const [projectMilestone, setProjectMilestone] = useState(null);
const [projectApproval, setProjectApproval] = useState(null);
const [projectPM, setPM] = useState(null);
const [projectK3Search, setK3Search] = useState(null);
const [projectAssignHR, setProjectAssignHR] = useState(null);
const [image, setProjectImage] = useState(null);
const [loadVersionGantt, setLoadVersionGantt] = useState(false);
const [loadHierarchy, setLoadHierarchy] = useState(false);
@ -218,17 +245,20 @@ const CreatedProyek = ({ params, ...props }) => {
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setDataDivisions(result.data.data);
const dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.parent === null);
setDataDivisions(filteredData);
}
};
const handleGetDataPm = async () => {
const handleGetDataPm = async (text) => {
const result = await axios
.get(USER_LIST, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setDataPM(result.data.data);
const dataRes = result.data.data;
setDataPM(dataRes);
} else {
}
};
@ -252,7 +282,7 @@ const CreatedProyek = ({ params, ...props }) => {
return;
} else if (result.status == 200 && result.data.data) {
history.push(
`dashboard-customer/${text.id}/${result.data.gantt.last_gantt_id}/1`
`dashboard-customer/${text.id}/${result.data.gantt}/1`
);
}
};
@ -426,9 +456,10 @@ const CreatedProyek = ({ params, ...props }) => {
setidTask(id);
};
const handleOpenDialogProyek = (id) => {
const handleOpenDialogProyek = async (id) => {
setOpenDialogProyek(true);
setidTask(id);
await getProjectImage(id);
};
const handleOpenDialogGantt = (data) => {
@ -496,8 +527,15 @@ const CreatedProyek = ({ params, ...props }) => {
await getDataProject(data.id);
await getProjectMilestone(data.id);
await getProjectParticipant(data.id);
await getProjectChecklist(data.id);
await getProjectIssue(data.id);
await getProjectRisk(data.id);
await getProjectApproval(data.id);
// await getDataProjectCharter(data.id);
await getK3toProject(data.id);
await getProjectAssignHR(data.id);
await getProjectImage(data.id);
// await handleGetDataPm(data.id);
setPM(data.join_first_name);
setOpenDialogViewDetail(true);
};
@ -520,11 +558,37 @@ const CreatedProyek = ({ params, ...props }) => {
return;
} else if (result.status == 200 && result.data.data) {
history.push(
`/dashboard-project/${id}/${result.data.gantt.last_gantt_id}/1`
`/dashboard-project/${id}/${result.data.gantt}/1`
);
}
};
const getK3toProject = async (id) => {
const payload = {
"select": [
"id",
"proyek_id",
"checklist_k3_id"
],
"columns": [
{ "name": "proyek_id", "logic_operator": "=", "value": id, "operator": "AND" }
]
}
const URL = `${BASE_OSPRO}/api/project-to-checklist-k3/search`;
const result = await axios
.post(URL, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek get project to checklist k3",result.data.data)
let dataRes = result.data.data;
if (dataRes.length > 0) {
setK3Search(dataRes);
}
}
}
const handleSCurve = async (data) => {
getProjectDetail(data.id);
};
@ -537,8 +601,9 @@ const CreatedProyek = ({ params, ...props }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectCharter(dataRes);
const {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 = {kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when};
setProjectCharter(dataToSend);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -546,6 +611,13 @@ const CreatedProyek = ({ params, ...props }) => {
const getProjectMilestone = async (id) => {
const payload = {
select: [
'id',
'proyek_id',
'status',
'due_date',
'deadline'
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [],
orders: { columns: ["id"], ascending: true },
@ -559,20 +631,76 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectMilestone(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectMilestone(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectAssignHR = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"user_id",
"project_role"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [
{
name: "m_users",
column_join: "user_id",
column_results: ["name"],
},
{
name: "m_role_proyek",
column_join: "project_role",
column_results: ["name", "description"],
}
],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
// const url = PROJECT_MI(proyek_id)
const result = await axios
.post(ASSIGN_HR_PROJECT_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectAssignHR(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectImage = async (id) => {
const url = IMAGE_GET_BY_ID(id, "project_structure_organization");
const result = await axios
.get(url, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setProjectImage(result.data.data);
}
}
const getProjectParticipant = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"tittle",
"name"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
// const url = PROJECT_MI(proyek_id)
const result = await axios
.post(PROJECT_PARTICIPANT_SEARCH, payload, HEADER)
.then((res) => res)
@ -580,7 +708,90 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectParticipant(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectParticipant(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectChecklist = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"item",
"status_exist"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_CHECKLIST_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectChecklist(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectIssue = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"description",
"level_issue"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_ISSUE_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectIssue(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectRisk = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"description",
"preventive_risk",
"level_risk"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_RISK_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectRisk(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -601,7 +812,8 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectApproval(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectApproval(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -626,8 +838,14 @@ const CreatedProyek = ({ params, ...props }) => {
const handleCloseDialogView = () => {
setProjectApproval(null);
setProjectParticipant(null);
setProjectChecklist(null);
setProjectIssue(null);
setProjectRisk(null);
setProjectMilestone(null);
setProjectCharter(null);
setK3Search(null);
setProjectAssignHR(null);
setProjectImage(null);
setOpenDialogViewDetail(false);
};
@ -637,8 +855,14 @@ const CreatedProyek = ({ params, ...props }) => {
if (openDialogViewDetail) {
setProjectApproval(null);
setProjectParticipant(null);
setProjectChecklist(null);
setProjectIssue(null);
setProjectRisk(null);
setProjectMilestone(null);
setProjectCharter(null);
setK3Search(null);
setProjectAssignHR(null);
setProjectImage(null);
}
setOpenDialogViewDetail(!openDialogViewDetail);
};
@ -652,7 +876,8 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code === 200) {
role_id !== "44" ? getDataProyek() : getDataProyekByCustomer();
getProjectImage(idDelete);
deleteImage(idDelete);
setIdDelete(0);
setAlertDelete(false);
NotificationManager.success(`Data proyek berhasil dihapus`, "Success!!");
@ -671,11 +896,25 @@ const CreatedProyek = ({ params, ...props }) => {
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
const { participants, milestones, approval } = data.projectCharter;
const { checklist, issue, potentialRisks, participants, milestones, approval } = data.projectCharter;
const imageObject = data.imageStructureOrg;
const resultParticipant = await saveParticipant(
result.data.data_result.id,
participants
);
const resultChecklist = await saveChecklist(
result.data.data_result.id,
checklist
);
const resultIssue = await saveIssue(
result.data.data_result.id,
issue
);
const resultRisk = await saveRisk(
result.data.data_result.id,
potentialRisks
);
const resultMilestone = await saveMilestone(
result.data.data_result.id,
milestones
@ -684,12 +923,21 @@ const CreatedProyek = ({ params, ...props }) => {
result.data.data_result.id,
approval
);
if (imageObject) {
await saveImage(
result.data.data_result.id,
imageObject
);
}
if (
resultChecklist === "berhasil" &&
resultIssue === "berhasil" &&
resultRisk === "berhasil" &&
resultParticipant === "berhasil" &&
resultMilestone === "berhasil" &&
resultApproval === "berhasil"
) {
// getDataProyek();
NotificationManager.success(
`Data proyek berhasil ditambah`,
"Success!!"
@ -724,6 +972,67 @@ const CreatedProyek = ({ params, ...props }) => {
return "berhasil";
};
const saveChecklist = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
item: res.item,
status_exist: res.status_exist,
};
return axios.post(PROJECT_CHECKLIST_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveIssue = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
description: res.description,
level_issue: res.level_issue,
};
return axios.post(PROJECT_ISSUE_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveRisk = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
level_risk: res.level_risk,
description: res.description,
preventive_risk: res.preventive_risk,
};
return axios.post(PROJECT_RISK_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveMilestone = async (id, data) => {
const request = data.map((res) => {
const payload = {
@ -766,8 +1075,33 @@ const CreatedProyek = ({ params, ...props }) => {
return "berhasil";
};
const saveImage = async (id, data) => {
const formData = new FormData;
formData.append('ref_id', id);
formData.append('category', 'project_structure_organization');
formData.append('files', data);
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
.then(res => res)
.catch((error) => error.response);
return "berhasil";
};
const deleteImage = async (id) => {
const URL = IMAGE_DELETE(id, 'project_structure_organization');
await axios
.delete(URL, HEADER)
.then(res => res)
.catch((error) => error.response);
return "berhasil";
};
const editProyek = async (data) => {
const { participants, milestones, approval } = data.projectCharter;
const { checklist, issue, potentialRisks, participants, milestones, approval } = data.projectCharter;
const imageObject = data.imageStructureOrg;
let urlEdit = PROYEK_EDIT(data.id);
const formData = data;
@ -778,6 +1112,18 @@ const CreatedProyek = ({ params, ...props }) => {
const resultParticipant = await editParticipant(data.id, participants);
const resultMilestone = await editMilestone(data.id, milestones);
const resultApproval = await editApproval(data.id, approval);
const resultChecklist = await editChecklist(data.id, checklist);
const resultIssue = await editIssue(data.id, issue);
const resultRisk = await editRisk(data.id, potentialRisks);
if (imageObject) {
await deleteImage(
data.id
);
await saveImage(
data.id,
imageObject
);
}
if (result && result.status === 200) {
role_id !== "44" ? getDataProyek() : getDataProyekByCustomer();
NotificationManager.success(`Data proyek berhasil Ubah`, "Success!!");
@ -786,13 +1132,76 @@ const CreatedProyek = ({ params, ...props }) => {
}
};
const editChecklist = async (id, data) => {
await axios.delete(PROJECT_CHECKLIST_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
item: res.item ? res.item : res.item,
status_exist: res.status_exist,
};
return axios.post(PROJECT_CHECKLIST_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editIssue = async (id, data) => {
await axios.delete(PROJECT_ISSUE_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
description: res.description ? res.description : res.description,
level_issue: res.level_issue,
};
return axios.post(PROJECT_ISSUE_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editRisk = async (id, data) => {
await axios.delete(PROJECT_RISK_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
level_risk: res.level_risk,
description: res.description ? res.description : res.description,
preventive_risk: res.preventive_risk ? res.preventive_risk : res.preventive_risk
};
return axios.post(PROJECT_RISK_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editParticipant = async (id, data) => {
await axios.delete(PROJECT_PARTICIPANT_DELETE_BY_PROYEK(id), HEADER);
// if (restDelete){
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
tittle: res.tittle ? res.tittle : res.title,
tittle: res.tittle ? res.tittle : res.tittle,
name: res.name,
};
return axios.post(PROJECT_PARTICIPANT_ADD, payload, HEADER);
@ -1081,12 +1490,16 @@ const CreatedProyek = ({ params, ...props }) => {
<span className="menu-text">Request Tools</span>
</div> */}
{/* <Link to={`/project-charter/${text.id}/gantt`}> */}
{
/*text.type_proyek_id != 9 ?*/
<div className="menu-list" onClick={() => handleOpenDialogGantt(text)}>
<span className="menu-icon">
<i className="fa fa-bars"></i>
</span>
<span className="menu-text">Gantt</span>
</div>
/*: null*/
}
<div className="menu-list" onClick={() => handleSCurve(text)}>
<span className="menu-icon">
<i className="fa fa-line-chart"></i>
@ -1338,6 +1751,7 @@ const CreatedProyek = ({ params, ...props }) => {
dataPhaseProject={dataPhaseProject}
dataDivisions={dataDivisions}
dataPM={dataPm}
projectImage={image}
/>
),
[
@ -1347,6 +1761,7 @@ const CreatedProyek = ({ params, ...props }) => {
dataPhaseProject,
dataTypeProyek,
idTask,
image
]
);
@ -1460,8 +1875,16 @@ const CreatedProyek = ({ params, ...props }) => {
toggleDialog={toggleAddDialogView}
projectCharter={projectCharter}
projectParticipant={projectParticipant}
projectChecklist={projectChecklist}
projectIssue={projectIssue}
projectRisk={projectRisk}
projectMilestone={projectMilestone}
projectApproval={projectApproval}
projectManager={projectPM}
projectK3={projectK3Search}
assignHR={projectAssignHR}
projectImage={image}
idTask={idTask}
/>
),
[openDialogViewDetail]

32
src/views/SimproV2/Divisi/DialogForm.js

@ -29,8 +29,17 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
}
}, [dataEdit, openDialog])
const validation = () => {
if (!name || name === "") {
alert("Division Name cannot be empty!");
return true;
}
}
const handleSave = () => {
let data = '';
const err = validation();
if (!err) {
if (typeDialog === "Save") {
data = {
name: name,
@ -49,28 +58,39 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
}
setId(0)
setDescription('')
setName('')
}
}
const handleCancel = () => {
closeDialog('cancel', 'none')
setId(0)
setDescription('')
setName('')
}
const renderForm = () => {
return (
<Form>
<Row>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('name')}</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
<Label className="capitalize">{t('name')}<span style={{ color: "red" }}>*</span></Label>
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={t('inputName')}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">{t('nameDivision')}</Label>
<Label className="capitalize">{t('Parent Division')}</Label>
<Select showSearch
value={parent}
onChange={onChangeParent}
@ -85,7 +105,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
</Col>
</Row>
<Row>
<Col md={6}>
<Col md={12}>
<FormGroup>
<Label className="capitalize">{t('description')}</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />

34
src/views/SimproV2/Divisi/index.js

@ -47,18 +47,14 @@ const ProjectType = ({ params }) => {
const [idDelete, setIdDelete] = useState(0)
const [openDialog, setOpenDialog] = useState(false)
const [rowsPerPage, setRowsPerPage] = useState(10)
const [search, setSearch] = useState('')
const [search, setSearch] = useState("")
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const [dataDivisions, setDataDivisions] = useState([])
const { t } = useTranslation()
useEffect(() => {
getListDivision()
}, [])
useEffect(() => {
getDataProjectType()
getDataProjectType();
}, [currentPage, rowsPerPage, search])
useEffect(() => {
@ -87,15 +83,15 @@ const ProjectType = ({ params }) => {
const getDataProjectType = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
start = currentPage * rowsPerPage - rowsPerPage;
}
const payload = {
"columns": [
columns: [
{
"name": "name",
"logic_operator": "ilike",
"value": search,
"operator": "AND"
name: "name",
logic_operator: "ilike",
value: search,
operator: "AND"
}
],
"orders": {
@ -115,10 +111,8 @@ const ProjectType = ({ params }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
result.data.data.map((res) => {
res.key = res.id.toString()
});
setDatatable(result.data.data);
let dataRes = result.data.data || [];
setDatatable(dataRes);
setTotalPage(result.data.totalRecord);
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
@ -220,9 +214,9 @@ const ProjectType = ({ params }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getDataProjectType()
NotificationManager.success(`Data berhasil ditambah`, 'Success!!');
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!');
} else {
NotificationManager.error(`${result.data.message}`, 'Failed!!');
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!');
}
}
@ -234,9 +228,9 @@ const ProjectType = ({ params }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
getDataProjectType();
NotificationManager.success(`Data berhasil diedit`, 'Success!!');
NotificationManager.success(`Data berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data gagal di edit`, `Failed!!`);
NotificationManager.error(`Data gagal diubah`, `Failed!!`);
}
}

4
src/views/SimproV2/PanicButton/index.js

@ -219,7 +219,7 @@ class index extends Component {
let dataExport = [];
dataExcel.map((val) => {
let row = {
"Tanggal": moment(val.created_date).format("DD-MM-YYYY HH:MM:SS"),
"Tanggal": moment(val.created_at).format("DD-MM-YYYY HH:MM:SS"),
"Nama Karyawan": val.join_first_name,
"Latitude": val.lat,
"Longitude": val.lon,
@ -275,7 +275,7 @@ class index extends Component {
<i id="tooltipMap" className="fa fa-map" style={{ color: 'black', cursor: "pointer" }} onClick={() => this.handleMap(n)}></i>
</Tooltip>
</td>
<td>{n.created_date !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"}</td>
<td>{n.created_at !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"}</td>
<td>{n.join_first_name !== null ? n.join_first_name : "-"}</td>
<td>{n.status_response !== null ? n.status_response : "-"}</td>
</tr>

27
src/views/SimproV2/ResourceWorker/DialogForm.js

@ -135,6 +135,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
alert("Password doesn't match");
return;
}
if (password.length < 8) {
alert("Password minimum 8 character");
return;
}
data = {
id,
username,
@ -199,7 +203,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
</>
)
}
const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const renderForm = () => {
return (
<Form>
@ -213,7 +220,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<FormGroup>
<Label className="capitalize">{t('nik')} <span style={{ color: "red" }}>*</span></Label>
{/* <Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={`Input NIK (KTP)...`} maxLength="16" /> */}
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value)} placeholder={t('inputNik')} maxLength="16" />
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNik')} maxLength="16" />
</FormGroup>
</Col>
<Col md={6}>
@ -246,7 +253,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Col md={6}>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('inputEmail')} />
<Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('inputEmail')}
onBlur={(e) => {
if (!isValidEmail(e.target.value)) {
alert("Masukkan email yang valid.");
}
}}
/>
</FormGroup>
</Col>
<Col md={6}>
@ -327,7 +340,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Col md={6}>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" defaultValue={""} value={email} onChange={(e) => setEmail(e.target.value)} placeholder={`Email...`} />
<Input type="email" defaultValue={""} value={email} onChange={(e) => setEmail(e.target.value)} placeholder={`Email...`}
onBlur={(e) => {
if (!isValidEmail(e.target.value)) {
alert("Masukkan email yang valid.");
}
}}
/>
</FormGroup>
</Col>
<Col md={6}>

16
src/views/SimproV2/Satuan/index.js

@ -72,12 +72,6 @@ const Satuan = ({ params }) => {
"logic_operator": "ilike",
"value": search,
"operator": "AND"
},
{
"name": "description",
"logic_operator": "ilike",
"value": search,
"operator": "AND"
}
],
"orders": {
@ -181,7 +175,7 @@ const Satuan = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataSatuan()
NotificationManager.success(`Data project type berhasil ditambah`, 'Success!!');
NotificationManager.success(`Satuan berhasil ditambah`, 'Success!!');
} else {
NotificationManager.error(`${result.data.message}`, 'Failed!!');
}
@ -197,9 +191,9 @@ const Satuan = ({ params }) => {
if (result && result.data && result.data.code === 200) {
getDataSatuan();
NotificationManager.success(`Data project type berhasil diedit`, 'Success!!');
NotificationManager.success(`Satuan berhasil diubah`, 'Success!!');
} else {
NotificationManager.error(`Data project type gagal di edit`, `Failed!!`);
NotificationManager.error(`Satuan gagal diubah`, `Failed!!`);
}
}
@ -218,11 +212,11 @@ const Satuan = ({ params }) => {
getDataSatuan()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data project type berhasil dihapus!`, 'Success!!');
NotificationManager.success(`Satuan berhasil dihapus!`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data project type gagal dihapus!}`, 'Failed!!');
NotificationManager.error(`Satuan gagal dihapus!}`, 'Failed!!');
}
}

Loading…
Cancel
Save