diff --git a/src/const/ApiConst.js b/src/const/ApiConst.js index 7e9365c..4241749 100644 --- a/src/const/ApiConst.js +++ b/src/const/ApiConst.js @@ -316,6 +316,7 @@ export const DOCUMENT_DOWNLOAD = (id) => { export const ROLE_ADD = `${BASE_SIMPRO_LUMEN}/role/add`; export const ROLE_SEARCH = `${BASE_SIMPRO_LUMEN}/role/search`; +export const ROLE_LIST = `${BASE_SIMPRO_LUMEN}/role/list`; export const ROLE_EDIT = (id) => { return `${BASE_SIMPRO_LUMEN}/role/update/${id}`; }; @@ -340,6 +341,7 @@ export const MENU_MANAGEMENT = (id) => { return `${BASE_SIMPRO_LUMEN}/menu/management/${id}`; }; export const MENU_SEARCH = `${BASE_SIMPRO_LUMEN}/menu/search`; +export const MENU_LIST = `${BASE_SIMPRO_LUMEN}/menu/list`; export const MENU_EDIT = (id) => { return `${BASE_SIMPRO_LUMEN}/menu/update/${id}`; }; diff --git a/src/views/Dashboard/DashboardBOD.js b/src/views/Dashboard/DashboardBOD.js index 110fb0d..87625f3 100644 --- a/src/views/Dashboard/DashboardBOD.js +++ b/src/views/Dashboard/DashboardBOD.js @@ -613,8 +613,8 @@ const DashboardBOD = () => { label: "", // data: [7, 2, 4, 3], data: PROJECT_PER_DIVISION ? PROJECT_PER_DIVISION.map((item, idx) => item.total) : [], - borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"], - backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"], + borderColor: PROJECT_PER_DIVISION ? PROJECT_PER_DIVISION.map((item, idx) => item.color) : [], + backgroundColor: PROJECT_PER_DIVISION ? PROJECT_PER_DIVISION.map((item, idx) => item.color) : [], borderWidth: 2, borderSkipped: false }, diff --git a/src/views/Dashboard/DashboardProject.js b/src/views/Dashboard/DashboardProject.js index ebc5bfd..4acf02a 100644 --- a/src/views/Dashboard/DashboardProject.js +++ b/src/views/Dashboard/DashboardProject.js @@ -345,7 +345,11 @@ const DashboardProject = () => { result.data.data.kode_sortname && result.data.data.kode_sortname !== "" ) { - getIntegrationInvoice(result.data.data.kode_sortname); + if (SCURVE) { + getIntegrationInvoice(result.data.data.kode_sortname, result.data.data.id); + } else { + getIntegrationInvoice(result.data.data.kode_sortname, result.data.data.id, GANTT_ID); + } } } }; @@ -490,12 +494,16 @@ const DashboardProject = () => { } }; - const getIntegrationInvoice = async (kode_sortname) => { + const getIntegrationInvoice = async (kode_sortname, id, gantt_id = null) => { setIsReadyIntegrationInvoice(false); const URL = `${BASE_OSPRO}/api/project/get-integration-invoice`; - const payload = { + let payload = { search: kode_sortname, + id: id }; + if (gantt_id) { + payload.gantt_id = gantt_id; + } const result = await axios .post(URL, payload, HEADER) .then((res) => res) diff --git a/src/views/Master/MasterBroadcast/DialogDetail.js b/src/views/Master/MasterBroadcast/DialogDetail.js index b4b96cc..b269bf8 100644 --- a/src/views/Master/MasterBroadcast/DialogDetail.js +++ b/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, USER_LIST } from '../../../const/ApiConst'; +import { BASE_SIMPRO_LUMEN, USER_LIST, ROLE_LIST } from '../../../const/ApiConst'; import { Transfer } from 'antd'; import { withTranslation } from 'react-i18next'; const token = window.localStorage.getItem('token'); @@ -43,6 +43,7 @@ class DialogDetail extends Component { }, () => { this.getDataDetail(); this.getDataUsers(); + this.getDataRoles(); this.setState({ isParentClick: false }); }); } @@ -61,6 +62,18 @@ class DialogDetail extends Component { } } + getDataRoles = async () => { + const result = await axios + .get(ROLE_LIST, config) + .then(res => res) + .catch((error) => error.response); + console.log('Get Data Roles', result) + + if (result && result.data && result.status == 200) { + this.setState({ dataRoles: result.data.data }); + } + } + getDataDetail = async () => { countError++; let url = BASE_SIMPRO_LUMEN + `/broadcast/search`; @@ -85,6 +98,7 @@ class DialogDetail extends Component { if (countError < 6) { this.getDataDetail(); this.getDataUsers(); + this.getDataRoles(); } } } @@ -97,7 +111,10 @@ class DialogDetail extends Component { this.props.closeDialog() } render() { + const dataListDetail = this.state.dataListDetail || []; const dataUser = this.state.dataUser || []; + const dataRoles = this.state.dataRoles || []; + return ( {this.props.t('broadcastDetail')} @@ -114,14 +131,42 @@ class DialogDetail extends Component { - {this.state.dataListDetail.map((val, index) => { - const matchedUser = dataUser.find(item => item.id == val.send_to_id); + {dataListDetail.map((val, index) => { + const matchedUserNames = []; + const matchedUserNamesNotKoma = []; + const matchRolesName = []; + + if (typeof val.send_to_id === 'string' && val.send_to_id.includes(',')) { + const sendToIds = val.send_to_id.split(',').map(id => parseInt(id, 10)); + matchedUserNames[index] = sendToIds.map(id => { + const matchedUser = dataUser.find(item => item.id === id); + return matchedUser ?
{"- " + matchedUser.name}
: null; + }); + } + + if (typeof val.send_to_id === 'string' && val.send_to_id.indexOf(',') === -1) { + const id = parseInt(val.send_to_id, 10); + const matchedUser = dataUser.find(item => item.id === id); + matchedUserNamesNotKoma[index] = matchedUser ?
{matchedUser.name}
: null; + } + + if (val.send_to_type === 'roles') { + const id = parseInt(val.send_to_id, 10); + const matchedRole = dataRoles.find(item => item.id === id); + matchRolesName[index] = matchedRole ?
Role {matchedRole.name}
: null; + } + return ( {val.status_send === "" ? "-" : val.status_send} - {val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")} + {val.created_at === "" ? "-" : moment(val.created_at).format("DD-MM-YYYY HH:mm:ss")} {val.description === "" ? "-" : val.description} - { matchedUser ? matchedUser.name : "-" } + + {val.send_to_type === "all" ? "All User" : ""} + {val.send_to_type === "roles" ? matchRolesName[index] : ""} + {typeof val.send_to_id === 'string' && val.send_to_id.indexOf(',') === -1 ? matchedUserNamesNotKoma[index] : ""} + {typeof val.send_to_id === 'string' && val.send_to_id.includes(',') ? matchedUserNames[index] : ""} + {val.title_notif === "" ? "-" : val.title_notif} {val.message_notif === "" ? "-" : val.message_notif} diff --git a/src/views/Master/MasterBroadcast/index.js b/src/views/Master/MasterBroadcast/index.js index 9cadec4..dfc989a 100644 --- a/src/views/Master/MasterBroadcast/index.js +++ b/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 { USER_LIST, BASE_SIMPRO_LUMEN } from '../../../const/ApiConst'; +import { USER_LIST, BASE_SIMPRO_LUMEN, ROLE_LIST } 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'; @@ -92,8 +92,30 @@ class index extends Component { console.log('Get Data User', result) if (result && result.data && result.status == 200) { - this.setState({ dataUser: result.data.data }, () => { - }); + const dataRes = result.data.data; + const finalData = []; + if (dataRes.length > 0) { + dataRes.map((val, index) => { + let data = { + id: val.id, + name: val.name, + }; + finalData.push(data); + }); + } + this.setState({ dataUser: finalData }); + } + } + + getDataRoles = async () => { + const result = await axios + .get(ROLE_LIST, config) + .then(res => res) + .catch((error) => error.response); + console.log('Get Data Roles', result) + + if (result && result.data && result.status == 200) { + this.setState({ dataRoles: result.data.data }); } } @@ -147,6 +169,7 @@ class index extends Component { if (result.data.code === 200) { this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); this.getDataUsers() + this.getDataRoles() } else { NotificationManager.error('Failed retreiving data!!', 'Failed'); } @@ -326,18 +349,47 @@ class index extends Component { handleExportExcel = async () => { const dataExcel = this.state.dataTable || []; const dataUser = this.state.dataUser || []; + const dataRoles = this.state.dataRoles || []; + const dataExport = []; dataExcel.map((val) => { - const matchedUser = dataUser.find(item => item.id == val.send_to_id); + const matchedUserNames = []; + const matchedUserNamesNotKoma = []; + const matchRolesName = []; + + if (typeof val.send_to_id === 'string' && val.send_to_id.includes(',')) { + const sendToIds = val.send_to_id.split(',').map(id => parseInt(id, 10)); + matchedUserNames[index] = sendToIds.map(id => { + const matchedUser = dataUser.find(item => item.id === id); + return matchedUser ?
{"- " + matchedUser.name}
: null; + }); + } + + if (typeof val.send_to_id === 'string' && val.send_to_id.indexOf(',') === -1) { + const id = parseInt(val.send_to_id, 10); + const matchedUser = dataUser.find(item => item.id === id); + matchedUserNamesNotKoma[index] = matchedUser ?
{matchedUser.name}
: null; + } + + if (val.send_to_type === 'roles') { + const id = parseInt(val.send_to_id, 10); + const matchedRole = dataRoles.find(item => item.id === id); + matchRolesName[index] = matchedRole ?
{matchedRole.name}
: null; + } + let row = { "Tanggal Broadcast": moment(val.created_at).format("YYYY-MM-DD HH:mm:ss"), "Judul": val.title_notif, - "Penerima": matchedUser ? matchedUser.name : "-", + "Penerima": (val.send_to_type === "all" ? "All User" : "") + + (val.send_to_type === "roles" ? (matchRolesName[index] ? 'Role: ' + matchRolesName[index].props.children : "") : "") + + (typeof val.send_to_id === 'string' && val.send_to_id.indexOf(',') === -1 ? (matchedUserNamesNotKoma[index] ? matchedUserNamesNotKoma[index].props.children : "") : "") + + (typeof val.send_to_id === 'string' && val.send_to_id.includes(',') ? (matchedUserNames[index] ? matchedUserNames[index].map(item => item.props.children).join("") : "") : ""), "Pesan": val.message_notif, "Deskripsi": val.description, "Status": val.status_send - } + }; dataExport.push(row); + }); const fileName = "Broadcast.xlsx"; const ws = XLSX.utils.json_to_sheet(dataExport); @@ -399,14 +451,37 @@ class index extends Component { ] const dataTable2 = this.state.dataTable || []; const dataUser = this.state.dataUser || []; - + const dataRoles = this.state.dataRoles || []; return ( - {dataTable2.length !== 0 ? dataTable2.map((n) => { - const matchedUser = dataUser.find(item => item.id == n.send_to_id); - return ( - - + {dataTable2.length !== 0 ? dataTable2.map((n, index) => { + const matchedUserNames = []; + const matchedUserNamesNotKoma = []; + const matchRolesName = []; + + if (typeof n.send_to_id === 'string' && n.send_to_id.includes(',')) { + const sendToIds = n.send_to_id.split(',').map(id => parseInt(id, 10)); + matchedUserNames[index] = sendToIds.map(id => { + const matchedUser = dataUser.find(item => item.id === id); + return matchedUser ?
{"- " + matchedUser.name}
: null; + }); + } + + if (typeof n.send_to_id === 'string' && n.send_to_id.indexOf(',') === -1) { + const id = parseInt(n.send_to_id, 10); + const matchedUser = dataUser.find(item => item.id === id); + matchedUserNamesNotKoma[index] = matchedUser ?
{matchedUser.name}
: null; + } + + if (n.send_to_type === 'roles') { + const id = parseInt(n.send_to_id, 10); + const matchedRole = dataRoles.find(item => item.id === id); + matchRolesName[index] = matchedRole ?
Role {matchedRole.name}
: null; + } + + return ( + + {n.status_send === 'completed' || n.status_send === 'failed' || n.status_send === 'send' || n.status_send === 'resend' ? this.renderBtnResend(n.id) : @@ -418,15 +493,21 @@ class index extends Component { Detail - - {n.title_notif} - {n.message_notif !== "" ? n.message_notif : "-"} - {n.description !== "" ? n.description : "-"} - { matchedUser ? matchedUser.name : "-" } - {n.status_send !== "" ? n.status_send : "-"} - {n.created_at !== "" ? moment.utc(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"} - - ); + + + {n.title_notif} + {n.message_notif !== "" ? n.message_notif : "-"} + {n.description !== "" ? n.description : "-"} + + {n.send_to_type === "all" ? "All User" : ""} + {n.send_to_type === "roles" ? matchRolesName[index] : ""} + {typeof n.send_to_id === 'string' && n.send_to_id.indexOf(',') === -1 ? matchedUserNamesNotKoma[index] : ""} + {typeof n.send_to_id === 'string' && n.send_to_id.includes(',') ? matchedUserNames[index] : ""} + + {n.status_send !== "" ? n.status_send : "-"} + {n.created_at !== "" ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"} + + ); }) : {this.props.t('noData')} diff --git a/src/views/Master/MasterMenu/index.js b/src/views/Master/MasterMenu/index.js index 3c78402..7c0e9bc 100644 --- a/src/views/Master/MasterMenu/index.js +++ b/src/views/Master/MasterMenu/index.js @@ -5,7 +5,7 @@ import SweetAlert from 'react-bootstrap-sweetalert'; import axios from 'axios'; import { Button } from 'reactstrap'; import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; -import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE } from '../../../const/ApiConst.js'; +import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE, MENU_LIST } from '../../../const/ApiConst.js'; import { NotificationContainer, NotificationManager } from 'react-notifications'; import { Pagination, Tooltip, Table } from 'antd'; import { useTranslation } from 'react-i18next'; @@ -67,23 +67,21 @@ const Index = ({ params }) => { }; const getDataAllMenu = async () => { - const payload = { - "paging": { "start": 0, "length": -1 }, - "columns": [ - { "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" } - ], - "joins": [], - "orders": { "columns": ["id"], "ascending": false } - } const result = await axios - .post(MENU_SEARCH, payload, config) - .then(res => res) - .catch((error) => error.response); + .get(MENU_LIST, config) + .then(res => res) + .catch((error) => error.response); if (result && result.data && result.data.code == 200) { - setAllDataMenu(result.data.data); - } else { - } + let arr = [] + let dataRes = result.data.data; + for (const v in dataRes) { + arr.push(dataRes[v]) + } + setAllDataMenu(arr); + }else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } } const getDataMenu = async () => { @@ -123,6 +121,7 @@ const Index = ({ params }) => { const handleOpenDialog = async (type) => { await setTypeDialog(type) + getDataAllMenu(); setOpenDialog(true) } diff --git a/src/views/SimproV2/CreatedProyek/AsignCustProject.js b/src/views/SimproV2/CreatedProyek/AsignCustProject.js index 1b9a70c..dca803a 100644 --- a/src/views/SimproV2/CreatedProyek/AsignCustProject.js +++ b/src/views/SimproV2/CreatedProyek/AsignCustProject.js @@ -32,11 +32,6 @@ const AssignCustProject = ({ openDialog, closeDialog, toggleDialog, idTask, proy } }, [openDialog]); - useEffect(() => { - if (openDialog) { - } - }, [dataUserToProject]) - const getDataAssignHr = async () => { const payload = { "paging": { @@ -45,7 +40,8 @@ const AssignCustProject = ({ openDialog, closeDialog, toggleDialog, idTask, proy }, "columns": [ { "name": "name", "logic_operator": "ilike", "value": "", "table_name": "m_users" }, - { "name": "proyek_id", "logic_operator": "=", "value": idTask } + { "name": "proyek_id", "logic_operator": "=", "value": idTask }, + { "name": "is_customer", "logic_operator": "=", "value": "true" } ], "joins": [ { "name": "m_users", "column_join": "user_id", "column_results": ["name"] }, @@ -144,7 +140,9 @@ const AssignCustProject = ({ openDialog, closeDialog, toggleDialog, idTask, proy } const handleCloseDialogFormTools = (type, data) => { - if (type === "add") getDataAssignHr(); + if (type === "add") { + getDataAssignHr() + } if (type === "success") { NotificationManager.success( `Assign Customer Project berhasil disimpan!`, diff --git a/src/views/SimproV2/CreatedProyek/AsignHrProject.js b/src/views/SimproV2/CreatedProyek/AsignHrProject.js index 4abb8a7..ff990b1 100644 --- a/src/views/SimproV2/CreatedProyek/AsignHrProject.js +++ b/src/views/SimproV2/CreatedProyek/AsignHrProject.js @@ -1,304 +1,305 @@ -import React, { useEffect, useState, useMemo } from 'react' -import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -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 axios from "../../../const/interceptorApi" -import { NotificationContainer, NotificationManager } from 'react-notifications'; -import SweetAlert from 'react-bootstrap-sweetalert'; -import FormAsignHr from './FormAsignHr'; -import { formatThousand } from '../../../const/CustomFunc'; - -const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsResource, proyekName }) => { - const token = localStorage.getItem("token") - const HEADER = { - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${token}` - } - } - const [dataUserToProject, setdataUserToProject] = useState([]) - 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) { - getDataAssignHr(); - } - }, [openDialog]); - - useEffect(() => { - if (openDialog) { - getDataProjectRole(); - getDataUser(); - } - }, [dataUserToProject]) - - const getDataAssignHr = async () => { - const payload = { - "paging": { - "start": 0, - "length": -1 - }, - "columns": [ - { "name": "name", "logic_operator": "ilike", "value": "", "table_name": "m_users" }, - { "name": "proyek_id", "logic_operator": "=", "value": idTask } - ], - "joins": [ - { "name": "m_users", "column_join": "user_id", "column_results": ["name"] }, - { "name": "m_role_proyek", "column_join": "project_role", "column_results": ["name"] }, - ], - "orders": { - "columns": [ - "id" - ], - "ascending": false - } - } - const URL = ASSIGN_HR_PROJECT_SEARCH - const result = await axios - .post(URL, payload, HEADER) - .then(res => res) - .catch((error) => error.response); - - if (result && result.data && result.data.code == 200) { - let dataRes = result.data.data || [] - - setdataUserToProject(dataRes); - } else { - NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); - } - } - - const getDataUser = async () => { - const HEADER_ADW = { - headers: { - "Authorization": `${TOKEN_ADW}` - } - } - const result = await axios - // .get(`${API_ADW}employees`, HEADER_ADW) - .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) - } - - const cancelDelete = () => { - setAlertDelete(false) - setIdDelete(0) - } - - const onConfirmDelete = async () => { - let urlDel = ASSIGN_HR_PROJECT_DELETE(idDelete) - const result = await axios.delete(urlDel, HEADER) - .then(res => res) - .catch((error) => error.response); - - if (result && result.data && result.data.code === 200) { - getDataAssignHr() - setIdDelete(0) - setAlertDelete(false) - NotificationManager.success(`Data assign human resource berhasil dihapus`, 'Success!!'); - } else { - setIdDelete(0) - setAlertDelete(false) - NotificationManager.error(`Data assign human resource gagal dihapus`, 'Failed!!'); - } - } - - const handleEdit = async (data) => { - await setDataEdit(data) - setOpenDialogFormTools(true) - } - - const handleOpenDialogFormTools = () => { - setOpenDialogFormTools(true) - } - - const handleCancel = () => { - closeDialog('cancel', 'none') - } - - - const RenderTable = useMemo(() => { - const columns = [ - { - title: 'Action', - dataIndex: '', - key: 'x', - className: "nowrap", - render: (text, record) => <> - - {" "} - - , - }, - { 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" }, - - ]; - - return ( - - ) - }, [dataUserToProject]) - - const renderForm = () => { - return ( -
- {RenderTable} -
- ) - } - - 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'); - } - } - - 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) - } - - - return ( - <> - - cancelDelete()} - focusCancelBtn - > - Delete this data - - - - -
Assign Human Resource - {proyekName}
-
- - {renderForm()} - - {/* - - */} -
- - - ) - -} - -export default AssignHrProject; +import React, { useEffect, useState, useMemo } from 'react' +import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +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 axios from "../../../const/interceptorApi" +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import FormAsignHr from './FormAsignHr'; +import { formatThousand } from '../../../const/CustomFunc'; + +const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsResource, proyekName }) => { + const token = localStorage.getItem("token") + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + const [dataUserToProject, setdataUserToProject] = useState([]) + 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) { + getDataAssignHr(); + } + }, [openDialog]); + + useEffect(() => { + if (openDialog) { + getDataProjectRole(); + getDataUser(); + } + }, [dataUserToProject]) + + const getDataAssignHr = async () => { + const payload = { + "paging": { + "start": 0, + "length": -1 + }, + "columns": [ + { "name": "name", "logic_operator": "ilike", "value": "", "table_name": "m_users" }, + { "name": "proyek_id", "logic_operator": "=", "value": idTask }, + { "name": "is_customer", "logic_operator": "=", "value": "false" } + ], + "joins": [ + { "name": "m_users", "column_join": "user_id", "column_results": ["name"] }, + { "name": "m_role_proyek", "column_join": "project_role", "column_results": ["name"] }, + ], + "orders": { + "columns": [ + "id" + ], + "ascending": false + } + } + const URL = ASSIGN_HR_PROJECT_SEARCH + const result = await axios + .post(URL, payload, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code == 200) { + let dataRes = result.data.data || [] + + setdataUserToProject(dataRes); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const getDataUser = async () => { + const HEADER_ADW = { + headers: { + "Authorization": `${TOKEN_ADW}` + } + } + const result = await axios + // .get(`${API_ADW}employees`, HEADER_ADW) + .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) + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const onConfirmDelete = async () => { + let urlDel = ASSIGN_HR_PROJECT_DELETE(idDelete) + const result = await axios.delete(urlDel, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataAssignHr() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data assign human resource berhasil dihapus`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data assign human resource gagal dihapus`, 'Failed!!'); + } + } + + const handleEdit = async (data) => { + await setDataEdit(data) + setOpenDialogFormTools(true) + } + + const handleOpenDialogFormTools = () => { + setOpenDialogFormTools(true) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + } + + + const RenderTable = useMemo(() => { + const columns = [ + { + title: 'Action', + dataIndex: '', + key: 'x', + className: "nowrap", + render: (text, record) => <> + + {" "} + + , + }, + { 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" }, + + ]; + + return ( +
+ ) + }, [dataUserToProject]) + + const renderForm = () => { + return ( +
+ {RenderTable} +
+ ) + } + + 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'); + } + } + + 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) + } + + + return ( + <> + + cancelDelete()} + focusCancelBtn + > + Delete this data + + + + +
Assign Human Resource - {proyekName}
+
+ + {renderForm()} + + {/* + + */} +
+ + + ) + +} + +export default AssignHrProject; diff --git a/src/views/SimproV2/CreatedProyek/DialogAssignCust.js b/src/views/SimproV2/CreatedProyek/DialogAssignCust.js index 940250c..c680615 100644 --- a/src/views/SimproV2/CreatedProyek/DialogAssignCust.js +++ b/src/views/SimproV2/CreatedProyek/DialogAssignCust.js @@ -3,7 +3,7 @@ import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import { Button, Form } from 'reactstrap'; import axios from "../../../const/interceptorApi"; import { - USER_LIST, + USER_SEARCH, ASSIGN_HR_PROJECT_SEARCH, ASSIGN_HR_PROJECT_ADD_MULTIPLE } from '../../../const/ApiConst'; @@ -40,8 +40,29 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idTask }) => const getDataAssignCustomer = async () => { + const payload = { + "select": [ + "id", + "name", + "role_id" + ], + "paging": { + "start": 0, + "length": -1 + }, + "columns": [ + { "name": "role_id", "logic_operator": "=", "value": 44 } + ], + "orders": { + "columns": [ + "id" + ], + "ascending": false + } + } + const URL = USER_SEARCH; const result = await axios - .get(USER_LIST, HEADER) + .post(URL, payload, HEADER) .then(res => res) .catch((error) => error.response); @@ -99,6 +120,12 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idTask }) => const getCustProject = async () => { const payload = { + "select": [ + "id", + "user_id", + "proyek_id", + "is_customer" + ], "columns": [ { "name": "proyek_id", "logic_operator": "=", "value": idTask }, {"name": "is_customer", "logic_operator": "=", "value": "true"} diff --git a/src/views/SimproV2/CreatedProyek/DialogFormProyek.js b/src/views/SimproV2/CreatedProyek/DialogFormProyek.js index 7dbe82b..e09fd47 100644 --- a/src/views/SimproV2/CreatedProyek/DialogFormProyek.js +++ b/src/views/SimproV2/CreatedProyek/DialogFormProyek.js @@ -332,18 +332,35 @@ const DialogFormProyek = ({ setHealthBudget(val); }; - const onChangePm = (val) => { - let data = [...dataPM]; - var item = data.find((item) => item.id === val); - participants.push({ - id: lastIdxParticipants + 1, - title: "PM", - name: item.name, - }); - setParticipants(participants); - setLastIdxParticipants(lastIdxParticipants + 1); - setPic(val); - }; + const onChangePm = (val) => { + const item = dataPM.find((item) => item.id === val); + const existingParticipant = participants.find((participant) => participant.tittle === "PM"); + if (existingParticipant) { + setParticipants((prevParticipants) => { + return prevParticipants.map((participant) => { + if (participant.tittle === "PM") { + return { + ...participant, + name: item.name, + }; + } + return participant; + }); + }); + } else { + setParticipants((prevParticipants) => [ + ...prevParticipants, + { + id: item.id, + tittle: "PM", + name: item.name, + }, + ]); + setLastIdxParticipants(lastIdxParticipants + 1); + } + + setPic(val); + }; const onChangeCurrency = (val) => { let curr = val.split("|"); // code|symbol|name @@ -399,7 +416,7 @@ const DialogFormProyek = ({ const addParticipant = () => { participants.push({ id: lastIdxParticipants + 1, - title: "", + tittle: "", name: "", }); setParticipants(participants); @@ -438,7 +455,24 @@ const DialogFormProyek = ({ }; const handleInputChangeParticipants = (e, index) => { - const { name, value } = e.target; + const { name, value } = e.target; + const existingParticipant = participants.find((participant) => participant.tittle === "PM"); + if(value.toLowerCase() === "pm" && name === "tittle" && existingParticipant) + { + alert('PM is already exist!'); + setParticipants((prevParticipants) => + prevParticipants.map((participant, i) => { + if (i === index) { + return { + ...participant, + tittle: "", + }; + } + return participant; + }) + ); + return false; + } const newParticipants = [...participants]; newParticipants[index][name] = value; setParticipants(newParticipants); @@ -566,7 +600,7 @@ const DialogFormProyek = ({ const addApproval = () => { approval.push({ id: lastIdxApproval + 1, - title: "", + tittle: "", name: "", date: moment(), }); @@ -1321,8 +1355,8 @@ const DialogFormProyek = ({
handleInputChangeParticipants(e, index)} /> @@ -1421,7 +1455,7 @@ const DialogFormProyek = ({ handleInputChangeApproval(e, index)} /> diff --git a/src/views/SimproV2/CreatedProyek/DialogGantt.js b/src/views/SimproV2/CreatedProyek/DialogGantt.js index fdce115..439f084 100644 --- a/src/views/SimproV2/CreatedProyek/DialogGantt.js +++ b/src/views/SimproV2/CreatedProyek/DialogGantt.js @@ -74,14 +74,16 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName "select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], "columns": [ { "name": "hierarchy_ftth_id", "logic_operator": "=", "value": hierarchyId, "operator": "AND" } - ] + ], + "orders": { "columns": ["name_version"], "ascending": true } } } else { payload = { "select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], "columns": [ { "name": "proyek_id", "logic_operator": "=", "value": idTask, "operator": "AND" } - ] + ], + "orders": { "columns": ["name_version"], "ascending": true }, } } const result = await axios diff --git a/src/views/SimproV2/CreatedProyek/DialogHierarchy.js b/src/views/SimproV2/CreatedProyek/DialogHierarchy.js index 7c1f99a..a6ac1b1 100644 --- a/src/views/SimproV2/CreatedProyek/DialogHierarchy.js +++ b/src/views/SimproV2/CreatedProyek/DialogHierarchy.js @@ -16,6 +16,7 @@ import { useTranslation } from 'react-i18next'; import { async } from '@dabeng/react-orgchart'; import { Link } from 'react-router-dom'; import { use } from 'i18next'; +import _ from 'lodash'; const DialogHierarchy = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName }) => { const token = localStorage.getItem("token") const HEADER = { @@ -154,7 +155,8 @@ const DialogHierarchy = ({ openDialog, closeDialog, toggleDialog, idTask, proyek .catch((error) => error.response); if (result && result.status == 200) { - setDataHierarchy(result.data.data); + const sortedData = _.orderBy(result.data.data, ['name'], ['asc']); + setDataHierarchy(sortedData); } else { NotificationManager.error(`Data gantt project gagal terload silahkan coba lagi!`, 'Failed!!'); } @@ -340,4 +342,4 @@ const DialogHierarchy = ({ openDialog, closeDialog, toggleDialog, idTask, proyek } -export default DialogHierarchy; +export default DialogHierarchy; diff --git a/src/views/SimproV2/CreatedProyek/FormAsignHr.js b/src/views/SimproV2/CreatedProyek/FormAsignHr.js index b02909d..0c7927f 100644 --- a/src/views/SimproV2/CreatedProyek/FormAsignHr.js +++ b/src/views/SimproV2/CreatedProyek/FormAsignHr.js @@ -1,246 +1,216 @@ -import React, { useEffect, useState } from 'react' -import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; -import { DatePicker, Select } from 'antd'; -import 'antd/dist/antd.css'; -import { formatNumber } from '../../../const/CustomFunc'; -const { Option } = Select - -const FormAsignHr = ({ openDialog, closeDialog, toggleDialog, idTask, dataEdit, dataHr, dataCurrentHr, dataRole }) => { - const [id, setId] = useState(null) - const [typeForm, setTypeForm] = useState('add') - const [user, setUser] = useState(null) - const [rbs, setRbs] = useState("") - const [projectRole, setProjectRole] = useState(null) - const [groupR, setGroupR] = useState("") - const [maxUsed, setMaxUsed] = useState("") - const [standartRate, setStandartRate] = useState("") - const [uomStandartRate, setUomStandartRate] = useState(null) - const [overTimeRate, setOverTimeRate] = useState("") - const [overTimeRateUom, setOverTimeRateUom] = useState(null) - const [costPerUsed, setCostPerUsed] = useState("") - const [accrue, setAccrue] = useState("") - const [baseCalender, setBaseCalender] = useState("") - const [listHr, setListHr] = useState([]) - const [isCustomer, setIsCustomer] = useState(false) - - const handleClearData = () => { - setUser(null) - setRbs("") - setProjectRole(null) - setGroupR("") - setMaxUsed("") - setIsCustomer(false) - setStandartRate("") - setUomStandartRate(null) - setOverTimeRate("") - setOverTimeRateUom(null) - setCostPerUsed("") - setAccrue("") - setBaseCalender("") - } - - useEffect(() => { - let data = dataHr || [] - let availableHr = [] - data.map((val, index) => { - if(dataEdit && dataEdit.user_id){ - if(parseInt(val.id)===parseInt(dataEdit.user_id)){ - availableHr.push(val); - } - } - let check = dataCurrentHr.some(function (x) { - return parseInt(val.id)==parseInt(x.user_id) - }); - if(!check){ - availableHr.push(val); - } - }); - setListHr(availableHr) - }, [dataHr, dataCurrentHr, dataEdit]) - - useEffect(() => { - if (idTask && idTask > 0) { - if(dataEdit && dataEdit!=""){ - setTypeForm('edit') - setId(dataEdit.id) - setUser(dataEdit.user_id) - setRbs(dataEdit.rbs) - setProjectRole(dataEdit.project_role) - setGroupR(dataEdit.group_r) - setMaxUsed(dataEdit.max_used ? formatNumber(dataEdit.max_used.toString()) : '') - setIsCustomer(dataEdit.is_customer) - setStandartRate(dataEdit.standart_rate ? formatNumber(dataEdit.standart_rate.toString()) : '') - setUomStandartRate(dataEdit.uom_standart_rate) - setOverTimeRate(dataEdit.overtime_rate ? formatNumber(dataEdit.overtime_rate.toString()) : '') - setOverTimeRateUom(dataEdit.uom_overtime_rate) - setCostPerUsed(dataEdit.cost_per_used) - setAccrue(dataEdit.accrue_at) - setBaseCalender(dataEdit.base_calender) - }else{ - handleClearData() - setTypeForm('add') - } - } else { - handleClearData() - } - }, [openDialog]) - - const handleSave = () => { - let data = ''; - if (typeForm=="edit") { - data = { - id, - proyek_id: idTask, - user_id:user, - project_role:projectRole, - is_customer: isCustomer, - max_used:maxUsed.replaceAll(".", ""), - standart_rate:standartRate.replaceAll(".", ""), - uom_standart_rate:uomStandartRate, - overtime_rate:overTimeRate.replaceAll(".", ""), - uom_overtime_rate:overTimeRateUom, - } - - closeDialog('edit', data); - } else { - data = { - proyek_id: idTask, - user_id:user, - project_role:projectRole, - is_customer: isCustomer, - max_used:maxUsed.replaceAll(".", ""), - standart_rate:standartRate.replaceAll(".", ""), - uom_standart_rate:uomStandartRate, - overtime_rate:overTimeRate.replaceAll(".", ""), - uom_overtime_rate:overTimeRateUom, - } - closeDialog('add', data); - } - handleClearData() - } - - const handleCancel = () => { - closeDialog('cancel', 'none') - handleClearData() - } - - - const renderForm = () => { - return ( - - - - - - - - - - - - - - - - - - setMaxUsed(formatNumber(e.target.value))} value={maxUsed} placeholder='' required/> - - - - - - - -
- setStandartRate(formatNumber(e.target.value))} value={standartRate} placeholder='1.000...' /> - -
- / -
- - - - -
- -
- - - setOverTimeRate(formatNumber(e.target.value))} value={overTimeRate} placeholder='1.000...' /> - -
- / -
- - - - -
- - ) - } - - return ( - <> - - {typeForm=="add" ? "Add" : "Edit" } Assign Human Resource - - {renderForm()} - - - {' '} - - - - - ) - -} - -export default FormAsignHr; +import React, { useEffect, useState } from 'react' +import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; +import { DatePicker, Select } from 'antd'; +import 'antd/dist/antd.css'; +import { formatNumber } from '../../../const/CustomFunc'; +const { Option } = Select + +const FormAsignHr = ({ openDialog, closeDialog, toggleDialog, idTask, dataEdit, dataHr, dataCurrentHr, dataRole }) => { + const [id, setId] = useState(null) + const [typeForm, setTypeForm] = useState('add') + const [user, setUser] = useState(null) + const [rbs, setRbs] = useState("") + const [projectRole, setProjectRole] = useState(null) + const [groupR, setGroupR] = useState("") + const [maxUsed, setMaxUsed] = useState("") + const [standartRate, setStandartRate] = useState("") + const [uomStandartRate, setUomStandartRate] = useState(null) + const [overTimeRate, setOverTimeRate] = useState("") + const [overTimeRateUom, setOverTimeRateUom] = useState(null) + const [costPerUsed, setCostPerUsed] = useState("") + const [accrue, setAccrue] = useState("") + const [baseCalender, setBaseCalender] = useState("") + const [listHr, setListHr] = useState([]) + + const handleClearData = () => { + setUser(null) + setRbs("") + setProjectRole(null) + setGroupR("") + setMaxUsed("") + setStandartRate("") + setUomStandartRate(null) + setOverTimeRate("") + setOverTimeRateUom(null) + setCostPerUsed("") + setAccrue("") + setBaseCalender("") + } + + useEffect(() => { + let data = dataHr || [] + let availableHr = [] + data.map((val, index) => { + if(dataEdit && dataEdit.user_id){ + if(parseInt(val.id)===parseInt(dataEdit.user_id)){ + availableHr.push(val); + } + } + let check = dataCurrentHr.some(function (x) { + return parseInt(val.id)==parseInt(x.user_id) + }); + if(!check){ + availableHr.push(val); + } + }); + setListHr(availableHr) + }, [dataHr, dataCurrentHr, dataEdit]) + + useEffect(() => { + if (idTask && idTask > 0) { + if(dataEdit && dataEdit!=""){ + setTypeForm('edit') + setId(dataEdit.id) + setUser(dataEdit.user_id) + setRbs(dataEdit.rbs) + setProjectRole(dataEdit.project_role) + setGroupR(dataEdit.group_r) + setMaxUsed(dataEdit.max_used ? formatNumber(dataEdit.max_used.toString()) : '') + setStandartRate(dataEdit.standart_rate ? formatNumber(dataEdit.standart_rate.toString()) : '') + setUomStandartRate(dataEdit.uom_standart_rate) + setOverTimeRate(dataEdit.overtime_rate ? formatNumber(dataEdit.overtime_rate.toString()) : '') + setOverTimeRateUom(dataEdit.uom_overtime_rate) + setCostPerUsed(dataEdit.cost_per_used) + setAccrue(dataEdit.accrue_at) + setBaseCalender(dataEdit.base_calender) + }else{ + handleClearData() + setTypeForm('add') + } + } else { + handleClearData() + } + }, [openDialog]) + + const handleSave = () => { + let data = ''; + if (typeForm=="edit") { + data = { + id, + proyek_id: idTask, + user_id:user, + project_role:projectRole, + is_customer: false, + max_used:maxUsed.replaceAll(".", ""), + standart_rate:standartRate.replaceAll(".", ""), + uom_standart_rate:uomStandartRate, + overtime_rate:overTimeRate.replaceAll(".", ""), + uom_overtime_rate:overTimeRateUom, + } + + closeDialog('edit', data); + } else { + data = { + proyek_id: idTask, + user_id:user, + project_role:projectRole, + is_customer: false, + max_used:maxUsed.replaceAll(".", ""), + standart_rate:standartRate.replaceAll(".", ""), + uom_standart_rate:uomStandartRate, + overtime_rate:overTimeRate.replaceAll(".", ""), + uom_overtime_rate:overTimeRateUom, + } + closeDialog('add', data); + } + handleClearData() + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + handleClearData() + } + + + const renderForm = () => { + return ( +
+ +
+ + + + + + + + + + + + + + + setMaxUsed(formatNumber(e.target.value))} value={maxUsed} placeholder='' required/> + + + +
+ + + setStandartRate(formatNumber(e.target.value))} value={standartRate} placeholder='1.000...' /> + +
+ / +
+ + + + +
+ +
+ + + setOverTimeRate(formatNumber(e.target.value))} value={overTimeRate} placeholder='1.000...' /> + +
+ / +
+ + + + +
+ + ) + } + + return ( + <> + + {typeForm=="add" ? "Add" : "Edit" } Assign Human Resource + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default FormAsignHr; diff --git a/src/views/SimproV2/CreatedProyek/ViewProject.js b/src/views/SimproV2/CreatedProyek/ViewProject.js index 9ad4b67..fd566f7 100644 --- a/src/views/SimproV2/CreatedProyek/ViewProject.js +++ b/src/views/SimproV2/CreatedProyek/ViewProject.js @@ -7,7 +7,7 @@ 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 { Tooltip, Spin } from 'antd'; import { useTranslation } from 'react-i18next'; import axios from "../../../const/interceptorApi" import autoTable from "jspdf-autotable"; @@ -47,6 +47,7 @@ const createMarkup = (element) => { const [HR, setAssignHR] = useState("") const formatDate = "DD-MM-YYYY"; const reportTemplateRef = useRef(null); + const [loading, setLoading] = useState(true); const { t } = useTranslation(); const token = localStorage.getItem("token"); @@ -85,6 +86,7 @@ const createMarkup = (element) => { setMilestone([]) setPotentialRisks("") setApproval([]) + setLoading(false) } }, [openDialog]); @@ -93,7 +95,7 @@ const createMarkup = (element) => { setProyekName(projectCharter.nama); setDescription(projectCharter.keterangan); setKodeShortname(projectCharter.kode_sortname); - setLokasiKantor(projectCharter.lokasi_kantor); + setLokasiKantor(projectCharter.area_kerja); setDurasiProyek(projectCharter.durasi_proyek); setMulaiProyek(projectCharter.mulai_proyek); setValueProyek(projectCharter.value_proyek); @@ -171,12 +173,11 @@ const createMarkup = (element) => { setAssignHR(assignHR) } }, [assignHR]); - const handleExportPdf = async () => { const doc = new jsPDF({ orientation: 'landscape', unit: 'px', - format: [1130, 1000] + format: [1106, 1000] }); doc.html(reportTemplateRef.current, { @@ -212,14 +213,18 @@ const createMarkup = (element) => { const K3Number = number[index]; return( - - + + ) }) ) }else{ - return () + return ( + + + + ); } } @@ -231,10 +236,10 @@ const createMarkup = (element) => { const ChecklistNumber = number[index]; return( - - - + + @@ -243,7 +248,12 @@ const createMarkup = (element) => { }) ) }else{ - return () + return ( + + + + + ); } } @@ -254,17 +264,21 @@ const createMarkup = (element) => { return( - + ) }) ) }else{ - return () + return ( + + + + ) } } @@ -275,18 +289,23 @@ const createMarkup = (element) => { return( - - + + ) }) ) }else{ - return () + return ( + + + + + ) } } @@ -297,20 +316,25 @@ const createMarkup = (element) => { return( ) }) ) }else{ - return () + return ( + + + + + ) } } @@ -328,20 +352,28 @@ const createMarkup = (element) => { return ( ); }) ); } else { - return (); + return ( + + + + + ); } } @@ -359,7 +391,10 @@ const createMarkup = (element) => { }) ) }else{ - return () + return ( + + + ) } } @@ -391,9 +426,16 @@ const createMarkup = (element) => { padding: '0', }; + const paddingTable = { + paddingTop:"20px", + paddingLeft: "30px", + paddingRight: "30px" + } + const renderForm = () => { return ( -
+
+

Project Charter

{ K3Number }

{val.checklist_k3_name ? val.checklist_k3_name : "-"}

{ K3Number }

{val.checklist_k3_name ? val.checklist_k3_name : "-"}



--

{ ChecklistNumber }

{val.item ? val.item : "-"}

-

+

{ ChecklistNumber }

{val.item ?? "-"}

+

{val.status_exist === true ? "Tersedia" : "Tidak tersedia"}



---
-

+

{val.level_issue ? val.level_issue : "-"}

{val.description ? val.description : "-"}

{val.description ? val.description : "-"}



--
-

- {val.level_risk ? val.level_risk : "-"} +

+ {val.level_risk ?? "-"}

{val.description ? val.description : "-"}

{val.preventive_risk ? val.preventive_risk : "-"}

{val.description ?? "-"}

{val.preventive_risk ?? "-"}



---
-

{val.join_first_name ? val.join_first_name : val.join_first_name}

+

{val.join_first_name ? val.join_first_name : "-"}

-

{val.join_second_name ? val.join_second_name : val.join_second_name}

+

{val.join_second_name ? val.join_second_name : "-"}

-

{val.join_second_description ? val.join_second_description : val.join_second_description}

+

{val.join_second_description ? val.join_second_description : "-"}



---
-

{milestoneLetter}

+

{milestoneLetter}

-

{val.status}

+

{val.status ?? "-"}

-

 {moment(val.deadline).format(formatDate)}

+

+ +  {moment(val.deadline).format(formatDate)} +



---


 -
@@ -406,7 +448,7 @@ const createMarkup = (element) => {

Nama Proyek

@@ -414,7 +456,7 @@ const createMarkup = (element) => {

Project description

@@ -430,7 +472,7 @@ const createMarkup = (element) => {

Lokasi Proyek

@@ -462,7 +504,7 @@ const createMarkup = (element) => {

Anggaran Proyek

@@ -483,7 +525,7 @@ const createMarkup = (element) => {

Project Manager

@@ -506,7 +548,13 @@ const createMarkup = (element) => { @@ -522,7 +570,11 @@ const createMarkup = (element) => { @@ -562,7 +614,7 @@ const createMarkup = (element) => { -

+

+ {lateProyek ? ( + + ) : ( + "-" + )} +

-

{proyekName ?? '-'}

+

{proyekName ?? '-'}

-

{description ?? '-'}

+

{description != "" ? description : '-'}

-

 {lokasi ?? '-' }

+

 {lokasi != "" ? lokasi :'-' }

-

{currency}. {formatThousand(budget)}

+

{currency}. {formatThousand(budget)}

-

 {PM}

+

 {PM ?? "-"}

-

{objectives ?? '-'}

+

+ {objectives ? ( + + ) : ( + '-' + )} +

    -
  • { scoupeProyek ?? '-' }
  • + {scoupeProyek ? ( +
  • { scoupeProyek ?? '-' }
  • + ) : ( + "-" + )}

  {image ? ( - + ) : ( '-' )} @@ -645,7 +697,13 @@ const createMarkup = (element) => {

@@ -659,7 +717,13 @@ const createMarkup = (element) => { -

{projectSuccess ?? '-'}

+

+ {projectSuccess ? ( + + ) : ( + '-' + )} +

@@ -674,7 +738,13 @@ const createMarkup = (element) => { -

+

+ {assumtionProyek ? ( + + ) : ( + '-' + )} +

@@ -741,15 +811,10 @@ const createMarkup = (element) => { <> -
-
- Project -
-
- - - -
+
+ + +
diff --git a/src/views/SimproV2/CreatedProyek/index.js b/src/views/SimproV2/CreatedProyek/index.js index aa85b54..2f021aa 100644 --- a/src/views/SimproV2/CreatedProyek/index.js +++ b/src/views/SimproV2/CreatedProyek/index.js @@ -325,7 +325,7 @@ const CreatedProyek = ({ params, ...props }) => { }, // { "name": "subproyeks.m_subproyek", "column_join": "parent_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual"] } ], - orders: { columns: ["id"], ascending: false }, + orders: { columns: ["nama"], ascending: true }, paging: { start: start, length: rowsPerPage }, }; @@ -601,8 +601,8 @@ const CreatedProyek = ({ params, ...props }) => { .catch((error) => error.response); if (result && result.data && result.data.code == 200) { - 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}; + const {value_proyek,area_kerja,scoupe_of_work, kode_sortname,nama,mulai_proyek,rencana_biaya,keterangan,durasi_proyek,project_objectives,potential_risk,currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when} = result.data.data; + const dataToSend = {value_proyek,area_kerja,scoupe_of_work, kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when}; setProjectCharter(dataToSend); } else { NotificationManager.error("Gagal Mengambil Data!!", "Failed"); @@ -956,7 +956,7 @@ const CreatedProyek = ({ params, ...props }) => { const request = data.map((res) => { const payload = { proyek_id: parseInt(id), - tittle: res.title, + tittle: res.tittle, name: res.name, }; return axios.post(PROJECT_PARTICIPANT_ADD, payload, HEADER); @@ -1356,7 +1356,7 @@ const CreatedProyek = ({ params, ...props }) => { }, // { "name": "subproyeks.m_subproyek", "column_join": "parent_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual"] } ], - orders: { columns: ["id"], ascending: false }, + orders: { columns: ["nama"], ascending: true }, }; const result = await axios @@ -1971,7 +1971,7 @@ const CreatedProyek = ({ params, ...props }) => { )} - + Close} title="Export" diff --git a/src/views/SimproV2/Divisi/DialogForm.js b/src/views/SimproV2/Divisi/DialogForm.js index dfced74..62ce6c2 100644 --- a/src/views/SimproV2/Divisi/DialogForm.js +++ b/src/views/SimproV2/Divisi/DialogForm.js @@ -6,12 +6,16 @@ import { import { Select } from 'antd'; import 'antd/dist/antd.css'; import { useTranslation } from 'react-i18next'; +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; const { Option } = Select const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataDivisions }) => { const [id, setId] = useState(0) const [name, setName] = useState('') const [parent, setParent] = useState(null) const [description, setDescription] = useState('') + const [color, setColor] = useState('') const { t } = useTranslation() const onChangeParent = (val) => { @@ -23,9 +27,11 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi setId(dataEdit.id) setDescription(dataEdit.description) setName(dataEdit.name) - setParent(dataEdit.parent) + setParent(dataEdit.parent) + setColor(dataEdit.color) } else { setId(0) + setColor('') } }, [dataEdit, openDialog]) @@ -42,30 +48,35 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi if (!err) { if (typeDialog === "Save") { data = { - name: name, + name, description, - parent + parent, + color } closeDialog('save', data); } else { data = { id, - name: name, + name, description, - parent + parent, + color } closeDialog('edit', data); } setId(0) setDescription('') setName('') + setParent(null) + setColor('') } } const handleCancel = () => { closeDialog('cancel', 'none') setId(0) setDescription('') - setName('') + setName('') + setParent(null) } const renderForm = () => { @@ -89,22 +100,22 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi - - - - - - - + + + + + + + @@ -112,6 +123,14 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi + + + + + setColor(e.color)} /> + + + ) } diff --git a/src/views/SimproV2/Divisi/InputColor.js b/src/views/SimproV2/Divisi/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/SimproV2/Divisi/InputColor.js @@ -0,0 +1,46 @@ +import React from "react"; +import Input from "antd/lib/input"; +import Button from "antd/lib/button"; +import Dropdown from "antd/lib/dropdown"; +import { Panel } from 'rc-color-picker' +import "antd/dist/antd.css"; +import "./styles.css"; + +export default function InputColor(props) { + const { color, onChange } = props; + + const [internalColor, setInternalColor] = React.useState(color); + + const handleChange = (color) => { + setInternalColor(color.color); + + if (onChange) { + onChange(color); + } + }; + + const overlay = ( +
+ +
+ ); + + return ( + <> + setInternalColor(e.target.value)} + suffix={ + + + + } + /> + + ); +} + diff --git a/src/views/SimproV2/Divisi/index.js b/src/views/SimproV2/Divisi/index.js index 9ab06d3..17e576a 100644 --- a/src/views/SimproV2/Divisi/index.js +++ b/src/views/SimproV2/Divisi/index.js @@ -25,6 +25,7 @@ const config = { const column = [ { name: "Nama" }, { name: "Deskripsi" }, + { name: "Color" }, ] const ProjectType = ({ params }) => { @@ -72,8 +73,10 @@ const ProjectType = ({ params }) => { if (listDivions && listDivions.data && listDivions.data.code == 200) { let arr = [] - for (const v in listDivions.data.data) { - arr.push(listDivions.data.data[v]) + let dataRes = listDivions.data.data; + const filteredData = dataRes.filter(item => item.parent === null); + for (const v in filteredData) { + arr.push(filteredData[v]) } setDataDivisions(arr); } else { @@ -97,7 +100,7 @@ const ProjectType = ({ params }) => { "orders": { "ascending": true, "columns": [ - 'id' + 'name' ] }, "paging": { @@ -183,7 +186,8 @@ const ProjectType = ({ params }) => { }; const handleOpenDialog = (type) => { - setOpenDialog(true) + setOpenDialog(true) + getListDivision(); setTypeDialog(type) } @@ -348,7 +352,16 @@ const ProjectType = ({ params }) => {
{n.name} - {n.description} + {n.description ?? '-'} + {n.color != null ? ( + + + + + + ): ( + No color set + )} ) })} diff --git a/src/views/SimproV2/Divisi/styles.css b/src/views/SimproV2/Divisi/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/SimproV2/Divisi/styles.css @@ -0,0 +1,41 @@ +.App { + font-family: sans-serif; + padding: 20px; +} + +h2 { + margin-top: 40px; +} + +.rc-color-picker-panel { + border: 1px solid #ccc; +} +.rc-color-picker-panel-inner { + border: none; + box-shadow: none; +} +.rc-color-picker-panel-board-hsv { + border-radius: 12px; + outline: none; +} +.rc-color-picker-panel-board-value { + border: none; + border-radius: 12px; +} +.rc-color-picker-panel-board-saturation { + border: none; + border-radius: 12px; +} +.rc-color-picker-panel-ribbon { + border-radius: 12px; +} +.rc-color-picker-panel-wrap-preview { + border-radius: 12px; +} +.rc-color-picker-panel-preview span { + border-radius: 12px; +} +.rc-color-picker-panel-preview input { + border-radius: 12px; +} +