diff --git a/package.json b/package.json index fc4190f..62ce4ca 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "numeral": "^2.0.6", "ol": "^5.3.3", "prop-types": "^15.7.2", + "rc-color-picker": "^1.2.6", "react": "^16.14.0", "react-app-polyfill": "^1.0.1", "react-awesome-query-builder": "^4.3.0", diff --git a/src/scss/_custom.scss b/src/scss/_custom.scss index d1248cc..22d01bd 100644 --- a/src/scss/_custom.scss +++ b/src/scss/_custom.scss @@ -127,3 +127,36 @@ .chat-body { padding: 6px 10px } + +.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; +} + diff --git a/src/views/DashboardPMOV1/chartDashboard.js b/src/views/DashboardPMOV1/chartDashboard.js index a40a34c..baada46 100644 --- a/src/views/DashboardPMOV1/chartDashboard.js +++ b/src/views/DashboardPMOV1/chartDashboard.js @@ -1,6 +1,5 @@ import React from 'react'; import { Doughnut } from 'react-chartjs-2'; -import { faker } from '@faker-js/faker'; const options = { title: { @@ -9,30 +8,37 @@ const options = { }, }; -const data = { - labels: ['Pengadaan Barang dan Jasa','Kontruksi', 'FTTH'], - datasets: [ - { - label: '# of Votes', - data: [1, 1, 2], - backgroundColor: [ - 'rgba(255, 99, 132, 0.2)', - 'rgba(54, 162, 235, 0.2)', - 'rgba(255, 206, 86, 0.2)', - 'rgba(75, 192, 192, 0.2)', - ], - borderColor: [ - 'rgba(255, 99, 132, 1)', - 'rgba(54, 162, 235, 1)', - 'rgba(255, 206, 86, 1)', - 'rgba(75, 192, 192, 1)', - 'rgba(153, 102, 255, 1)', - ], - borderWidth: 1, - }, - ], -}; +export const ProjectTypeChart = ({ projectTypes, projectsByType }) => { + let total = [] + + for (var j = 0; j < projectTypes.length; j++) { + total.push(projectsByType[j].total) + } + + let dataSets = [{ + label: "#", + data: total, + backgroundColor: [ + 'rgba(255, 99, 132, 0.2)', + 'rgba(54, 162, 235, 0.2)', + 'rgba(255, 206, 86, 0.2)', + 'rgba(75, 192, 192, 0.2)', + ], + borderColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + 'rgba(255, 206, 86, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)', + ], + borderWidth: 1, + }] + + const data = { + labels: projectTypes, + datasets: dataSets, + }; -export const ProjectTypeChart = () => { return ; } + diff --git a/src/views/DashboardPMOV1/index.js b/src/views/DashboardPMOV1/index.js index 8a1f152..970f53e 100644 --- a/src/views/DashboardPMOV1/index.js +++ b/src/views/DashboardPMOV1/index.js @@ -64,6 +64,9 @@ const DashboardPM = () => { const [PROJECTPHASES, SET_PROJECTPHASES] = useState([]) const [PROJECTSBYPHASE, SET_PROJECTSBYPHASE] = useState([]) + const [PROJECTTYPES, SET_PROJECTTYPES] = useState([]) + const [PROJECTSBYTYPE, SET_PROJECTSBYTYPE] = useState([]) + const token = localStorage.getItem("token") const HEADER = { headers: { @@ -83,6 +86,8 @@ const DashboardPM = () => { result.data.manpowers != undefined ? SET_MANPOWERS(result.data.manpowers) : SET_MANPOWERS(0) result.data.projectPhases != undefined ? SET_PROJECTPHASES(result.data.projectPhases) : SET_PROJECTPHASES([]) result.data.projectsByPhase != undefined ? SET_PROJECTSBYPHASE(result.data.projectsByPhase) : SET_PROJECTSBYPHASE([]) + result.data.projectTypes != undefined ? SET_PROJECTTYPES(result.data.projectTypes) : SET_PROJECTTYPES([]) + result.data.projectsByType != undefined ? SET_PROJECTSBYTYPE(result.data.projectsByType) : SET_PROJECTSBYTYPE([]) } @@ -205,7 +210,7 @@ const DashboardPM = () => { - + diff --git a/src/views/Master/ProjectPhase/DialogForm.js b/src/views/Master/ProjectPhase/DialogForm.js index f2ea800..aaa335b 100644 --- a/src/views/Master/ProjectPhase/DialogForm.js +++ b/src/views/Master/ProjectPhase/DialogForm.js @@ -1,121 +1,90 @@ import React, { useEffect, useState } from 'react' -import { - Modal, ModalHeader, ModalBody, ModalFooter, - Button, Form, FormGroup, Label, Input, Col, Row +import { + Modal, ModalHeader, ModalBody, ModalFooter, + Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; -import { DatePicker, Tooltip, Select } from 'antd'; -import { formatRupiah, formatNumber } from '../../../const/CustomFunc' -import moment from 'moment'; import 'antd/dist/antd.css'; -const { Option } = Select +import InputColor from "./InputColor"; +import "./styles.css"; +import "rc-color-picker/assets/index.css"; -const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit}) => { - const [id, setId] = useState(0) +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => { + const [id, setId] = useState(0) const [projectType, setProjectType] = useState('') - const [uom, setUom] = useState('') - const [description, setDescription] = useState('') - const [unitPrice, setUnitPrice] = useState() + const [color, setColor] = useState('') - - - - useEffect(()=> { - if(typeDialog==="Edit"){ + useEffect(() => { + if (typeDialog === "Edit") { console.log("cel data Edit", dataEdit) setId(dataEdit.id) - setDescription(dataEdit.description) - setUnitPrice(dataEdit.unit_price) - setUom(dataEdit.uom) setProjectType(dataEdit.name) - - }else{ + setColor(dataEdit.color) + } else { setId(0) + setColor('') + setProjectType('') } - },[dataEdit,openDialog]) + }, [dataEdit, openDialog]) const handleSave = () => { - let data = ''; - if(typeDialog==="Save"){ - data = { - name: projectType, - description - } - - closeDialog('save', data); - }else{ - data = { - id, - name: projectType, - description - } - closeDialog('edit', data); + let data = ''; + if (typeDialog === "Save") { + data = { + name: projectType, + color } - setId(0) - setDescription('') - + closeDialog('save', data); + } else { + data = { + id, + name: projectType, + color + } + closeDialog('edit', data); + } + setId(0) } const handleCancel = () => { closeDialog('cancel', 'none') setId(0) - - setDescription('') - } - - - - - const renderForm = () => { - return( + return (
- - - - setProjectType(e.target.value)} placeholder={`Input material name...`}/> - - - - - - setDescription(e.target.value)} placeholder={`Description ...`} /> - - - + + + + setProjectType(e.target.value)} /> + + + + + + setColor(e.color)} /> + + +
) } - return ( <> - - {typeDialog=="Save" ? `Add` : "Edit"} Resource - + + {typeDialog == "Save" ? `Add` : "Edit"} data + {renderForm()} - - - {' '} - - - - - {/* toggleMapDialog} - dataEdit={dataEdit} - workArea_={workArea} - lat_={lat} - lon_={lon} - radius_={radius} - /> */} + + + {' '} + + + ) - } -export default DialogForm; \ No newline at end of file +export default DialogForm; diff --git a/src/views/Master/ProjectPhase/DialogInitialGantt.js b/src/views/Master/ProjectPhase/DialogInitialGantt.js deleted file mode 100644 index c429e23..0000000 --- a/src/views/Master/ProjectPhase/DialogInitialGantt.js +++ /dev/null @@ -1,217 +0,0 @@ -import React, { useEffect, useMemo, useState } from 'react' -import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import { Button } from 'reactstrap'; -import { Table, Tooltip } from 'antd'; -import { NotificationContainer, NotificationManager } from 'react-notifications'; -import 'antd/dist/antd.css'; -import SweetAlert from 'react-bootstrap-sweetalert'; -import { TEMPLATE_GANTT_ADD, TEMPLATE_GANTT_DELETE, TEMPLATE_GANTT_EDIT, TEMPLATE_GANTT_TREE } from '../../../const/ApiConst'; -import axios from "../../../const/interceptorApi" -import DialogForm from './DialogFormInitial'; - -const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProject }) => { - const token = window.localStorage.getItem('token'); - const config = { - headers: - { - Authorization: `Bearer ${token}`, - "Content-type": `application/json` - } - }; - - const [dataTable, setDataTable] = useState([]) - const [alertDelete, setAlertDelete] = useState(false) - const [idDelete, setIdDelete] = useState(0) - const [idActivity, setIdActivity] = useState(0) - const [openDialogForm, setOpenDialogForm] = useState(false) - const [typeDialog, setTypeDialog] = useState("add") - const [dataEdit, setDataEdit] = useState([]) - - useEffect(() => { - if (idTypeProject && idTypeProject > 0) { - getDataInitial(); - } - }, [idTypeProject]) - - const getDataInitial = async () => { - const url = TEMPLATE_GANTT_TREE(idTypeProject) - const result = await axios - .get(url, config) - .then(res => res) - .catch((error) => error.response); - if (result && result.data && result.data.code == 200) { - setDataTable(result.data.data); - } else { - NotificationManager.error('Gagal mengambil data, Silahkan coba lagi!!', 'Failed'); - } - } - - const handleDelete = async (id) => { - await setIdDelete(id) - await setAlertDelete(true) - } - - const onConfirmDelete = async () => { - let url = TEMPLATE_GANTT_DELETE(idDelete); - - const result = await axios.delete(url, config) - .then(res => res) - .catch((error) => error.response); - - if (result && result.data && result.data.code === 200) { - getDataInitial() - setIdDelete(0) - setAlertDelete(false) - NotificationManager.success(`Activity berhasil dihapus!`, 'Success!!'); - } else { - setIdDelete(0) - setAlertDelete(false) - NotificationManager.error(`Activity gagal dihapus!}`, 'Failed!!'); - } - } - - const cancelDelete = () => { - setIdDelete(0) - setAlertDelete(false) - } - - const handleAdd = async () => { - setIdActivity(0) - await setTypeDialog("add") - setOpenDialogForm(true) - } - - const handleEdit = async (data) => { - await setDataEdit(data) - if (data.parent_id) { - await setIdActivity(data.parent_id); - } - await setTypeDialog("edit") - setOpenDialogForm(true) - } - - const handleAddWithParent = async (id) => { - setIdActivity(id) - await setTypeDialog("add") - setOpenDialogForm(true) - } - - const closeDialogForm = (type, data) => { - if (type == "save") { - saveActivity(data) - } else if (type == "edit") { - updateActivity(data) - } - setIdActivity(0) - setOpenDialogForm(false) - } - - const toggleDialogForm = () => { - if (openDialogForm) { - setIdActivity(0) - } - setOpenDialogForm(!openDialogForm); - } - - const saveActivity = async (data) => { - const result = await axios.post(TEMPLATE_GANTT_ADD, data, config) - .then(res => res) - .catch((error) => error.response); - - if (result && result.data && result.data.code === 200) { - getDataInitial() - NotificationManager.success(`Data activity berhasil ditambah`, 'Success!!'); - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } - - const updateActivity = async (data) => { - const url = TEMPLATE_GANTT_EDIT(data.id) - const result = await axios.put(url, data, config) - .then(res => res) - .catch((error) => error.response); - - if (result && result.data && result.data.code === 200) { - getDataInitial() - NotificationManager.success(`Data activity berhasil diedit`, 'Success!!'); - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } - - const renderTable = useMemo(() => { - const columns = [ - { - title: 'Action', - dataIndex: '', - key: 'id', - className: "nowrap", - render: (text, record) => - <> - - - {" "} - - {" "} - - - - , - }, - { title: 'Nama Activity', dataIndex: 'name_activity', key: 'name_activity' }, - ]; - - return ( - - ) - }, [dataTable]) - - - return (<> - - - Delete this data - - - - {/* Initial Gantt */} - -
Template Gantt
-
- - {renderTable} - - - - -
- - ) - -} - -export default DialogInitialGantt; \ No newline at end of file diff --git a/src/views/Master/ProjectPhase/InputColor.js b/src/views/Master/ProjectPhase/InputColor.js new file mode 100644 index 0000000..ff2f865 --- /dev/null +++ b/src/views/Master/ProjectPhase/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/ProjectPhase/index.js b/src/views/Master/ProjectPhase/index.js index 81b4af7..e6718d9 100644 --- a/src/views/Master/ProjectPhase/index.js +++ b/src/views/Master/ProjectPhase/index.js @@ -1,13 +1,12 @@ import * as XLSX from 'xlsx'; import DialogForm from './DialogForm'; -import DialogInitialGantt from './DialogInitialGantt'; 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_PHASE_ADD, PROJECT_PHASE_EDIT, PROJECT_PHASE_DELETE, PROJECT_PHASE_SEARCH } from '../../../const/ApiConst'; +import { PROJECT_PHASE_ADD, PROJECT_PHASE_EDIT, PROJECT_PHASE_DELETE, PROJECT_PHASE_SEARCH, BASE_OSPRO } from '../../../const/ApiConst'; import { Pagination, Button, Tooltip, Table } from 'antd'; const token = window.localStorage.getItem('token'); @@ -16,18 +15,23 @@ const config = { { Authorization: `Bearer ${token}`, "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", - "Access-Control-Allow-Origin": `*` } }; const ProjectPhase = ({ params }) => { const token = localStorage.getItem("token") - const HEADER = { + /*const HEADER = { headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Access-Control-Allow-Origin": "*", "Authorization": `Bearer ${token}` } + }*/ + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } } const pageName = params.name; @@ -77,10 +81,15 @@ const ProjectPhase = ({ params }) => { } } - const result = await axios + /*const result = await axios .post(PROJECT_PHASE_SEARCH, payload, config) .then(res => res) - .catch((error) => error.response); + .catch((error) => error.response);*/ + //const result = await axios.post(PROJECT_PHASE_SEARCH, payload, HEADER).then(res => res).catch(err => err.response) + + const URL = `${BASE_OSPRO}/api/project-phase/list` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + console.log(result) if (result && result.data && result.data.code == 200) { setDatatable(result.data.data); @@ -249,7 +258,16 @@ const ProjectPhase = ({ params }) => { , }, { title: 'Fase', dataIndex: 'name', key: 'name', className: "nowrap" }, - { title: 'Warna', dataIndex: 'color', key: 'color' }, + { + title: 'Warna', + dataIndex: 'color', + key: 'color', + render: (text) => <> + + + + , + }, ]; return (
{ focusCancelBtn > Delete this data - + { clickOpenModal={clickOpenModal} dataParent={allDataMenu} /> -

{pageName}

- + diff --git a/src/views/Master/ProjectPhase/styles.css b/src/views/Master/ProjectPhase/styles.css new file mode 100644 index 0000000..d48cce6 --- /dev/null +++ b/src/views/Master/ProjectPhase/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; +} +