From 5c4c75fe6c9298bdc7f253bf92b7f39795c5298e Mon Sep 17 00:00:00 2001 From: farhantock Date: Wed, 13 Dec 2023 20:32:40 +0700 Subject: [PATCH 01/11] update filter by company --- src/views/Dashboard/DashboardProjectCarousell.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/views/Dashboard/DashboardProjectCarousell.js b/src/views/Dashboard/DashboardProjectCarousell.js index e6e020f..774fd2d 100644 --- a/src/views/Dashboard/DashboardProjectCarousell.js +++ b/src/views/Dashboard/DashboardProjectCarousell.js @@ -70,7 +70,15 @@ const center = { }; const DashboardProject = (args) => { - const token = localStorage.getItem("token"); + let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '', company_id = 0, all_project = '', hierarchy = []; + role_id = localStorage.getItem("role_id"); + proyek_id = localStorage.getItem("proyek_id"); + user_id = localStorage.getItem("user_id"); + token = localStorage.getItem("token"); + isLogin = localStorage.getItem("isLogin"); + company_id = localStorage.getItem('company_id'); + all_project = localStorage.getItem('all_project'); + hierarchy.push(JSON.parse(localStorage.getItem("hierarchy"))); const HEADER = { headers: { "Content-Type": "application/json", @@ -116,7 +124,7 @@ const DashboardProject = (args) => { setIsReadyProjectDetail(false); setIsReadySCurve(false) setIsReadySCurve(false); - const URL = `${BASE_OSPRO}/api/project-carausell`; + const URL = `${BASE_OSPRO}/api/project-carausell/${company_id}/${all_project}/${hierarchy}`; const result = await axios .get(URL, HEADER) .then((res) => res) From 142cf38892d27eecebf5c709b513efc28dd81105 Mon Sep 17 00:00:00 2001 From: farhantock Date: Wed, 13 Dec 2023 20:32:55 +0700 Subject: [PATCH 02/11] removed unused code --- src/views/SimproV2/CreatedProyek/index.js | 39 ++++++----------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/src/views/SimproV2/CreatedProyek/index.js b/src/views/SimproV2/CreatedProyek/index.js index daa277c..30912f9 100644 --- a/src/views/SimproV2/CreatedProyek/index.js +++ b/src/views/SimproV2/CreatedProyek/index.js @@ -142,7 +142,7 @@ const CreatedProyek = ({ params, ...props }) => { const [userProyek, setUserProyek] = useState([]); const [materialProyek, setMaterialProyek] = useState([]); const [dataCharter, setDataCharter] = useState(null); - const [dataViewStartDate, setDataViewStartDate] = useState([]); + const [dataViewStartDate, setDataViewStartDate] = useState(""); const [materialResource, setMaterialResource] = useState([]); const [toolsResource, setToolsResource] = useState([]); const [dataTypeProyek, setDataTypeProyek] = useState([]); @@ -376,7 +376,7 @@ const CreatedProyek = ({ params, ...props }) => { paging: { start: start, length: rowsPerPage }, }; - if (all_project) { + if (all_project !== null && all_project === true) { payload["columns"] = [ { name: "company_id", logic_operator: "like", value: company_id, operator: "AND" } ]; @@ -512,6 +512,7 @@ const CreatedProyek = ({ params, ...props }) => { }; const handleOpenDialogGantt = (data) => { + console.log('data.mulai_proyek', data.mulai_proyek); setDataViewStartDate(data.mulai_proyek) setidTask(data.id); setProyekName(data.nama); @@ -1534,32 +1535,12 @@ const CreatedProyek = ({ params, ...props }) => { Assign Checklist K3 - {/*
handleOpenDialogMaterial(text)} - > - - - - Request Material Resource -
*/} - {/*
handleOpenDialogTools(text)}> - - - - Request Tools -
*/} - {/* */} - { - /*text.type_proyek_id != 9 ?*/ -
handleOpenDialogGantt(text)}> - - - - Gantt -
- /*: null*/ - } +
handleOpenDialogGantt(text)}> + + + + Gantt +
handleSCurve(text)}> @@ -1572,7 +1553,6 @@ const CreatedProyek = ({ params, ...props }) => { Report Analysis
- {/* */}
handleOpenDialogProyek(text.id)} @@ -1995,6 +1975,7 @@ const CreatedProyek = ({ params, ...props }) => { toggleDialog={toggleDialogHierarchy} idTask={idTask} proyekName={proyekName} + dataViewStartDate={dataViewStartDate} /> ), [openDialogHierarchy] From 8e79b5ba9a5eb3db1bd85c78ccfe15844b281b8c Mon Sep 17 00:00:00 2001 From: farhantock Date: Wed, 13 Dec 2023 21:54:09 +0700 Subject: [PATCH 03/11] update url get-invoice-outstanding --- src/views/Dashboard/DashboardBOD.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/Dashboard/DashboardBOD.js b/src/views/Dashboard/DashboardBOD.js index 83b2442..8006da5 100644 --- a/src/views/Dashboard/DashboardBOD.js +++ b/src/views/Dashboard/DashboardBOD.js @@ -104,7 +104,7 @@ const DashboardBOD = (props) => { } const getInvoiceOutstanding = async () => { - const URL = `${BASE_OSPRO}/api/dashboard/get-invoice-outstanding` + const URL = `${BASE_OSPRO}/api/dashboard/get-invoice-outstanding/${moment().format('YYYY')}/${company_id}/${all_project}/${hierarchy}` const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) const content = "Get Project Invoice vs Cash In."; From e4f9b272e27923368a89007328e6728209ae68a2 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Sat, 16 Dec 2023 16:10:20 +0700 Subject: [PATCH 04/11] Styling input search --- .../SimproV2/CreatedProyek/DialogGantt.js | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/views/SimproV2/CreatedProyek/DialogGantt.js b/src/views/SimproV2/CreatedProyek/DialogGantt.js index 738a075..b3dd3a2 100644 --- a/src/views/SimproV2/CreatedProyek/DialogGantt.js +++ b/src/views/SimproV2/CreatedProyek/DialogGantt.js @@ -247,27 +247,28 @@ const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName ) : (
Gantt Project {proyekName}
)} - - - {!hierarchyId && ( - - )} +
+ + {!hierarchyId && ( + + )} +
From a31b1247a2623b5be53aee82fc00be8a8be4120d Mon Sep 17 00:00:00 2001 From: farhantock Date: Mon, 18 Dec 2023 14:45:16 +0700 Subject: [PATCH 05/11] add notif when gantt null --- src/components/BottomModal/BottomModal.js | 203 ++++++++++++---------- 1 file changed, 112 insertions(+), 91 deletions(-) diff --git a/src/components/BottomModal/BottomModal.js b/src/components/BottomModal/BottomModal.js index 69b04c3..27d1bf3 100644 --- a/src/components/BottomModal/BottomModal.js +++ b/src/components/BottomModal/BottomModal.js @@ -6,8 +6,9 @@ import Icon from '@iconify/react' import closeCircleOutline from '@iconify/icons-ion/close-circle-outline'; import removeCircleOutline from '@iconify/icons-ion/remove-circle-outline'; import windowMaximaze from '@iconify/icons-mdi/window-maximize'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; -const BottomModal = ({title, tableHeader, tableData, closeModal, isReady}) => { +const BottomModal = ({ title, tableHeader, tableData, closeModal, isReady }) => { const [tableHeight, setTableHeight] = useState(150) const [resizableWidth, setResizableWidth] = useState("100%") const [resizableHeight, setResizableHeight] = useState(300) @@ -39,25 +40,42 @@ const BottomModal = ({title, tableHeader, tableData, closeModal, isReady}) => { const renderTableRow = (item) => { let row = []; + // looping through its object keys (item is an object) Object.keys(item).map(key => { if (key === 'project_name') { let URL = `/#/dashboard-project/${item['id']}/${item['last_gantt_id']}`; - row.push({item[key]}) - } else if(key === 'last_gantt_id') { - } else if(key === 'id') { - } else { - row.push({item[key]}) + row.push( + + { + e.preventDefault(); + if (!item['last_gantt_id']) { + NotificationManager.warning('Data Gantt Belum Tersedia.', 'Warning'); + } else { + window.location.href = URL; + } + }} + > + {item[key]} + + + ); + } else if (key === 'id' || key === 'last_gantt_id') { + } else { + row.push({item[key]}); } - }) + }); + return row; - } + }; const RenderTable = useMemo(() => { if (tableData && tableData.length > 0) { return ( - + {tableHeader && tableHeader.length > 0 && tableHeader.map((item, idx) => ( @@ -66,8 +84,8 @@ const BottomModal = ({title, tableHeader, tableData, closeModal, isReady}) => { } - - {tableData && tableData.length > 0 && + + {tableData && tableData.length > 0 && tableData.map((item, index) => { return ( {renderTableRow(item, tableHeader)} @@ -85,92 +103,95 @@ const BottomModal = ({title, tableHeader, tableData, closeModal, isReady}) => { // // //
No Data Available
-
+
No Data Available
) }, [tableData, isReady]) return ( - { - setResizableWidth("100%"); - setResizableHeight(resizableHeight + d.height); - if (e.screenY < 100) { // max - setResizableHeight('100vh'); - setTableHeight(450) - } - else if (e.screenY < 150) { - setTableHeight(400) - } - else if (e.screenY < 200) { - setTableHeight(350) - } - else if (e.screenY < 250) { - setTableHeight(300) - } - else if (e.screenY < 300) { - setTableHeight(250) - } - else if (e.screenY < 400) { - setTableHeight(200) - } - else if (e.screenY < 600) { - setTableHeight(150) // default - } - else if (e.screenY >= 600) { - setBottomTableWindow('min'); - } - }} - > -
- - -

{title}

- - - setBottomTableWindow("min")} - > - - - setBottomTableWindow("max")} - > - - - - - - -
- - - {isReady ? RenderTable :
Loading data...
} -
-
-
-
+ <> + + { + setResizableWidth("100%"); + setResizableHeight(resizableHeight + d.height); + if (e.screenY < 100) { // max + setResizableHeight('100vh'); + setTableHeight(450) + } + else if (e.screenY < 150) { + setTableHeight(400) + } + else if (e.screenY < 200) { + setTableHeight(350) + } + else if (e.screenY < 250) { + setTableHeight(300) + } + else if (e.screenY < 300) { + setTableHeight(250) + } + else if (e.screenY < 400) { + setTableHeight(200) + } + else if (e.screenY < 600) { + setTableHeight(150) // default + } + else if (e.screenY >= 600) { + setBottomTableWindow('min'); + } + }} + > +
+ + +

{title}

+ + + setBottomTableWindow("min")} + > + + + setBottomTableWindow("max")} + > + + + + + + +
+ + + {isReady ? RenderTable :
Loading data...
} +
+
+
+
+ ) } From 381b414fef664c19db272cde570df14afca9b412 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:49:05 +0700 Subject: [PATCH 06/11] color chart --- .../Master/ProjectExpenditure/DialogForm.js | 113 +++++ .../ProjectExpenditure/DialogFormInitial.js | 89 ++++ .../Master/ProjectExpenditure/InputColor.js | 46 ++ src/views/Master/ProjectExpenditure/index.js | 392 ++++++++++++++++++ .../Master/ProjectExpenditure/styles.css | 41 ++ 5 files changed, 681 insertions(+) create mode 100644 src/views/Master/ProjectExpenditure/DialogForm.js create mode 100644 src/views/Master/ProjectExpenditure/DialogFormInitial.js create mode 100644 src/views/Master/ProjectExpenditure/InputColor.js create mode 100644 src/views/Master/ProjectExpenditure/index.js create mode 100644 src/views/Master/ProjectExpenditure/styles.css diff --git a/src/views/Master/ProjectExpenditure/DialogForm.js b/src/views/Master/ProjectExpenditure/DialogForm.js new file mode 100644 index 0000000..1bf2886 --- /dev/null +++ b/src/views/Master/ProjectExpenditure/DialogForm.js @@ -0,0 +1,113 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; +import 'antd/dist/antd.css'; +import { Select } from "antd"; +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; +import { useTranslation } from 'react-i18next'; +const company_id = localStorage.getItem("company_id") +const { Option } = Select; +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { + const [id, setId] = useState(0) + const [projectExpenditure, setProjectExpenditure] = useState('') + const [color, setColor] = useState('') + const { t } = useTranslation(); + useEffect(() => { + if (typeDialog === "Edit") { + setId(dataEdit.id) + setProjectExpenditure(dataEdit.name) + setColor(dataEdit.color) + } else { + setId(0) + setColor('') + setProjectExpenditure('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + if (typeDialog === "Save") { + data = { + name: projectExpenditure, + color, + company_id + } + closeDialog('save', data); + } else { + data = { + id, + name: projectExpenditure, + color, + company_id + } + closeDialog('edit', data); + } + setId(0) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + } + + const renderForm = () => { + return ( +
+ + + + + + + + + + + setColor(e.color)} /> + + + +
+ ) + } + + return ( + <> + + {typeDialog == "Save" ? `Add` : "Edit"} data + + {renderForm()} + + + {' '} + + + + + ) +} + +export default DialogForm; diff --git a/src/views/Master/ProjectExpenditure/DialogFormInitial.js b/src/views/Master/ProjectExpenditure/DialogFormInitial.js new file mode 100644 index 0000000..200ba87 --- /dev/null +++ b/src/views/Master/ProjectExpenditure/DialogFormInitial.js @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; + +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, idActivity, projectTypeId }) => { + + const [id, setId] = useState(0) + const [activity, setActivity] = useState('') + + useEffect(() => { + if (typeDialog === "edit") { + setId(dataEdit.id) + setActivity(dataEdit.name_activity) + + } else { + setId(0) + setActivity('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + + if (typeDialog === "add") { + data = { + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('save', data); + } else { + data = { + id, + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('edit', data); + } + setId(0) + setActivity('') + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + setActivity('') + } + + const renderForm = () => { + return ( +
+ + + setActivity(e.target.value)} placeholder={`Persiapan ...`} /> + +
+ ) + } + + + return ( + <> + + {typeDialog == "add" ? `Add` : "Edit"} Activity + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default DialogForm; \ No newline at end of file diff --git a/src/views/Master/ProjectExpenditure/InputColor.js b/src/views/Master/ProjectExpenditure/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/Master/ProjectExpenditure/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/Master/ProjectExpenditure/index.js b/src/views/Master/ProjectExpenditure/index.js new file mode 100644 index 0000000..4dde162 --- /dev/null +++ b/src/views/Master/ProjectExpenditure/index.js @@ -0,0 +1,392 @@ +import * as XLSX from 'xlsx'; +import DialogForm from './DialogForm'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from "../../../const/interceptorApi" +import moment from 'moment' +import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { PROJECT_EXPENDITURE_ADD, PROJECT_EXPENDITURE_EDIT, PROJECT_EXPENDITURE_DELETE, PROJECT_EXPENDITURE_SEARCH } from '../../../const/ApiConst'; +import { Pagination, Button, Tooltip, Table } from 'antd'; +import { useTranslation } from 'react-i18next'; + + +const ProjectExpenditure = ({ params, ...props }) => { + let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '', company_id = 0, role_name = ''; + if (props.location.state && props.location.state.role_id && props.location.state.user_id) { + role_id = props.location.state.role_id; + user_id = props.location.state.user_id; + token = props.location.state.token; + isLogin = props.location.state.isLogin; + role_name = props.location.state.role_name; + } else { + role_id = localStorage.getItem("role_id"); + proyek_id = localStorage.getItem("proyek_id"); + user_id = localStorage.getItem("user_id"); + token = localStorage.getItem("token"); + isLogin = localStorage.getItem("isLogin"); + company_id = localStorage.getItem('company_id'); + role_name = localStorage.getItem('role_name'); + } + + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + const pageName = params.name; + + const [alertDelete, setAlertDelete] = useState(false) + const [clickOpenModal, setClickOpenModal] = useState(false) + const [currentPage, setCurrentPage] = useState(1) + const [dataEdit, setDataEdit] = useState([]) + const [dataExport, setDataExport] = useState([]) + const [dataTable, setDatatable] = useState([]) + const [idDelete, setIdDelete] = useState(0) + const [idPhaseProject, setIdPhaseProject] = useState(0) + const [openDialog, setOpenDialog] = useState(false) + const [openDialogIG, setOpenDialogIG] = useState(false) + const [rowsPerPage, setRowsPerPage] = useState(10) + const [search, setSearch] = useState('') + const [totalPage, setTotalPage] = useState(0) + const [typeDialog, setTypeDialog] = useState('Save') + const { t } = useTranslation() + useEffect(() => { + getDataProjectExpenditure() + }, [currentPage, rowsPerPage, search]) + + useEffect(() => { + const cekData = dataExport || [] + if (cekData.length > 0) { + exportExcel() + } + }, [dataExport]) + + const getDataProjectExpenditure = async () => { + let start = 0; + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "ilike", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + if (role_name !== "Super Admin") { + payload.columns.push( + { "name": "company_id", "logic_operator": "=", "value": company_id, "operator": "AND" }, + ) + } else { + payload.columns.push( + { "name": "company_id", "logic_operator": "is null", "value": "", "operator": "AND" }, + ) + } + const result = await axios + .post(PROJECT_EXPENDITURE_SEARCH, payload, HEADER) + .then((res) => res) + .catch((err) => err.response); + + if (result && result.data && result.data.code == 200) { + result.data.data.map((res) => { + res.key = res.id.toString() + }); + setDatatable(result.data.data); + setTotalPage(result.data.totalRecord); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const handleSearch = e => { + const value = e.target.value + setSearch(value); + setCurrentPage(1) + }; + const handleOpenDialog = (type) => { + setOpenDialog(true) + setTypeDialog(type) + } + + const handleExportExcel = async () => { + let start = 0; + + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "like", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + + const result = await axios + .post(PROJECT_EXPENDITURE_SEARCH, payload, HEADER) + .then(res => res) + .catch((error) => error.response); + if (result && result.data && result.data.code == 200) { + let resData = result.data.data; + const excelData = []; + resData.map((val, index) => { + let dataRow = { + "Nama": val.name, + "Color": val.color, + } + excelData.push(dataRow) + }) + await setDataExport(excelData) + } else { + NotificationManager.error('Gagal Export Data!!', 'Failed'); + } + } + + const exportExcel = () => { + const dataExcel = dataExport || []; + const fileName = `Data ${pageName}.xlsx`; + const ws = XLSX.utils.json_to_sheet(dataExcel); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); + XLSX.writeFile(wb, fileName); + setDataExport([]) + } + + const handleEdit = (data) => { + setDataEdit(data) + handleOpenDialog('Edit'); + } + + const handleDelete = async (id) => { + await setAlertDelete(true) + await setIdDelete(id) + } + + const handleCloseDialog = (type, data) => { + if (type === "save") { + saveProjectExpenditure(data); + } else if (type === "edit") { + editMaterialR(data); + } + setDataEdit([]) + setOpenDialog(false) + } + + const saveProjectExpenditure = async (data) => { + const result = await axios.post(PROJECT_EXPENDITURE_ADD, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectExpenditure() + NotificationManager.success(`Data project expenditure berhasil ditambah`, 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } + + const editMaterialR = async (data) => { + let urlEdit = PROJECT_EXPENDITURE_EDIT(data.id) + const result = await axios.put(urlEdit, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectExpenditure(); + NotificationManager.success(`Data project expenditure berhasil diedit`, 'Success!!'); + } else { + NotificationManager.error(`Data project expenditure gagal di edit`, `Failed!!`); + } + } + + const toggleAddDialog = () => { + setOpenDialog(!openDialog) + } + + const handleDialogIg = (id) => { + setIdPhaseProject(id) + setOpenDialogIG(true) + } + + const closeDialogIG = () => { + setIdPhaseProject(0) + setOpenDialogIG(false) + } + + const toggleDialogIG = () => { + if (openDialogIG) { + setIdPhaseProject(0) + } + setOpenDialogIG(!openDialogIG); + } + + const onConfirmDelete = async () => { + let url = PROJECT_EXPENDITURE_DELETE(idDelete); + + const result = await axios.delete(url, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectExpenditure() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data project expenditure berhasil dihapus!`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data project expenditure gagal dihapus!}`, 'Failed!!'); + } + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const onShowSizeChange = (current, pageSize) => { + setRowsPerPage(pageSize) + } + + const onPagination = (current, pageSize) => { + setCurrentPage(current) + } + + const dataNotAvailable = () => { + if (dataTable.length === 0) { + return ( + + {t('noData')} + + ) + } + } + + const renderTable = useMemo(() => { + const columns = [ + { + title: t('action'), + dataIndex: '', + key: 'x', + className: 'nowrap', + render: (text, record) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + {" "} + , + }, + { title: t('Project Expenditure'), dataIndex: 'name', key: 'name', className: "nowrap" }, + { + title: t('color'), + dataIndex: 'color', + key: 'color', + render: (text) => <> + + + + , + }, + ]; + return ( + + ) + }, [dataTable]) + + return ( +
+ + + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + /> + + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + + + ) +} + +export default ProjectExpenditure; diff --git a/src/views/Master/ProjectExpenditure/styles.css b/src/views/Master/ProjectExpenditure/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/Master/ProjectExpenditure/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; +} + From 91101852f4b2dc83aeb75618f5caff9a70d77b74 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:49:17 +0700 Subject: [PATCH 07/11] color chart --- .../ProjectFinancialHealth/DialogForm.js | 110 +++++ .../DialogFormInitial.js | 89 ++++ .../ProjectFinancialHealth/InputColor.js | 46 ++ .../Master/ProjectFinancialHealth/index.js | 392 ++++++++++++++++++ .../Master/ProjectFinancialHealth/styles.css | 41 ++ 5 files changed, 678 insertions(+) create mode 100644 src/views/Master/ProjectFinancialHealth/DialogForm.js create mode 100644 src/views/Master/ProjectFinancialHealth/DialogFormInitial.js create mode 100644 src/views/Master/ProjectFinancialHealth/InputColor.js create mode 100644 src/views/Master/ProjectFinancialHealth/index.js create mode 100644 src/views/Master/ProjectFinancialHealth/styles.css diff --git a/src/views/Master/ProjectFinancialHealth/DialogForm.js b/src/views/Master/ProjectFinancialHealth/DialogForm.js new file mode 100644 index 0000000..aed6397 --- /dev/null +++ b/src/views/Master/ProjectFinancialHealth/DialogForm.js @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; +import 'antd/dist/antd.css'; +import { Select } from "antd"; +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; +import { useTranslation } from 'react-i18next'; +const company_id = localStorage.getItem("company_id") +const { Option } = Select; +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { + const [id, setId] = useState(0) + const [projectFinancialHealth, setProjectFinancialHealth] = useState('') + const [color, setColor] = useState('') + const { t } = useTranslation(); + useEffect(() => { + if (typeDialog === "Edit") { + setId(dataEdit.id) + setProjectFinancialHealth(dataEdit.name) + setColor(dataEdit.color) + } else { + setId(0) + setColor('') + setProjectFinancialHealth('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + if (typeDialog === "Save") { + data = { + name: projectFinancialHealth, + color, + company_id + } + closeDialog('save', data); + } else { + data = { + id, + name: projectFinancialHealth, + color, + company_id + } + closeDialog('edit', data); + } + setId(0) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + } + + const renderForm = () => { + return ( +
+ +
+ + + + + + + + + setColor(e.color)} /> + + + + + ) + } + + return ( + <> + + {typeDialog == "Save" ? `Add` : "Edit"} data + + {renderForm()} + + + {' '} + + + + + ) +} + +export default DialogForm; diff --git a/src/views/Master/ProjectFinancialHealth/DialogFormInitial.js b/src/views/Master/ProjectFinancialHealth/DialogFormInitial.js new file mode 100644 index 0000000..200ba87 --- /dev/null +++ b/src/views/Master/ProjectFinancialHealth/DialogFormInitial.js @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; + +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, idActivity, projectTypeId }) => { + + const [id, setId] = useState(0) + const [activity, setActivity] = useState('') + + useEffect(() => { + if (typeDialog === "edit") { + setId(dataEdit.id) + setActivity(dataEdit.name_activity) + + } else { + setId(0) + setActivity('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + + if (typeDialog === "add") { + data = { + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('save', data); + } else { + data = { + id, + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('edit', data); + } + setId(0) + setActivity('') + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + setActivity('') + } + + const renderForm = () => { + return ( + + + + setActivity(e.target.value)} placeholder={`Persiapan ...`} /> + + + ) + } + + + return ( + <> + + {typeDialog == "add" ? `Add` : "Edit"} Activity + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default DialogForm; \ No newline at end of file diff --git a/src/views/Master/ProjectFinancialHealth/InputColor.js b/src/views/Master/ProjectFinancialHealth/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/Master/ProjectFinancialHealth/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/Master/ProjectFinancialHealth/index.js b/src/views/Master/ProjectFinancialHealth/index.js new file mode 100644 index 0000000..bc6b0a3 --- /dev/null +++ b/src/views/Master/ProjectFinancialHealth/index.js @@ -0,0 +1,392 @@ +import * as XLSX from 'xlsx'; +import DialogForm from './DialogForm'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from "../../../const/interceptorApi" +import moment from 'moment' +import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { PROJECT_FINANCIAL_HEALTH_ADD, PROJECT_FINANCIAL_HEALTH_EDIT, PROJECT_FINANCIAL_HEALTH_DELETE, PROJECT_FINANCIAL_HEALTH_SEARCH } from '../../../const/ApiConst'; +import { Pagination, Button, Tooltip, Table } from 'antd'; +import { useTranslation } from 'react-i18next'; + + +const ProjectFinancialHealth = ({ params, ...props }) => { + let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '', company_id = 0, role_name = ''; + if (props.location.state && props.location.state.role_id && props.location.state.user_id) { + role_id = props.location.state.role_id; + user_id = props.location.state.user_id; + token = props.location.state.token; + isLogin = props.location.state.isLogin; + role_name = props.location.state.role_name; + } else { + role_id = localStorage.getItem("role_id"); + proyek_id = localStorage.getItem("proyek_id"); + user_id = localStorage.getItem("user_id"); + token = localStorage.getItem("token"); + isLogin = localStorage.getItem("isLogin"); + company_id = localStorage.getItem('company_id'); + role_name = localStorage.getItem('role_name'); + } + + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + const pageName = params.name; + + const [alertDelete, setAlertDelete] = useState(false) + const [clickOpenModal, setClickOpenModal] = useState(false) + const [currentPage, setCurrentPage] = useState(1) + const [dataEdit, setDataEdit] = useState([]) + const [dataExport, setDataExport] = useState([]) + const [dataTable, setDatatable] = useState([]) + const [idDelete, setIdDelete] = useState(0) + const [idPhaseProject, setIdPhaseProject] = useState(0) + const [openDialog, setOpenDialog] = useState(false) + const [openDialogIG, setOpenDialogIG] = useState(false) + const [rowsPerPage, setRowsPerPage] = useState(10) + const [search, setSearch] = useState('') + const [totalPage, setTotalPage] = useState(0) + const [typeDialog, setTypeDialog] = useState('Save') + const { t } = useTranslation() + useEffect(() => { + getDataProjectFinancialHealth() + }, [currentPage, rowsPerPage, search]) + + useEffect(() => { + const cekData = dataExport || [] + if (cekData.length > 0) { + exportExcel() + } + }, [dataExport]) + + const getDataProjectFinancialHealth = async () => { + let start = 0; + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "ilike", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + if (role_name !== "Super Admin") { + payload.columns.push( + { "name": "company_id", "logic_operator": "=", "value": company_id, "operator": "AND" }, + ) + } else { + payload.columns.push( + { "name": "company_id", "logic_operator": "is null", "value": "", "operator": "AND" }, + ) + } + const result = await axios + .post(PROJECT_FINANCIAL_HEALTH_SEARCH, payload, HEADER) + .then((res) => res) + .catch((err) => err.response); + + if (result && result.data && result.data.code == 200) { + result.data.data.map((res) => { + res.key = res.id.toString() + }); + setDatatable(result.data.data); + setTotalPage(result.data.totalRecord); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const handleSearch = e => { + const value = e.target.value + setSearch(value); + setCurrentPage(1) + }; + const handleOpenDialog = (type) => { + setOpenDialog(true) + setTypeDialog(type) + } + + const handleExportExcel = async () => { + let start = 0; + + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "like", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + + const result = await axios + .post(PROJECT_FINANCIAL_HEALTH_SEARCH, payload, HEADER) + .then(res => res) + .catch((error) => error.response); + if (result && result.data && result.data.code == 200) { + let resData = result.data.data; + const excelData = []; + resData.map((val, index) => { + let dataRow = { + "Nama": val.name, + "Color": val.color, + } + excelData.push(dataRow) + }) + await setDataExport(excelData) + } else { + NotificationManager.error('Gagal Export Data!!', 'Failed'); + } + } + + const exportExcel = () => { + const dataExcel = dataExport || []; + const fileName = `Data ${pageName}.xlsx`; + const ws = XLSX.utils.json_to_sheet(dataExcel); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); + XLSX.writeFile(wb, fileName); + setDataExport([]) + } + + const handleEdit = (data) => { + setDataEdit(data) + handleOpenDialog('Edit'); + } + + const handleDelete = async (id) => { + await setAlertDelete(true) + await setIdDelete(id) + } + + const handleCloseDialog = (type, data) => { + if (type === "save") { + saveProjectFinancialHealth(data); + } else if (type === "edit") { + editMaterialR(data); + } + setDataEdit([]) + setOpenDialog(false) + } + + const saveProjectFinancialHealth = async (data) => { + const result = await axios.post(PROJECT_FINANCIAL_HEALTH_ADD, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectFinancialHealth() + NotificationManager.success(`Data project financial health berhasil ditambah`, 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } + + const editMaterialR = async (data) => { + let urlEdit = PROJECT_FINANCIAL_HEALTH_EDIT(data.id) + const result = await axios.put(urlEdit, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectFinancialHealth(); + NotificationManager.success(`Data project financial health berhasil diedit`, 'Success!!'); + } else { + NotificationManager.error(`Data project financial health gagal di edit`, `Failed!!`); + } + } + + const toggleAddDialog = () => { + setOpenDialog(!openDialog) + } + + const handleDialogIg = (id) => { + setIdPhaseProject(id) + setOpenDialogIG(true) + } + + const closeDialogIG = () => { + setIdPhaseProject(0) + setOpenDialogIG(false) + } + + const toggleDialogIG = () => { + if (openDialogIG) { + setIdPhaseProject(0) + } + setOpenDialogIG(!openDialogIG); + } + + const onConfirmDelete = async () => { + let url = PROJECT_FINANCIAL_HEALTH_DELETE(idDelete); + + const result = await axios.delete(url, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectFinancialHealth() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data project financial health berhasil dihapus!`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data project financial health gagal dihapus!}`, 'Failed!!'); + } + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const onShowSizeChange = (current, pageSize) => { + setRowsPerPage(pageSize) + } + + const onPagination = (current, pageSize) => { + setCurrentPage(current) + } + + const dataNotAvailable = () => { + if (dataTable.length === 0) { + return ( + + + + ) + } + } + + const renderTable = useMemo(() => { + const columns = [ + { + title: t('action'), + dataIndex: '', + key: 'x', + className: 'nowrap', + render: (text, record) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + {" "} + , + }, + { title: t('Project Financial Health'), dataIndex: 'name', key: 'name', className: "nowrap" }, + { + title: t('color'), + dataIndex: 'color', + key: 'color', + render: (text) => <> + + + + , + }, + ]; + return ( +
{t('noData')}
+ ) + }, [dataTable]) + + return ( +
+ + + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + /> + + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + + + ) +} + +export default ProjectFinancialHealth; diff --git a/src/views/Master/ProjectFinancialHealth/styles.css b/src/views/Master/ProjectFinancialHealth/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/Master/ProjectFinancialHealth/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; +} + From 5e466f37cba6746c86c0e02c4d425f02cce984e5 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:49:27 +0700 Subject: [PATCH 08/11] color chart --- src/views/Master/ProjectInvoice/DialogForm.js | 107 +++++ .../ProjectInvoice/DialogFormInitial.js | 89 ++++ src/views/Master/ProjectInvoice/InputColor.js | 46 ++ src/views/Master/ProjectInvoice/index.js | 392 ++++++++++++++++++ src/views/Master/ProjectInvoice/styles.css | 41 ++ 5 files changed, 675 insertions(+) create mode 100644 src/views/Master/ProjectInvoice/DialogForm.js create mode 100644 src/views/Master/ProjectInvoice/DialogFormInitial.js create mode 100644 src/views/Master/ProjectInvoice/InputColor.js create mode 100644 src/views/Master/ProjectInvoice/index.js create mode 100644 src/views/Master/ProjectInvoice/styles.css diff --git a/src/views/Master/ProjectInvoice/DialogForm.js b/src/views/Master/ProjectInvoice/DialogForm.js new file mode 100644 index 0000000..2a42dc1 --- /dev/null +++ b/src/views/Master/ProjectInvoice/DialogForm.js @@ -0,0 +1,107 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; +import 'antd/dist/antd.css'; +import { Select } from "antd"; +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; +import { useTranslation } from 'react-i18next'; +const company_id = localStorage.getItem("company_id") +const { Option } = Select; +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { + const [id, setId] = useState(0) + const [projectInvoice, setProjectInvoice] = useState('') + const [color, setColor] = useState('') + const { t } = useTranslation(); + useEffect(() => { + if (typeDialog === "Edit") { + setId(dataEdit.id) + setProjectInvoice(dataEdit.name) + setColor(dataEdit.color) + } else { + setId(0) + setColor('') + setProjectInvoice('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + if (typeDialog === "Save") { + data = { + name: projectInvoice, + color, + company_id + } + closeDialog('save', data); + } else { + data = { + id, + name: projectInvoice, + color, + company_id + } + closeDialog('edit', data); + } + setId(0) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + } + + const renderForm = () => { + return ( +
+ +
+ + + + + + + + + setColor(e.color)} /> + + + + + ) + } + + return ( + <> + + {typeDialog == "Save" ? `Add` : "Edit"} data + + {renderForm()} + + + {' '} + + + + + ) +} + +export default DialogForm; diff --git a/src/views/Master/ProjectInvoice/DialogFormInitial.js b/src/views/Master/ProjectInvoice/DialogFormInitial.js new file mode 100644 index 0000000..200ba87 --- /dev/null +++ b/src/views/Master/ProjectInvoice/DialogFormInitial.js @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; + +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, idActivity, projectTypeId }) => { + + const [id, setId] = useState(0) + const [activity, setActivity] = useState('') + + useEffect(() => { + if (typeDialog === "edit") { + setId(dataEdit.id) + setActivity(dataEdit.name_activity) + + } else { + setId(0) + setActivity('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + + if (typeDialog === "add") { + data = { + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('save', data); + } else { + data = { + id, + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('edit', data); + } + setId(0) + setActivity('') + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + setActivity('') + } + + const renderForm = () => { + return ( + + + + setActivity(e.target.value)} placeholder={`Persiapan ...`} /> + + + ) + } + + + return ( + <> + + {typeDialog == "add" ? `Add` : "Edit"} Activity + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default DialogForm; \ No newline at end of file diff --git a/src/views/Master/ProjectInvoice/InputColor.js b/src/views/Master/ProjectInvoice/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/Master/ProjectInvoice/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/Master/ProjectInvoice/index.js b/src/views/Master/ProjectInvoice/index.js new file mode 100644 index 0000000..da213a1 --- /dev/null +++ b/src/views/Master/ProjectInvoice/index.js @@ -0,0 +1,392 @@ +import * as XLSX from 'xlsx'; +import DialogForm from './DialogForm'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from "../../../const/interceptorApi" +import moment from 'moment' +import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { PROJECT_INVOICE_ADD, PROJECT_INVOICE_EDIT, PROJECT_INVOICE_DELETE, PROJECT_INVOICE_SEARCH } from '../../../const/ApiConst'; +import { Pagination, Button, Tooltip, Table } from 'antd'; +import { useTranslation } from 'react-i18next'; + + +const ProjectInvoice = ({ params, ...props }) => { + let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '', company_id = 0, role_name = ''; + if (props.location.state && props.location.state.role_id && props.location.state.user_id) { + role_id = props.location.state.role_id; + user_id = props.location.state.user_id; + token = props.location.state.token; + isLogin = props.location.state.isLogin; + role_name = props.location.state.role_name; + } else { + role_id = localStorage.getItem("role_id"); + proyek_id = localStorage.getItem("proyek_id"); + user_id = localStorage.getItem("user_id"); + token = localStorage.getItem("token"); + isLogin = localStorage.getItem("isLogin"); + company_id = localStorage.getItem('company_id'); + role_name = localStorage.getItem('role_name'); + } + + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + const pageName = params.name; + + const [alertDelete, setAlertDelete] = useState(false) + const [clickOpenModal, setClickOpenModal] = useState(false) + const [currentPage, setCurrentPage] = useState(1) + const [dataEdit, setDataEdit] = useState([]) + const [dataExport, setDataExport] = useState([]) + const [dataTable, setDatatable] = useState([]) + const [idDelete, setIdDelete] = useState(0) + const [idPhaseProject, setIdPhaseProject] = useState(0) + const [openDialog, setOpenDialog] = useState(false) + const [openDialogIG, setOpenDialogIG] = useState(false) + const [rowsPerPage, setRowsPerPage] = useState(10) + const [search, setSearch] = useState('') + const [totalPage, setTotalPage] = useState(0) + const [typeDialog, setTypeDialog] = useState('Save') + const { t } = useTranslation() + useEffect(() => { + getDataProjectInvoice() + }, [currentPage, rowsPerPage, search]) + + useEffect(() => { + const cekData = dataExport || [] + if (cekData.length > 0) { + exportExcel() + } + }, [dataExport]) + + const getDataProjectInvoice = async () => { + let start = 0; + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "ilike", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + if (role_name !== "Super Admin") { + payload.columns.push( + { "name": "company_id", "logic_operator": "=", "value": company_id, "operator": "AND" }, + ) + } else { + payload.columns.push( + { "name": "company_id", "logic_operator": "is null", "value": "", "operator": "AND" }, + ) + } + const result = await axios + .post(PROJECT_INVOICE_SEARCH, payload, HEADER) + .then((res) => res) + .catch((err) => err.response); + + if (result && result.data && result.data.code == 200) { + result.data.data.map((res) => { + res.key = res.id.toString() + }); + setDatatable(result.data.data); + setTotalPage(result.data.totalRecord); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const handleSearch = e => { + const value = e.target.value + setSearch(value); + setCurrentPage(1) + }; + const handleOpenDialog = (type) => { + setOpenDialog(true) + setTypeDialog(type) + } + + const handleExportExcel = async () => { + let start = 0; + + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "like", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + + const result = await axios + .post(PROJECT_INVOICE_SEARCH, payload, HEADER) + .then(res => res) + .catch((error) => error.response); + if (result && result.data && result.data.code == 200) { + let resData = result.data.data; + const excelData = []; + resData.map((val, index) => { + let dataRow = { + "Nama": val.name, + "Color": val.color, + } + excelData.push(dataRow) + }) + await setDataExport(excelData) + } else { + NotificationManager.error('Gagal Export Data!!', 'Failed'); + } + } + + const exportExcel = () => { + const dataExcel = dataExport || []; + const fileName = `Data ${pageName}.xlsx`; + const ws = XLSX.utils.json_to_sheet(dataExcel); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); + XLSX.writeFile(wb, fileName); + setDataExport([]) + } + + const handleEdit = (data) => { + setDataEdit(data) + handleOpenDialog('Edit'); + } + + const handleDelete = async (id) => { + await setAlertDelete(true) + await setIdDelete(id) + } + + const handleCloseDialog = (type, data) => { + if (type === "save") { + saveProjectInvoice(data); + } else if (type === "edit") { + editMaterialR(data); + } + setDataEdit([]) + setOpenDialog(false) + } + + const saveProjectInvoice = async (data) => { + const result = await axios.post(PROJECT_INVOICE_ADD, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectInvoice() + NotificationManager.success(`Data project invoice berhasil ditambah`, 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } + + const editMaterialR = async (data) => { + let urlEdit = PROJECT_INVOICE_EDIT(data.id) + const result = await axios.put(urlEdit, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectInvoice(); + NotificationManager.success(`Data project invoice berhasil diedit`, 'Success!!'); + } else { + NotificationManager.error(`Data project invoice gagal di edit`, `Failed!!`); + } + } + + const toggleAddDialog = () => { + setOpenDialog(!openDialog) + } + + const handleDialogIg = (id) => { + setIdPhaseProject(id) + setOpenDialogIG(true) + } + + const closeDialogIG = () => { + setIdPhaseProject(0) + setOpenDialogIG(false) + } + + const toggleDialogIG = () => { + if (openDialogIG) { + setIdPhaseProject(0) + } + setOpenDialogIG(!openDialogIG); + } + + const onConfirmDelete = async () => { + let url = PROJECT_INVOICE_DELETE(idDelete); + + const result = await axios.delete(url, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectInvoice() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data project invoice berhasil dihapus!`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data project invoice gagal dihapus!}`, 'Failed!!'); + } + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const onShowSizeChange = (current, pageSize) => { + setRowsPerPage(pageSize) + } + + const onPagination = (current, pageSize) => { + setCurrentPage(current) + } + + const dataNotAvailable = () => { + if (dataTable.length === 0) { + return ( + + + + ) + } + } + + const renderTable = useMemo(() => { + const columns = [ + { + title: t('action'), + dataIndex: '', + key: 'x', + className: 'nowrap', + render: (text, record) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + {" "} + , + }, + { title: t('Project Invoice'), dataIndex: 'name', key: 'name', className: "nowrap" }, + { + title: t('color'), + dataIndex: 'color', + key: 'color', + render: (text) => <> + + + + , + }, + ]; + return ( +
{t('noData')}
+ ) + }, [dataTable]) + + return ( +
+ + + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + /> + + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + + + ) +} + +export default ProjectInvoice; diff --git a/src/views/Master/ProjectInvoice/styles.css b/src/views/Master/ProjectInvoice/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/Master/ProjectInvoice/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; +} + From 121d09b1cbb3daac60891876811ff4034c29e412 Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:49:44 +0700 Subject: [PATCH 09/11] color chart --- .../ProjectScheduleHealth/DialogForm.js | 110 +++++ .../DialogFormInitial.js | 89 ++++ .../ProjectScheduleHealth/InputColor.js | 46 ++ .../Master/ProjectScheduleHealth/index.js | 392 ++++++++++++++++++ .../Master/ProjectScheduleHealth/styles.css | 41 ++ 5 files changed, 678 insertions(+) create mode 100644 src/views/Master/ProjectScheduleHealth/DialogForm.js create mode 100644 src/views/Master/ProjectScheduleHealth/DialogFormInitial.js create mode 100644 src/views/Master/ProjectScheduleHealth/InputColor.js create mode 100644 src/views/Master/ProjectScheduleHealth/index.js create mode 100644 src/views/Master/ProjectScheduleHealth/styles.css diff --git a/src/views/Master/ProjectScheduleHealth/DialogForm.js b/src/views/Master/ProjectScheduleHealth/DialogForm.js new file mode 100644 index 0000000..7b77ead --- /dev/null +++ b/src/views/Master/ProjectScheduleHealth/DialogForm.js @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; +import 'antd/dist/antd.css'; +import { Select } from "antd"; +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; +import { useTranslation } from 'react-i18next'; +const company_id = localStorage.getItem("company_id") +const { Option } = Select; +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { + const [id, setId] = useState(0) + const [projectScheduleHealth, setProjectScheduleHealth] = useState('') + const [color, setColor] = useState('') + const { t } = useTranslation(); + useEffect(() => { + if (typeDialog === "Edit") { + setId(dataEdit.id) + setProjectScheduleHealth(dataEdit.name) + setColor(dataEdit.color) + } else { + setId(0) + setColor('') + setProjectScheduleHealth('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + if (typeDialog === "Save") { + data = { + name: projectScheduleHealth, + color, + company_id + } + closeDialog('save', data); + } else { + data = { + id, + name: projectScheduleHealth, + color, + company_id + } + closeDialog('edit', data); + } + setId(0) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + } + + const renderForm = () => { + return ( +
+ +
+ + + + + + + + + setColor(e.color)} /> + + + + + ) + } + + return ( + <> + + {typeDialog == "Save" ? `Add` : "Edit"} data + + {renderForm()} + + + {' '} + + + + + ) +} + +export default DialogForm; diff --git a/src/views/Master/ProjectScheduleHealth/DialogFormInitial.js b/src/views/Master/ProjectScheduleHealth/DialogFormInitial.js new file mode 100644 index 0000000..200ba87 --- /dev/null +++ b/src/views/Master/ProjectScheduleHealth/DialogFormInitial.js @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from 'react' +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row +} from 'reactstrap'; + +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, idActivity, projectTypeId }) => { + + const [id, setId] = useState(0) + const [activity, setActivity] = useState('') + + useEffect(() => { + if (typeDialog === "edit") { + setId(dataEdit.id) + setActivity(dataEdit.name_activity) + + } else { + setId(0) + setActivity('') + } + }, [dataEdit, openDialog]) + + const handleSave = () => { + let data = ''; + + if (typeDialog === "add") { + data = { + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('save', data); + } else { + data = { + id, + name_activity: activity, + proyek_type_id: projectTypeId + } + + if (idActivity && idActivity > 0) { + data['parent_id'] = idActivity + } + + closeDialog('edit', data); + } + setId(0) + setActivity('') + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + setId(0) + setActivity('') + } + + const renderForm = () => { + return ( + + + + setActivity(e.target.value)} placeholder={`Persiapan ...`} /> + + + ) + } + + + return ( + <> + + {typeDialog == "add" ? `Add` : "Edit"} Activity + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default DialogForm; \ No newline at end of file diff --git a/src/views/Master/ProjectScheduleHealth/InputColor.js b/src/views/Master/ProjectScheduleHealth/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/Master/ProjectScheduleHealth/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/Master/ProjectScheduleHealth/index.js b/src/views/Master/ProjectScheduleHealth/index.js new file mode 100644 index 0000000..ed90090 --- /dev/null +++ b/src/views/Master/ProjectScheduleHealth/index.js @@ -0,0 +1,392 @@ +import * as XLSX from 'xlsx'; +import DialogForm from './DialogForm'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from "../../../const/interceptorApi" +import moment from 'moment' +import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { PROJECT_SCHEDULE_HEALTH_ADD, PROJECT_SCHEDULE_HEALTH_EDIT, PROJECT_SCHEDULE_HEALTH_DELETE, PROJECT_SCHEDULE_HEALTH_SEARCH } from '../../../const/ApiConst'; +import { Pagination, Button, Tooltip, Table } from 'antd'; +import { useTranslation } from 'react-i18next'; + + +const ProjectScheduleHealth = ({ params, ...props }) => { + let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = '', company_id = 0, role_name = ''; + if (props.location.state && props.location.state.role_id && props.location.state.user_id) { + role_id = props.location.state.role_id; + user_id = props.location.state.user_id; + token = props.location.state.token; + isLogin = props.location.state.isLogin; + role_name = props.location.state.role_name; + } else { + role_id = localStorage.getItem("role_id"); + proyek_id = localStorage.getItem("proyek_id"); + user_id = localStorage.getItem("user_id"); + token = localStorage.getItem("token"); + isLogin = localStorage.getItem("isLogin"); + company_id = localStorage.getItem('company_id'); + role_name = localStorage.getItem('role_name'); + } + + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + const pageName = params.name; + + const [alertDelete, setAlertDelete] = useState(false) + const [clickOpenModal, setClickOpenModal] = useState(false) + const [currentPage, setCurrentPage] = useState(1) + const [dataEdit, setDataEdit] = useState([]) + const [dataExport, setDataExport] = useState([]) + const [dataTable, setDatatable] = useState([]) + const [idDelete, setIdDelete] = useState(0) + const [idPhaseProject, setIdPhaseProject] = useState(0) + const [openDialog, setOpenDialog] = useState(false) + const [openDialogIG, setOpenDialogIG] = useState(false) + const [rowsPerPage, setRowsPerPage] = useState(10) + const [search, setSearch] = useState('') + const [totalPage, setTotalPage] = useState(0) + const [typeDialog, setTypeDialog] = useState('Save') + const { t } = useTranslation() + useEffect(() => { + getDataProjectScheduleHealth() + }, [currentPage, rowsPerPage, search]) + + useEffect(() => { + const cekData = dataExport || [] + if (cekData.length > 0) { + exportExcel() + } + }, [dataExport]) + + const getDataProjectScheduleHealth = async () => { + let start = 0; + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "ilike", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + if (role_name !== "Super Admin") { + payload.columns.push( + { "name": "company_id", "logic_operator": "=", "value": company_id, "operator": "AND" }, + ) + } else { + payload.columns.push( + { "name": "company_id", "logic_operator": "is null", "value": "", "operator": "AND" }, + ) + } + const result = await axios + .post(PROJECT_SCHEDULE_HEALTH_SEARCH, payload, HEADER) + .then((res) => res) + .catch((err) => err.response); + + if (result && result.data && result.data.code == 200) { + result.data.data.map((res) => { + res.key = res.id.toString() + }); + setDatatable(result.data.data); + setTotalPage(result.data.totalRecord); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const handleSearch = e => { + const value = e.target.value + setSearch(value); + setCurrentPage(1) + }; + const handleOpenDialog = (type) => { + setOpenDialog(true) + setTypeDialog(type) + } + + const handleExportExcel = async () => { + let start = 0; + + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + const payload = { + "columns": [ + { + "name": "name", + "logic_operator": "like", + "value": search, + "operator": "AND" + } + ], + "orders": { + "ascending": true, + "columns": [ + 'id' + ] + }, + "paging": { + "length": rowsPerPage, + "start": start + } + } + + const result = await axios + .post(PROJECT_SCHEDULE_HEALTH_SEARCH, payload, HEADER) + .then(res => res) + .catch((error) => error.response); + if (result && result.data && result.data.code == 200) { + let resData = result.data.data; + const excelData = []; + resData.map((val, index) => { + let dataRow = { + "Nama": val.name, + "Color": val.color, + } + excelData.push(dataRow) + }) + await setDataExport(excelData) + } else { + NotificationManager.error('Gagal Export Data!!', 'Failed'); + } + } + + const exportExcel = () => { + const dataExcel = dataExport || []; + const fileName = `Data ${pageName}.xlsx`; + const ws = XLSX.utils.json_to_sheet(dataExcel); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); + XLSX.writeFile(wb, fileName); + setDataExport([]) + } + + const handleEdit = (data) => { + setDataEdit(data) + handleOpenDialog('Edit'); + } + + const handleDelete = async (id) => { + await setAlertDelete(true) + await setIdDelete(id) + } + + const handleCloseDialog = (type, data) => { + if (type === "save") { + saveProjectScheduleHealth(data); + } else if (type === "edit") { + editMaterialR(data); + } + setDataEdit([]) + setOpenDialog(false) + } + + const saveProjectScheduleHealth = async (data) => { + const result = await axios.post(PROJECT_SCHEDULE_HEALTH_ADD, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectScheduleHealth() + NotificationManager.success(`Data project schedule health berhasil ditambah`, 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } + + const editMaterialR = async (data) => { + let urlEdit = PROJECT_SCHEDULE_HEALTH_EDIT(data.id) + const result = await axios.put(urlEdit, data, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectScheduleHealth(); + NotificationManager.success(`Data project schedule health berhasil di edit`, 'Success!!'); + } else { + NotificationManager.error(`Data project schedule health gagal di edit`, `Failed!!`); + } + } + + const toggleAddDialog = () => { + setOpenDialog(!openDialog) + } + + const handleDialogIg = (id) => { + setIdPhaseProject(id) + setOpenDialogIG(true) + } + + const closeDialogIG = () => { + setIdPhaseProject(0) + setOpenDialogIG(false) + } + + const toggleDialogIG = () => { + if (openDialogIG) { + setIdPhaseProject(0) + } + setOpenDialogIG(!openDialogIG); + } + + const onConfirmDelete = async () => { + let url = PROJECT_SCHEDULE_HEALTH_DELETE(idDelete); + + const result = await axios.delete(url, HEADER) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataProjectScheduleHealth() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data project schedule health berhasil dihapus!`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data project schedule health gagal dihapus!}`, 'Failed!!'); + } + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const onShowSizeChange = (current, pageSize) => { + setRowsPerPage(pageSize) + } + + const onPagination = (current, pageSize) => { + setCurrentPage(current) + } + + const dataNotAvailable = () => { + if (dataTable.length === 0) { + return ( + + + + ) + } + } + + const renderTable = useMemo(() => { + const columns = [ + { + title: t('action'), + dataIndex: '', + key: 'x', + className: 'nowrap', + render: (text, record) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + {" "} + , + }, + { title: t('Project Schedule Health'), dataIndex: 'name', key: 'name', className: "nowrap" }, + { + title: t('color'), + dataIndex: 'color', + key: 'color', + render: (text) => <> + + + + , + }, + ]; + return ( +
{t('noData')}
+ ) + }, [dataTable]) + + return ( +
+ + + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + /> + + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + + + ) +} + +export default ProjectScheduleHealth; diff --git a/src/views/Master/ProjectScheduleHealth/styles.css b/src/views/Master/ProjectScheduleHealth/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/Master/ProjectScheduleHealth/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; +} + From 7e3b2f1051f6eabb1875d919d115a7be51e9747a Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:50:25 +0700 Subject: [PATCH 10/11] color chart --- src/views/Dashboard/DashboardBOD.js | 116 +++++++++++++++++++++------- 1 file changed, 88 insertions(+), 28 deletions(-) diff --git a/src/views/Dashboard/DashboardBOD.js b/src/views/Dashboard/DashboardBOD.js index b84d1e6..46175ac 100644 --- a/src/views/Dashboard/DashboardBOD.js +++ b/src/views/Dashboard/DashboardBOD.js @@ -52,6 +52,10 @@ const DashboardBOD = (props) => { const [READY_PROJECT_SCHEDULE_BUDGET_HEALTH_PER_DIVISION, SET_READY_PROJECT_SCHEDULE_BUDGET_HEALTH_PER_DIVISION] = useState(false); const [PROJECT_EXPENDITURE, SET_PROJECT_EXPENDITURE] = useState(null); + const [PROJECT_EXPENDITURE_COLOR, SET_PROJECT_EXPENDITURE_COLOR] = useState(null); + const [PROJECT_FINANCIAL_HEALTH_COLOR, SET_PROJECT_FINANCIAL_HEALTH_COLOR] = useState(null); + const [PROJECT_SCHEDULE_HEALTH_COLOR, SET_PROJECT_SCHEDULE_HEALTH_COLOR] = useState(null); + const [PROJECT_INVOICE_COLOR, SET_PROJECT_INVOICE_COLOR] = useState(null); const [PROJECT_BY_PHASE, SET_PROJECT_BY_PHASE] = useState(null); const [PROJECT_BY_FINANCIAL_HEALTH, SET_PROJECT_BY_FINANCIAL_HEALTH] = useState(null); const [PROJECT_BY_SCHEDULE_HEALTH, SET_PROJECT_BY_SCHEDULE_HEALTH] = useState(null); @@ -66,6 +70,10 @@ const DashboardBOD = (props) => { useEffect(() => { getCompanyCashFlow(); // expenditure + getCompanyExpenditureColor(); // expenditure Color + getCompanyFinancialHealthColor(); // financial health Color + getCompanyScheduleHealthColor(); // schedule health Color + getCompanyInvoiceColor(); // Project Invoice vs Cash In Color getProjectPerPhase(); // project by phase getInvoiceOutstanding(); // project invoice vs cash in getProjectPerBudgetHealth(); // project by financial health @@ -103,6 +111,32 @@ const DashboardBOD = (props) => { SET_READY_PROJECT_EXPENDITURE(true); } + // Project Expenditure Color + + const getCompanyExpenditureColor = async () => { + const URL = `${BASE_OSPRO}/api/dashboard/get-detail-expenditure-color/${company_id}` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + SET_PROJECT_EXPENDITURE_COLOR(result.data.data) + } + + const getCompanyFinancialHealthColor = async () => { + const URL = `${BASE_OSPRO}/api/dashboard/get-detail-financial-health-color/${company_id}` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + SET_PROJECT_FINANCIAL_HEALTH_COLOR(result.data.data) + } + + const getCompanyScheduleHealthColor = async () => { + const URL = `${BASE_OSPRO}/api/dashboard/get-detail-schedule-health-color/${company_id}` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + SET_PROJECT_SCHEDULE_HEALTH_COLOR(result.data.data) + } + + const getCompanyInvoiceColor = async () => { + const URL = `${BASE_OSPRO}/api/dashboard/get-detail-invoice-color/${company_id}` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + SET_PROJECT_INVOICE_COLOR(result.data.data) + } + const getInvoiceOutstanding = async () => { const URL = `${BASE_OSPRO}/api/dashboard/get-invoice-outstanding/${moment().format('YYYY')}/${company_id}/${all_project}/${hierarchy}` const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) @@ -501,8 +535,18 @@ const DashboardBOD = (props) => { PROJECT_EXPENDITURE && PROJECT_EXPENDITURE.total_invoice ? Math.floor(PROJECT_EXPENDITURE.total_invoice) : 0, PROJECT_EXPENDITURE && PROJECT_EXPENDITURE.total_paid_invoice ? PROJECT_EXPENDITURE.total_paid_invoice : 0 ], - borderColor: ['#480CA8', '#B5179E', '#A26A16', '#4C4747'], - backgroundColor: ['#480CA8', '#B5179E', '#A26A16', '#4C4747'], + borderColor: [ + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_budget && PROJECT_EXPENDITURE_COLOR.total_budget !== "" ? PROJECT_EXPENDITURE_COLOR.total_budget : '#480ca8', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_expenditure && PROJECT_EXPENDITURE_COLOR.total_expenditure !== "" ? PROJECT_EXPENDITURE_COLOR.total_expenditure : '#b5179e', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_invoice && PROJECT_EXPENDITURE_COLOR.total_invoice !== "" ? PROJECT_EXPENDITURE_COLOR.total_invoice : '#a26a16', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_paid_invoice && PROJECT_EXPENDITURE_COLOR.total_paid_invoice !== "" ? PROJECT_EXPENDITURE_COLOR.total_paid_invoice : '#4c4747' + ], + backgroundColor: [ + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_budget && PROJECT_EXPENDITURE_COLOR.total_budget !== "" ? PROJECT_EXPENDITURE_COLOR.total_budget : '#480ca8', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_expenditure && PROJECT_EXPENDITURE_COLOR.total_expenditure !== "" ? PROJECT_EXPENDITURE_COLOR.total_expenditure : '#b5179e', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_invoice && PROJECT_EXPENDITURE_COLOR.total_invoice !== "" ? PROJECT_EXPENDITURE_COLOR.total_invoice : '#a26a16', + PROJECT_EXPENDITURE_COLOR && PROJECT_EXPENDITURE_COLOR.total_paid_invoice && PROJECT_EXPENDITURE_COLOR.total_paid_invoice !== "" ? PROJECT_EXPENDITURE_COLOR.total_paid_invoice : '#4c4747' + ], borderRadius: 5, borderSkipped: false } @@ -553,8 +597,16 @@ const DashboardBOD = (props) => { PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH.warning ? PROJECT_BY_FINANCIAL_HEALTH.warning : '', PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH['on-budget'] ? PROJECT_BY_FINANCIAL_HEALTH['on-budget'] : '' ].filter(value => value !== null), - borderColor: ["#E80053", "#FFD600", "#52AC0B",], - backgroundColor: ["#E80053", "#FFD600", "#52AC0B",], + borderColor: [ + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.overrun && PROJECT_FINANCIAL_HEALTH_COLOR.overrun !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.overrun : '#E80053', + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.warning && PROJECT_FINANCIAL_HEALTH_COLOR.warning !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.warning : '#FFD600', + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] : '#52AC0B' + ], + backgroundColor: [ + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.overrun && PROJECT_FINANCIAL_HEALTH_COLOR.overrun !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.overrun : '#E80053', + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.warning && PROJECT_FINANCIAL_HEALTH_COLOR.warning !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.warning : '#FFD600', + PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] : '#52AC0B' + ], borderWidth: 2, borderSkipped: false }, @@ -579,8 +631,16 @@ const DashboardBOD = (props) => { PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH.warning ? PROJECT_BY_SCHEDULE_HEALTH.warning : '', PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] ? PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] : '' ], - borderColor: ["#E80053", "#FFD600", "#52AC0B"], - backgroundColor: ["#E80053", "#FFD600", "#52AC0B"], + borderColor: [ + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] : '#E80053', + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR.warning && PROJECT_SCHEDULE_HEALTH_COLOR.warning !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR.warning : '#FFD600', + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] : '#52AC0B' + ], + backgroundColor: [ + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] : '#E80053', + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR.warning && PROJECT_SCHEDULE_HEALTH_COLOR.warning !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR.warning : '#FFD600', + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] : '#52AC0B' + ], borderWidth: 2, borderSkipped: false }, @@ -740,9 +800,6 @@ const DashboardBOD = (props) => { datasets: [ { label: "", - // data: [3, 1, 2, 3, 7], - // borderColor: ["#F74B25", "#B5179E", "#7209B7", "#023E8A", "#3B009A"], - // backgroundColor: ["#F74B25", "#B5179E", "#7209B7", "#023E8A", "#3B009A"], data: PROJECT_BY_PHASE ? PROJECT_BY_PHASE.map((item, idx) => item.totalProject) : [], borderColor: PROJECT_BY_PHASE ? PROJECT_BY_PHASE.map((item, idx) => item.color) : [], backgroundColor: PROJECT_BY_PHASE ? PROJECT_BY_PHASE.map((item, idx) => item.color) : [], @@ -835,27 +892,21 @@ const DashboardBOD = (props) => { } }} data={{ - // labels: ["Gedung Tenaga Panel Surya", "Pembangunan Gedung Tower ABC", "Tower Jaringan Jawa Barat", "Tower Jaringan Jawa Timur", "Tower Jaringan Jawa Tengah", "Tower Jaringan Bali", "Project Tower ABC", "Tower Jaringan DKI Jakarta", "Tower Jaringan NTT"], - // labels: [["Gedung Tenaga", "Panel Surya"], ["Pembangunan Gedung", "Tower ABC"], ["Tower Jaringan", "Jawa Barat"], ["Tower Jaringan", "Jawa Timur"], ["Tower Jaringan", "Jawa Tengah"], "Tower Jaringan Bali", "Project Tower ABC", ["Tower Jaringan", "DKI Jakarta"], "Tower Jaringan NTT"], labels: PROJECT_INVOICE_VS_CASH_IN ? PROJECT_INVOICE_VS_CASH_IN.map((item, idx) => item.project_code) : [], datasets: [ { label: "Invoiced", - // data: [16, 8, 12, 10, 13, 12, 10, 10, 8], data: PROJECT_INVOICE_VS_CASH_IN ? PROJECT_INVOICE_VS_CASH_IN.map((item, idx) => Math.floor(item.invoiced)) : [], - borderColor: '#A36A16', - backgroundColor: '#A36A16', - // borderWidth: 2, + borderColor: PROJECT_INVOICE_COLOR && PROJECT_INVOICE_COLOR.invoiced && PROJECT_INVOICE_COLOR.invoiced !== "" ? PROJECT_INVOICE_COLOR.invoiced : '#A36A16', + backgroundColor: PROJECT_INVOICE_COLOR && PROJECT_INVOICE_COLOR.invoiced && PROJECT_INVOICE_COLOR.invoiced !== "" ? PROJECT_INVOICE_COLOR.invoiced : '#A36A16', borderRadius: 5, borderSkipped: false }, { label: "Cash In", - // data: [1, 1, 7, 6, 10, 9.5, 8, 9, 7.5], data: PROJECT_INVOICE_VS_CASH_IN ? PROJECT_INVOICE_VS_CASH_IN.map((item, idx) => item.paid) : [], - borderColor: '#4C4747', - backgroundColor: '#4C4747', - // borderWidth: 2, + borderColor: PROJECT_INVOICE_COLOR && PROJECT_INVOICE_COLOR.paid && PROJECT_INVOICE_COLOR.paid !== "" ? PROJECT_INVOICE_COLOR.paid : '#4C4747', + backgroundColor: PROJECT_INVOICE_COLOR && PROJECT_INVOICE_COLOR.paid && PROJECT_INVOICE_COLOR.paid !== "" ? PROJECT_INVOICE_COLOR.paid : '#4C4747', borderRadius: 5, borderSkipped: false } @@ -891,39 +942,48 @@ const DashboardBOD = (props) => { datasets: [ { label: healthPerDivisionMode === 'schedule' ? "Behind Schedule" : "Overrun", - // data: [1, 0, 0, 0], data: healthPerDivisionMode === 'schedule' ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION.map((item, idx) => item.scheduleData.behindSchedule) : [] : PROJECT_BUDGET_HEALTH_PER_DIVISION ? PROJECT_BUDGET_HEALTH_PER_DIVISION.map((item, idx) => item.budgetData.overrun) : [] , - borderColor: '#E80053', - backgroundColor: '#E80053', + borderColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] : '#E80053' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.overrun && PROJECT_FINANCIAL_HEALTH_COLOR.overrun !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.overrun : '#E80053', + backgroundColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['behind-schedule'] : '#E80053' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.overrun && PROJECT_FINANCIAL_HEALTH_COLOR.overrun !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.overrun : '#E80053', borderWidth: 2, borderRadius: 5, borderSkipped: false }, { label: healthPerDivisionMode === 'schedule' ? "Early Warning" : "Warning", - // data: [2, 0, 1, 1], data: healthPerDivisionMode === 'schedule' ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION.map((item, idx) => item.scheduleData.warning) : [] : PROJECT_BUDGET_HEALTH_PER_DIVISION ? PROJECT_BUDGET_HEALTH_PER_DIVISION.map((item, idx) => item.budgetData.warning) : [] , - borderColor: '#FFD600', - backgroundColor: '#FFD600', + borderColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR.warning && PROJECT_SCHEDULE_HEALTH_COLOR.warning !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR.warning : '#FFD600' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.warning && PROJECT_FINANCIAL_HEALTH_COLOR.warning !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.warning : '#FFD600', + backgroundColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR.warning && PROJECT_SCHEDULE_HEALTH_COLOR.warning !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR.warning : '#FFD600' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR.warning && PROJECT_FINANCIAL_HEALTH_COLOR.warning !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR.warning : '#FFD600', borderWidth: 2, borderRadius: 5, borderSkipped: false }, { label: healthPerDivisionMode === 'schedule' ? "On Schedule" : "On Budget", - // data: [4, 2, 3, 1], data: healthPerDivisionMode === 'schedule' ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION ? PROJECT_SCHEDULE_HEALTH_PER_DIVISION.map((item, idx) => item.scheduleData.onSchedule) : [] : PROJECT_BUDGET_HEALTH_PER_DIVISION ? PROJECT_BUDGET_HEALTH_PER_DIVISION.map((item, idx) => item.budgetData['on-budget']) : [] , - borderColor: '#52AC0B', - backgroundColor: '#52AC0B', + borderColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] : '#52AC0B' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] : '#52AC0B', + backgroundColor: healthPerDivisionMode === 'schedule' ? + PROJECT_SCHEDULE_HEALTH_COLOR && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] && PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] !== "" ? PROJECT_SCHEDULE_HEALTH_COLOR['on-schedule'] : '#52AC0B' + : PROJECT_FINANCIAL_HEALTH_COLOR && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] && PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] !== "" ? PROJECT_FINANCIAL_HEALTH_COLOR['on-budget'] : '#52AC0B', borderWidth: 2, borderRadius: 5, borderSkipped: false From e6f1eefb04ffb97af7aec088246887877b815cbf Mon Sep 17 00:00:00 2001 From: wahyuun Date: Wed, 20 Dec 2023 05:50:56 +0700 Subject: [PATCH 11/11] add endpoint --- src/const/ApiConst.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/const/ApiConst.js b/src/const/ApiConst.js index 5552366..f3cf52d 100644 --- a/src/const/ApiConst.js +++ b/src/const/ApiConst.js @@ -456,6 +456,42 @@ export const PROJECT_PHASE_DELETE = (id) => { }; export const PHASE_PROYEK = `${BASE_SIMPRO_LUMEN}/project-phase/list`; +export const PROJECT_EXPENDITURE_ADD = `${BASE_SIMPRO_LUMEN}/project-expenditure/add`; +export const PROJECT_EXPENDITURE_SEARCH = `${BASE_SIMPRO_LUMEN}/project-expenditure/search`; +export const PROJECT_EXPENDITURE_EDIT = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-expenditure/update/${id}`; +}; +export const PROJECT_EXPENDITURE_DELETE = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-expenditure/delete/${id}`; +}; + +export const PROJECT_FINANCIAL_HEALTH_ADD = `${BASE_SIMPRO_LUMEN}/project-financial-health/add`; +export const PROJECT_FINANCIAL_HEALTH_SEARCH = `${BASE_SIMPRO_LUMEN}/project-financial-health/search`; +export const PROJECT_FINANCIAL_HEALTH_EDIT = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-financial-health/update/${id}`; +}; +export const PROJECT_FINANCIAL_HEALTH_DELETE = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-financial-health/delete/${id}`; +}; + +export const PROJECT_SCHEDULE_HEALTH_ADD = `${BASE_SIMPRO_LUMEN}/project-schedule-health/add`; +export const PROJECT_SCHEDULE_HEALTH_SEARCH = `${BASE_SIMPRO_LUMEN}/project-schedule-health/search`; +export const PROJECT_SCHEDULE_HEALTH_EDIT = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-schedule-health/update/${id}`; +}; +export const PROJECT_SCHEDULE_HEALTH_DELETE = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-schedule-health/delete/${id}`; +}; + +export const PROJECT_INVOICE_ADD = `${BASE_SIMPRO_LUMEN}/project-invoice/add`; +export const PROJECT_INVOICE_SEARCH = `${BASE_SIMPRO_LUMEN}/project-invoice/search`; +export const PROJECT_INVOICE_EDIT = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-invoice/update/${id}`; +}; +export const PROJECT_INVOICE_DELETE = (id) => { + return `${BASE_SIMPRO_LUMEN}/project-invoice/delete/${id}`; +}; + export const PROJECT_CHARTER_ADD = `${BASE_SIMPRO_LUMEN}/project-charter/add`; export const PROJECT_CHARTER_SEARCH = `${BASE_SIMPRO_LUMEN}/project-charter/search`; export const PROJECT_CHARTER_EDIT = (id) => {