diff --git a/package.json b/package.json index f6e19ba..c698e3b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ }, "dependencies": { "@ant-design/plots": "^1.1.1", + "@ckeditor/ckeditor5-build-classic": "^39.0.2", + "@ckeditor/ckeditor5-react": "^6.1.0", "@coreui/coreui": "^2.1.12", "@coreui/icons": "0.3.0", "@coreui/react": "^2.5.1", diff --git a/src/const/ApiConst.js b/src/const/ApiConst.js index 645d3b2..9a7f3ae 100644 --- a/src/const/ApiConst.js +++ b/src/const/ApiConst.js @@ -677,3 +677,9 @@ export const HIERARCHY_FTTH_TREE = (id) => { return `${BASE_SIMPRO_LUMEN}/hierarchy-ftths/tree/${id}`; }; export const WAYPOINT_SEARCH = `${BASE_SIMPRO_LUMEN}/waypoint/search`; + +export const IMAGE_UPLOAD = `${BASE_SIMPRO_LUMEN}/image/upload`; + +export const IMAGE_DELETE = (id, category) => { + return `${BASE_SIMPRO_LUMEN}/image/delete/${id}/${category}`; +} diff --git a/src/views/SimproV2/CreatedProyek/DialogFormProyek.js b/src/views/SimproV2/CreatedProyek/DialogFormProyek.js index 75ec4c7..86f06bb 100644 --- a/src/views/SimproV2/CreatedProyek/DialogFormProyek.js +++ b/src/views/SimproV2/CreatedProyek/DialogFormProyek.js @@ -1,1041 +1,1105 @@ -import React, { useEffect, useState, useMemo } from "react"; -import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap"; -import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap"; -import { DatePicker, Tooltip, Select, Divider } from "antd"; -import axios from "../../../const/interceptorApi"; -import moment from "moment"; -import { - NotificationContainer, - NotificationManager, -} from "react-notifications"; -import "antd/dist/antd.css"; -import { formatNumber } from "../../../const/CustomFunc"; -import { - PROYEK_GET_ID, - PROJECT_MILESTONE_WHERE_CUSTOM, - PROJECT_PARTICIPANT_WHERE_CUSTOM, - PROJECT_APPROVAL_WHERE_CUSTOM, - CURRENCY_LIST, -} from "../../../const/ApiConst"; - -const { Option } = Select; - -const DialogFormProyek = ({ - openDialog, - closeDialog, - toggleDialog, - idTask, - dataTypeProyek, - dataPhaseProject, - dataDivisions, - dataPM, -}) => { - const token = localStorage.getItem("token"); - const HEADER = { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }; - const [id, setId] = useState(0); - const [name, setName] = useState(""); - const [shortName, setShortName] = useState(""); - const [description, setDescription] = useState(""); - const [biaya, setBiaya] = useState(""); - const [typeProject, setTypeproject] = useState(null); - const [phaseProject, setPhaseProject] = useState(null); - const [divisiProject, setDivisiProject] = useState(null); - const [budgetHealth, setHealthBudget] = useState(null); - const [sdm, setSdm] = useState(0); - const [pic, setPic] = useState(null); - const [startDate, setStartDate] = useState(moment()); - const [endDate, setEndDate] = useState(moment()); - const [workArea, setWorkArea] = useState(""); - const [finance, setFinance] = useState(""); - const [investor, setInvestor] = useState(""); - const [company, setCompany] = useState(""); - const [step, setStep] = useState(1); - const [currencyList, setCurrencyList] = useState(null); - const [currency, setCurrency] = useState(""); // merge of code | symbol | name - const [currencyCode, setCurrencyCode] = useState(""); - const [currencySymbol, setCurrencySymbol] = useState(null); - const [currencyName, setCurrencyName] = useState(""); - const [objectives, setObjectives] = useState(""); - const [projectIsConsideredSuccessful, setProjectIsConsideredSuccessful] = useState(""); - const [participants, setParticipants] = useState([]); - const [availableResources, setAvailableResources] = useState(""); - const [milestones, setMilestones] = useState([]); - const [potentialRisks, setPotentialRisks] = useState(""); - const [approval, setApproval] = useState([]); - const [testingEnv, setTestingEnv] = useState(""); - - const [lastIdxParticipants, setLastIdxParticipants] = useState(0); - const [lastIdxMilestones, setLastIdxMilestones] = useState(0); - const [lastIdxApproval, setLastIdxApproval] = useState(0); - - const handleGetdataIdproyek = async (id) => { - const result = await axios - .get(`${PROYEK_GET_ID(id)}`, HEADER) - .then((res) => res) - .catch((err) => err.response); - if (result && result.data && result.data.code === 200) { - const val = result.data.data; - setName(val.nama); - setShortName(val.kode_sortname); - setDescription(val.keterangan); - setBiaya(val.rencana_biaya ? formatNumber(val.rencana_biaya) : ""); - setTypeproject(val.type_proyek_id); - setPhaseProject(val.phase_id); - setDivisiProject(val.divisi_id); - setHealthBudget(val.budget_health); - setPic(val.pm_id); - setStartDate(moment(val.mulai_proyek)); - setEndDate(moment(val.akhir_proyek)); - setWorkArea(val.area_kerja); - setInvestor(val.investor); - setCompany(val.company); - setFinance(val.finance); - setObjectives(val.project_objectives ? val.project_objectives : ""); - setTestingEnv(val.testing_environment); - setPotentialRisks(val.potential_risk); - setProjectIsConsideredSuccessful( - val.considered_success_when ? val.considered_success_when : "" - ); - setCurrencyCode(val.currency_code); - setCurrencySymbol(val.currency_symbol); - setCurrencyName(val.currency_name); - } else { - NotificationManager.error(`Data proyek gagal di edit`, `Failed!!`); - } - }; - - const handleGetDataApproval = async (id) => { - const result = await axios - .get(`${PROJECT_APPROVAL_WHERE_CUSTOM("proyek_id", id)}`, HEADER) - .then((res) => res) - .catch((err) => err.response); - setApproval(result.data.data); - }; - - const handleGetDataMileStone = async (id) => { - const result = await axios - .get(`${PROJECT_MILESTONE_WHERE_CUSTOM("proyek_id", id)}`, HEADER) - .then((res) => res) - .catch((err) => err.response); - setMilestones(result.data.data); - }; - - const handleGetDataParticipants = async (id) => { - const result = await axios - .get(`${PROJECT_PARTICIPANT_WHERE_CUSTOM("proyek_id", id)}`, HEADER) - .then((res) => res) - .catch((err) => err.response); - setParticipants(result.data.data); - }; - - const handleGetDataCurrency = async () => { - const result = await axios - .get(CURRENCY_LIST, HEADER) - .then((res) => res) - .catch((err) => err.response); - setCurrencyList(result.data.data); - }; - - const handleClearData = () => { - setName(""); - setShortName(""); - setBiaya(""); - setTypeproject(null); - setPhaseProject(null); - setHealthBudget(null); - setPic(null); - setStartDate(moment()); - setEndDate(moment()); - setDescription(""); - setInvestor(""); - setFinance(""); - setWorkArea(""); - setCompany(""); - setCurrency(""); - setCurrencyCode(""); - setCurrencySymbol(null); - setCurrencyName(""); - setObjectives(""); - setProjectIsConsideredSuccessful(""); - setParticipants([]); - setAvailableResources(""); - setMilestones([]); - setPotentialRisks(""); - setApproval([]); - setTestingEnv(""); - setLastIdxParticipants(0); - setLastIdxMilestones(0); - setLastIdxApproval(0); - setStep(1); - }; - - useEffect(() => { - if (openDialog) { - handleGetDataCurrency(); - } - - if (idTask && idTask > 0) { - handleGetdataIdproyek(idTask); - handleGetDataParticipants(idTask); - handleGetDataMileStone(idTask); - handleGetDataApproval(idTask); - } else { - handleClearData(); - } - }, [openDialog]); - - const handleSave = () => { - let data = ""; - if (idTask) { - data = { - id: idTask, - nama: name, - kode_sortname: shortName, - rencana_biaya: biaya.replaceAll(".", ""), - mulai_proyek: startDate, - akhir_proyek: endDate, - type_proyek_id: parseInt(typeProject), - phase_id: parseInt(phaseProject), - divisi_id: parseInt(divisiProject), - budget_health: budgetHealth, - pm_id: pic, - investor, - finance, - company, - area_kerja: workArea, - keterangan: description, - project_objectives: objectives, - considered_success_when: projectIsConsideredSuccessful, - potential_risk: potentialRisks, - testing_environment: testingEnv, - currency_symbol: currencySymbol, - currency_code: currencyCode, - currency_name: currencyName, - }; - data.projectCharter = { participants, milestones, approval }; - closeDialog("edit", data); - } else { - data = { - nama: name, - kode_sortname: shortName, - rencana_biaya: biaya.replaceAll(".", ""), - mulai_proyek: startDate, - akhir_proyek: endDate, - type_proyek_id: parseInt(typeProject), - phase_id: parseInt(phaseProject), - divisi_id: parseInt(divisiProject), - health_budget: budgetHealth, - pm_id: pic, - investor, - finance, - company, - area_kerja: workArea, - keterangan: description, - project_objectives: objectives, - considered_success_when: projectIsConsideredSuccessful, - potential_risk: potentialRisks, - testing_environment: testingEnv, - currency_symbol: currencySymbol, - currency_code: currencyCode, - currency_name: currencyName, - }; - data.projectCharter = { participants, milestones, approval }; - closeDialog("add", data); - } - handleClearData(); - }; - - const handleCancel = () => { - closeDialog("cancel", "none"); - handleClearData(); - }; - - const onChangeTypeProject = (val) => { - setTypeproject(val); - }; - - const onChangePhaseProject = (val) => { - setPhaseProject(val); - }; - - const onChangeDivisiProject = (val) => { - setDivisiProject(val); - }; - - const onChangeBudgetHealth = (val) => { - setHealthBudget(val); - }; - - const onChangePm = (val) => { - let data = [...dataPM]; - var item = data.find((item) => item.id === val); - participants.push({ - id: lastIdxParticipants + 1, - title: "PM", - name: item.name, - }); - setParticipants(participants); - setLastIdxParticipants(lastIdxParticipants + 1); - setPic(val); - }; - - const onChangeCurrency = (val) => { - let curr = val.split("|"); // code|symbol|name - setCurrencyCode(curr[0]); - setCurrencySymbol(curr[1]); - setCurrencyName(curr[2]); - }; - - const handleDatePickerStart = (date, dateString) => { - setStartDate(date); - }; - - const handleDatePickerEnd = (date, dateString) => { - setEndDate(date); - }; - - const nextStep = () => { - if (!name || name === "") { - alert("Project Name cannot be empty!"); - return false; - } - if (!shortName || shortName === "") { - alert("Project Code cannot be empty!"); - return false; - } - if (!typeProject || typeProject === "") { - alert("Project Type cannot be empty!"); - return false; - } - if (!startDate || startDate === "") { - alert("Start Date cannot be empty!"); - return false; - } - if (!endDate || endDate === "") { - alert("End Date cannot be empty!"); - return false; - } - if (!biaya || biaya === "") { - alert("Budget cannot be empty!"); - return false; - } - setStep(2); - }; - - const previousStep = () => { - setStep(1); - }; - - const addParticipant = () => { - participants.push({ - id: lastIdxParticipants + 1, - title: "", - name: "", - }); - setParticipants(participants); - setLastIdxParticipants(lastIdxParticipants + 1); - }; - - const handleInputChangeParticipants = (e, index) => { - const { name, value } = e.target; - const newParticipants = [...participants]; - newParticipants[index][name] = value; - setParticipants(newParticipants); - }; - - const deleteParticipant = (id) => { - if (participants && participants.length > 0) { - let parIdx = participants.findIndex((o) => o.id === id); - if (parIdx > -1) { - participants.splice(parIdx, 1); - setParticipants(participants.filter((_, i2) => i2 !== id)); - } - } - }; - - const addMilestone = () => { - milestones.push({ - id: lastIdxMilestones + 1, - status: "", - due: moment(), - deadline: moment(), - }); - setMilestones(milestones); - setLastIdxMilestones(lastIdxMilestones + 1); - }; - - const handleInputChangeMilestones = (e, index) => { - const { name, value } = e.target; - const newMilestones = [...milestones]; - newMilestones[index][name] = value; - setMilestones(newMilestones); - }; - - const handleInputChangeMilestonesDate = (date, name, index) => { - const newMilestones = [...milestones]; - newMilestones[index][name] = date; - setMilestones(newMilestones); - }; - - const deleteMilestones = (id) => { - if (milestones && milestones.length > 0) { - let mileIdx = milestones.findIndex((o) => o.id === id); - if (mileIdx > -1) { - milestones.splice(mileIdx, 1); - setMilestones(milestones.filter((_, i2) => i2 !== id)); - } - } - }; - - const addApproval = () => { - approval.push({ - id: lastIdxApproval + 1, - title: "", - name: "", - date: moment(), - }); - setApproval(approval); - setLastIdxApproval(lastIdxApproval + 1); - }; - - const handleInputChangeApproval = (e, index) => { - const { name, value } = e.target; - const newApproval = [...approval]; - newApproval[index][name] = value; - setApproval(newApproval); - }; - - const handleInputChangeApprovalDate = (date, name, index) => { - const newApproval = [...approval]; - newApproval[index][name] = date; - setApproval(newApproval); - }; - - const deleteApproval = (id) => { - if (approval && approval.length > 0) { - let mileIdx = approval.findIndex((o) => o.id === id); - if (mileIdx > -1) { - approval.splice(mileIdx, 1); - setApproval(approval.filter((_, i2) => i2 !== id)); - } - } - }; - - const renderForm = () => { - return ( -
- - - * Wajib diisi. - - - - - - - setName(e.target.value)} - /> - - - - - - setShortName(e.target.value)} - /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - let currentDate = moment(current).format("YYYY-MM-DD"); - let customDate = moment(startDate) - .add(1, "days") - .format("YYYY-MM-DD"); - return current && currentDate < customDate; - }} - format={"DD-MM-YYYY"} - style={{ width: "100%" }} - value={endDate} - onChange={handleDatePickerEnd} - /> - - - - - - - - setWorkArea(e.target.value)} - /> - - - - - - setCompany(e.target.value)} - /> - - - - - - - - - - - - - setBiaya(formatNumber(e.target.value))} - /> - - - - - - - - setDescription(e.target.value)} - /> - - - - - - - - - - - - - Info Dashboard - - - - - - - - - - - - - - - -
- ); - }; - - const renderFormCharter = () => { - return ( -
- - - Project Objectives - - - - setObjectives(e.target.value)} - /> - - - - - - Project is considered successful when - - - - - setProjectIsConsideredSuccessful(e.target.value) - } - placeholder={`List of indicators`} - rows={5} - /> - - - - - - Project Participants - - - {/* - - - - */} - - - Title - - - Name - - - Action - - - - - -
{RenderParticipants()}
- -
- - - Testing Environment - - - - setTestingEnv(e.target.value)} - rows={5} - /> - - - - - - Milestones - - - {/* - - - - */} - - - Status - - {/* - Due - */} - - Deadline - - - Action - - - - - -
{RenderMilestones()}
- -
- - - Potential risks - - - - setPotentialRisks(e.target.value)} - placeholder={`List of risks`} - rows={5} - /> - - - - - - Approval - - - {/* - - - - */} - - - Title - - - Name - - - Date - - - Action - - - - - -
{RenderApproval()}
- -
-
- ); - }; - - const RenderParticipants = () => { - if (participants.length > 0) { - return participants.map((item, index) => { - return ( - - - handleInputChangeParticipants(e, index)} - /> - - - handleInputChangeParticipants(e, index)} - /> - - - - - - ); - }); - } else if (participants.length < 1) { - return ( -
- No participants found -
- ); - } - }; - - const RenderMilestones = () => { - if (milestones.length > 0) { - return milestones.map((item, index) => { - return ( - - - handleInputChangeMilestones(e, index)} - /> - - - - handleInputChangeMilestonesDate(date, "deadline", index) - } - /> - - - - - - ); - }); - } else if (milestones.length < 1) { - return ( -
- No milestones found -
- ); - } - }; - - const RenderApproval = () => { - if (approval.length > 0) { - return approval.map((item, index) => { - return ( - - - handleInputChangeApproval(e, index)} - /> - - - handleInputChangeApproval(e, index)} - /> - - - - handleInputChangeApprovalDate(date, "date", index) - } - /> - - - - - - ); - }); - } else if (approval.length < 1) { - return ( -
- No approval found -
- ); - } - }; - - return ( - <> - - - {step === 1 - ? idTask - ? "Update Project" - : "Add Project" - : "Project Charter"} - - {step === 1 ? renderForm() : renderFormCharter()} - - {step === 1 ? ( - <> - {" "} - - - ) : ( - <> - {" "} - - - )} - - - - ); -}; - -export default DialogFormProyek; +import React, { useEffect, useState, useMemo } from "react"; +import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap"; +import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap"; +import { DatePicker, Tooltip, Select, Divider } from "antd"; +import axios from "../../../const/interceptorApi"; +import moment from "moment"; +import { CKEditor } from '@ckeditor/ckeditor5-react'; +import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; +import { + NotificationContainer, + NotificationManager, +} from "react-notifications"; +import "antd/dist/antd.css"; +import { formatNumber } from "../../../const/CustomFunc"; +import { + PROYEK_GET_ID, + PROJECT_MILESTONE_WHERE_CUSTOM, + PROJECT_PARTICIPANT_WHERE_CUSTOM, + PROJECT_APPROVAL_WHERE_CUSTOM, + CURRENCY_LIST, +} from "../../../const/ApiConst"; + +const { Option } = Select; + +const DialogFormProyek = ({ + openDialog, + closeDialog, + toggleDialog, + idTask, + dataTypeProyek, + dataPhaseProject, + dataDivisions, + dataPM, + projectImage +}) => { + const token = localStorage.getItem("token"); + const HEADER = { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + }; + const [id, setId] = useState(0); + const [name, setName] = useState(""); + const [shortName, setShortName] = useState(""); + const [description, setDescription] = useState(""); + const [late, setLateConsequence] = useState(""); + const [assumtion, setAssumtion] = useState(""); + const [biaya, setBiaya] = useState(""); + const [typeProject, setTypeproject] = useState(null); + const [phaseProject, setPhaseProject] = useState(null); + const [divisiProject, setDivisiProject] = useState(null); + const [budgetHealth, setHealthBudget] = useState(null); + const [sdm, setSdm] = useState(0); + const [pic, setPic] = useState(null); + const [startDate, setStartDate] = useState(moment()); + const [endDate, setEndDate] = useState(moment()); + const [workArea, setWorkArea] = useState(""); + const [duration, setProjectDuration] = useState(""); + const [organization, setProjectStructureOrg] = useState(null); + const [finance, setFinance] = useState(""); + const [investor, setInvestor] = useState(""); + const [company, setCompany] = useState(""); + const [step, setStep] = useState(1); + const [currencyList, setCurrencyList] = useState(null); + const [currency, setCurrency] = useState(""); // merge of code | symbol | name + const [currencyCode, setCurrencyCode] = useState(""); + const [currencySymbol, setCurrencySymbol] = useState(null); + const [currencyName, setCurrencyName] = useState(""); + const [objectives, setObjectives] = useState(""); + const [projectIsConsideredSuccessful, setProjectIsConsideredSuccessful] = useState(""); + const [participants, setParticipants] = useState([]); + const [image, setImage] = useState("") + const [availableResources, setAvailableResources] = useState(""); + const [milestones, setMilestones] = useState([]); + const [potentialRisks, setPotentialRisks] = useState(""); + const [approval, setApproval] = useState([]); + const [testingEnv, setTestingEnv] = useState(""); + + const [lastIdxParticipants, setLastIdxParticipants] = useState(0); + const [lastIdxMilestones, setLastIdxMilestones] = useState(0); + const [lastIdxApproval, setLastIdxApproval] = useState(0); + + const handleGetdataIdproyek = async (id) => { + const result = await axios + .get(`${PROYEK_GET_ID(id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + if (result && result.data && result.data.code === 200) { + const val = result.data.data; + setName(val.nama); + setShortName(val.kode_sortname); + setDescription(val.keterangan); + setLateConsequence(val.late_consequence ? val.late_consequence : ""); + setAssumtion(val.assumtion ? val.assumtion : ""); + setBiaya(val.rencana_biaya ? formatNumber(val.rencana_biaya) : ""); + setTypeproject(val.type_proyek_id); + setPhaseProject(val.phase_id); + setDivisiProject(val.divisi_id); + setHealthBudget(val.budget_health); + setPic(val.pm_id); + setStartDate(moment(val.mulai_proyek)); + setEndDate(moment(val.akhir_proyek)); + setWorkArea(val.area_kerja); + setProjectDuration(val.durasi_proyek); + setInvestor(val.investor); + setCompany(val.company); + setFinance(val.finance); + setObjectives(val.project_objectives ? val.project_objectives : ""); + setTestingEnv(val.testing_environment); + setPotentialRisks(val.potential_risk); + setProjectIsConsideredSuccessful( + val.considered_success_when ? val.considered_success_when : "" + ); + setCurrencyCode(val.currency_code); + setCurrencySymbol(val.currency_symbol); + setCurrencyName(val.currency_name); + } else { + NotificationManager.error(`Data proyek gagal di edit`, `Failed!!`); + } + }; + + const handleGetDataApproval = async (id) => { + const result = await axios + .get(`${PROJECT_APPROVAL_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setApproval(result.data.data); + }; + + const handleGetDataMileStone = async (id) => { + const result = await axios + .get(`${PROJECT_MILESTONE_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setMilestones(result.data.data); + }; + + const handleGetDataParticipants = async (id) => { + const result = await axios + .get(`${PROJECT_PARTICIPANT_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setParticipants(result.data.data); + }; + + const handleGetDataCurrency = async () => { + const result = await axios + .get(CURRENCY_LIST, HEADER) + .then((res) => res) + .catch((err) => err.response); + setCurrencyList(result.data.data); + }; + + const handleClearData = () => { + setName(""); + setShortName(""); + setBiaya(""); + setTypeproject(null); + setPhaseProject(null); + setHealthBudget(null); + setPic(null); + setStartDate(moment()); + setEndDate(moment()); + setDescription(""); + setLateConsequence(""); + setAssumtion(""); + setInvestor(""); + setFinance(""); + setWorkArea(""); + setProjectDuration(""); + setProjectStructureOrg(null); + setCompany(""); + setCurrency(""); + setCurrencyCode(""); + setCurrencySymbol(null); + setCurrencyName(""); + setObjectives(""); + setImage(""); + setProjectIsConsideredSuccessful(""); + setParticipants([]); + setAvailableResources(""); + setMilestones([]); + setPotentialRisks(""); + setApproval([]); + setTestingEnv(""); + setLastIdxParticipants(0); + setLastIdxMilestones(0); + setLastIdxApproval(0); + setStep(1); + }; + + useEffect(() => { + if (openDialog) { + handleGetDataCurrency(); + } + + if (idTask && idTask > 0) { + handleGetdataIdproyek(idTask); + handleGetDataParticipants(idTask); + handleGetDataMileStone(idTask); + handleGetDataApproval(idTask); + } else { + handleClearData(); + } + }, [openDialog]); + + const handleSave = () => { + let data = ""; + if (idTask) { + data = { + id: idTask, + nama: name, + kode_sortname: shortName, + rencana_biaya: biaya.replaceAll(".", ""), + mulai_proyek: startDate, + akhir_proyek: endDate, + type_proyek_id: parseInt(typeProject), + phase_id: parseInt(phaseProject), + divisi_id: parseInt(divisiProject), + budget_health: budgetHealth, + pm_id: pic, + investor, + finance, + company, + area_kerja: workArea, + durasi_proyek: parseInt(duration), + late_consequence: late, + assumtion: assumtion, + keterangan: description, + project_objectives: objectives, + considered_success_when: projectIsConsideredSuccessful, + potential_risk: potentialRisks, + testing_environment: testingEnv, + currency_symbol: currencySymbol, + currency_code: currencyCode, + currency_name: currencyName, + }; + data.projectCharter = { participants, milestones, approval }; + data.imageStructureOrg = organization ? organization : null; + closeDialog("edit", data); + } else { + data = { + nama: name, + kode_sortname: shortName, + rencana_biaya: biaya.replaceAll(".", ""), + mulai_proyek: startDate, + akhir_proyek: endDate, + type_proyek_id: parseInt(typeProject), + phase_id: parseInt(phaseProject), + divisi_id: parseInt(divisiProject), + health_budget: budgetHealth, + pm_id: pic, + investor, + finance, + company, + area_kerja: workArea, + durasi_proyek: parseInt(duration), + late_consequence: late, + assumtion: assumtion, + keterangan: description, + project_objectives: objectives, + considered_success_when: projectIsConsideredSuccessful, + potential_risk: potentialRisks, + testing_environment: testingEnv, + currency_symbol: currencySymbol, + currency_code: currencyCode, + currency_name: currencyName, + }; + data.projectCharter = { participants, milestones, approval }; + data.imageStructureOrg = organization ? organization : null; + + closeDialog("add", data); + } + handleClearData(); + }; + + const handleCancel = () => { + closeDialog("cancel", "none"); + handleClearData(); + }; + + const onChangeTypeProject = (val) => { + setTypeproject(val); + }; + + const onChangePhaseProject = (val) => { + setPhaseProject(val); + }; + + const onChangeDivisiProject = (val) => { + setDivisiProject(val); + }; + + const onChangeBudgetHealth = (val) => { + setHealthBudget(val); + }; + + const onChangePm = (val) => { + let data = [...dataPM]; + var item = data.find((item) => item.id === val); + participants.push({ + id: lastIdxParticipants + 1, + title: "PM", + name: item.name, + }); + setParticipants(participants); + setLastIdxParticipants(lastIdxParticipants + 1); + setPic(val); + }; + + const onChangeCurrency = (val) => { + let curr = val.split("|"); // code|symbol|name + setCurrencyCode(curr[0]); + setCurrencySymbol(curr[1]); + setCurrencyName(curr[2]); + }; + + const handleDatePickerStart = (date, dateString) => { + setStartDate(date); + }; + + const handleDatePickerEnd = (date, dateString) => { + setEndDate(date); + }; + + const nextStep = () => { + if (!name || name === "") { + alert("Project Name cannot be empty!"); + return false; + } + if (!shortName || shortName === "") { + alert("Project Code cannot be empty!"); + return false; + } + if (!typeProject || typeProject === "") { + alert("Project Type cannot be empty!"); + return false; + } + if (!startDate || startDate === "") { + alert("Start Date cannot be empty!"); + return false; + } + if (!endDate || endDate === "") { + alert("End Date cannot be empty!"); + return false; + } + if (!biaya || biaya === "") { + alert("Budget cannot be empty!"); + return false; + } + if (!currencySymbol || currencySymbol === "") { + alert("Currency Symbol cannot be empty!"); + return false; + } + setStep(2); + }; + + const previousStep = () => { + setStep(1); + }; + + const addParticipant = () => { + participants.push({ + id: lastIdxParticipants + 1, + title: "", + name: "", + }); + setParticipants(participants); + setLastIdxParticipants(lastIdxParticipants + 1); + }; + + const handleInputChangeParticipants = (e, index) => { + const { name, value } = e.target; + const newParticipants = [...participants]; + newParticipants[index][name] = value; + setParticipants(newParticipants); + }; + + const deleteParticipant = (id) => { + if (participants && participants.length > 0) { + let parIdx = participants.findIndex((o) => o.id === id); + if (parIdx > -1) { + participants.splice(parIdx, 1); + setParticipants(participants.filter((_, i2) => i2 !== id)); + } + } + }; + + const addMilestone = () => { + milestones.push({ + id: lastIdxMilestones + 1, + status: "", + due: moment(), + deadline: moment(), + }); + setMilestones(milestones); + setLastIdxMilestones(lastIdxMilestones + 1); + }; + + const handleInputChangeMilestones = (e, index) => { + const { name, value } = e.target; + const newMilestones = [...milestones]; + newMilestones[index][name] = value; + setMilestones(newMilestones); + }; + + const handleInputChangeMilestonesDate = (date, name, index) => { + const newMilestones = [...milestones]; + newMilestones[index][name] = date; + setMilestones(newMilestones); + }; + + const deleteMilestones = (id) => { + if (milestones && milestones.length > 0) { + let mileIdx = milestones.findIndex((o) => o.id === id); + if (mileIdx > -1) { + milestones.splice(mileIdx, 1); + setMilestones(milestones.filter((_, i2) => i2 !== id)); + } + } + }; + + const addApproval = () => { + approval.push({ + id: lastIdxApproval + 1, + title: "", + name: "", + date: moment(), + }); + setApproval(approval); + setLastIdxApproval(lastIdxApproval + 1); + }; + + const handleInputChangeApproval = (e, index) => { + const { name, value } = e.target; + const newApproval = [...approval]; + newApproval[index][name] = value; + setApproval(newApproval); + }; + + const handleInputChangeApprovalDate = (date, name, index) => { + const newApproval = [...approval]; + newApproval[index][name] = date; + setApproval(newApproval); + }; + + const deleteApproval = (id) => { + if (approval && approval.length > 0) { + let mileIdx = approval.findIndex((o) => o.id === id); + if (mileIdx > -1) { + approval.splice(mileIdx, 1); + setApproval(approval.filter((_, i2) => i2 !== id)); + } + } + }; + const editorConfig = { + height: '900px' + }; + + const RenderFormProject = () => { + return ( + <> +
+ + + * Wajib diisi. + + + + + + + setName(e.target.value)} + /> + + + + + + setShortName(e.target.value)} + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + let currentDate = moment(current).format("YYYY-MM-DD"); + let customDate = moment(startDate) + .add(1, "days") + .format("YYYY-MM-DD"); + return current && currentDate < customDate; + }} + format={"DD-MM-YYYY"} + style={{ width: "100%" }} + value={endDate} + onChange={handleDatePickerEnd} + /> + + + + + + + + setWorkArea(e.target.value)} + /> + + + + + + setCompany(e.target.value)} + /> + + + + + + + + + + + + + setBiaya(formatNumber(e.target.value))} + /> + + + + + + + + + + + + + + + + setProjectDuration(e.target.value)} + /> + + + + + + + + setProjectStructureOrg(e.target.files[0])} + /> + {projectImage ? projectImage.image :

Not found image

}
+
+ + + + + setDescription(e.target.value)} + /> + + +
+ + + + { + const data = editor.getData(); + setLateConsequence(data); + } } + /> + + + + + + { + const data = editor.getData(); + setAssumtion(data); + } } + /> + + + + Info Dashboard + + + + + + + + + + + + + + + +
+ +
+ + + Project Objectives + + + + setObjectives(e.target.value)} + /> + + + + + + Project is considered successful when + + + + + setProjectIsConsideredSuccessful(e.target.value) + } + placeholder={`List of indicators`} + rows={5} + /> + + + + + + Project Participants + + + + + Title + + + Name + + + Action + + + + + +
{RenderParticipants()}
+ +
+ + + Testing Environment + + + + setTestingEnv(e.target.value)} + rows={5} + /> + + + + + + Milestones + + + + + Status + + + Deadline + + + Action + + + + + +
{RenderMilestones()}
+ +
+ + + Potential risks + + + + setPotentialRisks(e.target.value)} + placeholder={`List of risks`} + rows={5} + /> + + + + + + Approval + + + + + Title + + + Name + + + Date + + + Action + + + + + +
{RenderApproval()}
+ +
+
+ + ) + } + + const RenderParticipants = () => { + if (participants.length > 0) { + return participants.map((item, index) => { + return ( + + + handleInputChangeParticipants(e, index)} + /> + + + handleInputChangeParticipants(e, index)} + /> + + + + + + ); + }); + } else if (participants.length < 1) { + return ( +
+ No participants found +
+ ); + } + }; + + const RenderMilestones = () => { + if (milestones.length > 0) { + return milestones.map((item, index) => { + return ( + + + handleInputChangeMilestones(e, index)} + /> + + + + handleInputChangeMilestonesDate(date, "deadline", index) + } + /> + + + + + + ); + }); + } else if (milestones.length < 1) { + return ( +
+ No milestones found +
+ ); + } + }; + + const RenderApproval = () => { + if (approval.length > 0) { + return approval.map((item, index) => { + return ( + + + handleInputChangeApproval(e, index)} + /> + + + handleInputChangeApproval(e, index)} + /> + + + + handleInputChangeApprovalDate(date, "date", index) + } + /> + + + + + + ); + }); + } else if (approval.length < 1) { + return ( +
+ No approval found +
+ ); + } + }; + + return ( + <> + + + {step === 1 + ? idTask + ? "Update Project" + : "Add Project" + : "Project Charter"} + + { RenderFormProject() } + + {step === 1 ? ( + <> + {" "} + + + ) : ( + <> + {" "} + + + )} + + + + ); +}; + +export default DialogFormProyek; diff --git a/src/views/SimproV2/CreatedProyek/ViewProject.js b/src/views/SimproV2/CreatedProyek/ViewProject.js index d31f48f..7798212 100644 --- a/src/views/SimproV2/CreatedProyek/ViewProject.js +++ b/src/views/SimproV2/CreatedProyek/ViewProject.js @@ -6,21 +6,28 @@ import 'antd/dist/antd.css'; import _ from 'underscore' import './style.css' import { formatThousand, sortBy } from '../../../const/CustomFunc'; +import { BASE_OSPRO } from "../../../const/ApiConst"; const createMarkup = (element) => { return {__html: element}; } - const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectMilestone, projectApproval, projectManager, projectK3, assignHR }) => { + const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectMilestone, projectApproval, projectManager, projectK3, assignHR, projectImage }) => { const [proyekName, setProyekName] = useState("") const [description, setDescription] = useState("") const [shortname, setKodeShortname] = useState("") const [lokasi, setLokasiKantor] = useState("") const [durasi, setDurasiProyek] = useState("") const [mulaiProyek, setMulaiProyek] = useState("") + const [valueProyek, setValueProyek] = useState("") + const [scoupeProyek, setScoupeProyek] = useState("") + const [sponsorProyek, setSponsorProyek] = useState("") + const [lateProyek, setLateConsequenceProyek] = useState("") + const [assumtionProyek, setAssumtionProyek] = useState("") const [objectives, setObjective] = useState("") const [projectSuccess, setProjectSuccess] = useState("") const [participants, setParticipants] = useState("") + const [image, setImage] = useState("") const [budget, setBudget] = useState("") const [currency, setCurrency] = useState("") const [testing, setTesting] = useState("") @@ -39,11 +46,17 @@ const createMarkup = (element) => { setLokasiKantor("") setDurasiProyek("") setMulaiProyek("") + setValueProyek("") + setScoupeProyek("") + setSponsorProyek("") + setLateConsequenceProyek("") + setAssumtionProyek("") setObjective("") setProjectSuccess("") setParticipants([]) setDataK3Search([]) setAssignHR([]) + setImage("") setBudget("") setCurrency("") setTesting("") @@ -61,6 +74,11 @@ const createMarkup = (element) => { setLokasiKantor(projectCharter.lokasi_kantor); setDurasiProyek(projectCharter.durasi_proyek); setMulaiProyek(projectCharter.mulai_proyek); + setValueProyek(projectCharter.value_proyek); + setScoupeProyek(projectCharter.scoupe_of_work); + setSponsorProyek(projectCharter.nama_divisi); + setLateConsequenceProyek(projectCharter.late_consequence); + setAssumtionProyek(projectCharter.assumtion); setObjective(projectCharter.project_objectives); setProjectSuccess(projectCharter.considered_success_when); setBudget(projectCharter.rencana_biaya); @@ -70,6 +88,12 @@ const createMarkup = (element) => { } }, [projectCharter]); + useEffect(() => { + if (projectImage && projectImage != {}) { + setImage(projectImage.image) + } + }, [projectImage]); + useEffect(() => { if(projectParticipant && projectParticipant.length > 0){ setParticipants(projectParticipant) @@ -232,6 +256,7 @@ const createMarkup = (element) => { const tdStyle = { border: '1px solid black', + width: "250px" }; const pStyle = { marginLeft: '5pt', @@ -254,17 +279,6 @@ const createMarkup = (element) => { padding: '0', }; - const redStyle = { - fontFamily: 'Arial', - fontSize: '10pt', - color: '#FF0000', - }; - const boldItalicStyle = { - ...pStyle, - fontWeight: 'bold', - fontStyle: 'italic', - }; - const renderForm = () => { return (
@@ -328,7 +342,7 @@ const createMarkup = (element) => {

Nilai Kontrak Proyek

-

 

+

 {valueProyek ?? '-'}

@@ -344,7 +358,9 @@ const createMarkup = (element) => {

Sponsor Proyek

-

Adalah Divisi yang memiliki akun atas proyek ini berikut nama GM nya

+

+ {sponsorProyek ?? '-'} +

 

@@ -378,7 +394,7 @@ const createMarkup = (element) => { -

{objectives}

+

{objectives ?? '-'}

@@ -394,10 +410,7 @@ const createMarkup = (element) => { @@ -435,7 +448,13 @@ const createMarkup = (element) => { -

 

+

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

@@ -515,7 +534,7 @@ const createMarkup = (element) => { -

+

@@ -530,11 +549,7 @@ const createMarkup = (element) => { - -

Adalah dampak dari jika terjadi keterlambatan atas implementasi proyek.

-

Sampaikan berapa besar kerugian jika dikenakan dengan denda maksimal.

-

Apa dampak pada potensi repeat order untuk proyek berikutnya.

- +

@@ -548,10 +563,7 @@ const createMarkup = (element) => { -

Waktu

-

Biaya

-

Benefit bagi customer: misalkan bisa memberikan layanan publik sebelum hari raya

-

Zero accident Report: (tidak adanya kejadian yang memberikan dampak negative kepada Kesehatan tim dan warga sekitar)

+

{projectSuccess ?? '-'}

@@ -566,9 +578,7 @@ const createMarkup = (element) => { -

- Disebutkan SDM/Tools apa yang bisa dan mandatory diperlukan untuk menunjang lancarnya implementasi, dan jika hal tersebut tidak terpenuhi maka potensi akan terjadinya kondisi yang tidak diinginkan akan menjadi semakin besar. Misalkan; harus tersedia 4 orang drafter yang sudah memahami alur proyek dengan baik. -

+

@@ -669,10 +679,10 @@ const createMarkup = (element) => { - +

NO

- +

ITEM

diff --git a/src/views/SimproV2/CreatedProyek/index.js b/src/views/SimproV2/CreatedProyek/index.js index 6a5c10f..7905a59 100644 --- a/src/views/SimproV2/CreatedProyek/index.js +++ b/src/views/SimproV2/CreatedProyek/index.js @@ -55,6 +55,9 @@ import { PHASE_PROYEK, DIVISI_LIST, BASE_OSPRO, + IMAGE_UPLOAD, + IMAGE_GET_BY_ID, + IMAGE_DELETE, } from "../../../const/ApiConst"; import { formatNumber, @@ -96,6 +99,13 @@ const CreatedProyek = ({ params, ...props }) => { }, }; + const HEADER_MULTIPART = { + headers: { + "Content-Type": "multipart/form-data", + Authorization: `Bearer ${token}`, + }, + }; + const [idTask, setidTask] = useState(0); const [dataTable, setDatatable] = useState([]); const [search, setSearch] = useState(""); @@ -136,6 +146,7 @@ const CreatedProyek = ({ params, ...props }) => { const [projectPM, setPM] = useState(null); const [projectK3Search, setK3Search] = useState(null); const [projectAssignHR, setProjectAssignHR] = useState(null); + const [image, setProjectImage] = useState(null); const [loadVersionGantt, setLoadVersionGantt] = useState(false); const [loadHierarchy, setLoadHierarchy] = useState(false); @@ -431,9 +442,10 @@ const CreatedProyek = ({ params, ...props }) => { setidTask(id); }; - const handleOpenDialogProyek = (id) => { + const handleOpenDialogProyek = async (id) => { setOpenDialogProyek(true); setidTask(id); + await getProjectImage(id); }; const handleOpenDialogGantt = (data) => { @@ -504,6 +516,7 @@ const CreatedProyek = ({ params, ...props }) => { await getProjectApproval(data.id); await getK3toProject(data.id); await getProjectAssignHR(data.id); + await getProjectImage(data.id); // await handleGetDataPm(data.id); setPM(data.join_first_name); setOpenDialogViewDetail(true); @@ -571,8 +584,8 @@ const CreatedProyek = ({ params, ...props }) => { .catch((error) => error.response); if (result && result.data && result.data.code == 200) { - const {kode_sortname,nama,mulai_proyek,rencana_biaya,keterangan,durasi_proyek,project_objectives,potential_risk,currency_symbol} = result.data.data; - const dataToSend = { kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol }; + const {kode_sortname,nama,mulai_proyek,rencana_biaya,keterangan,durasi_proyek,project_objectives,potential_risk,currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when} = result.data.data; + const dataToSend = { kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when}; setProjectCharter(dataToSend); } else { NotificationManager.error("Gagal Mengambil Data!!", "Failed"); @@ -647,6 +660,17 @@ const CreatedProyek = ({ params, ...props }) => { } }; + const getProjectImage = async (id) => { + const url = IMAGE_GET_BY_ID(id, "project_structure_organization"); + const result = await axios + .get(url, HEADER) + .then((res) => res) + .catch((err) => err.response); + if (result && result.data && result.data.code === 200) { + setProjectImage(result.data.data); + } + } + const getProjectParticipant = async (id) => { const payload = { select: [ @@ -720,6 +744,7 @@ const CreatedProyek = ({ params, ...props }) => { setProjectCharter(null); setK3Search(null); setProjectAssignHR(null); + setProjectImage(null); setOpenDialogViewDetail(false); }; @@ -733,6 +758,7 @@ const CreatedProyek = ({ params, ...props }) => { setProjectCharter(null); setK3Search(null); setProjectAssignHR(null); + setProjectImage(null); } setOpenDialogViewDetail(!openDialogViewDetail); }; @@ -746,7 +772,8 @@ const CreatedProyek = ({ params, ...props }) => { if (result && result.data && result.data.code === 200) { role_id !== "44" ? getDataProyek() : getDataProyekByCustomer(); - + getProjectImage(idDelete); + deleteImage(idDelete); setIdDelete(0); setAlertDelete(false); NotificationManager.success(`Data proyek berhasil dihapus`, "Success!!"); @@ -766,6 +793,7 @@ const CreatedProyek = ({ params, ...props }) => { .catch((error) => error.response); if (result && result.data && result.data.code === 200) { const { participants, milestones, approval } = data.projectCharter; + const imageObject = data.imageStructureOrg; const resultParticipant = await saveParticipant( result.data.data_result.id, participants @@ -778,12 +806,18 @@ const CreatedProyek = ({ params, ...props }) => { result.data.data_result.id, approval ); + if (imageObject) { + await saveImage( + result.data.data_result.id, + imageObject + ); + } + if ( resultParticipant === "berhasil" && resultMilestone === "berhasil" && resultApproval === "berhasil" ) { - // getDataProyek(); NotificationManager.success( `Data proyek berhasil ditambah`, "Success!!" @@ -860,8 +894,33 @@ const CreatedProyek = ({ params, ...props }) => { return "berhasil"; }; + const saveImage = async (id, data) => { + const formData = new FormData; + formData.append('ref_id', id); + formData.append('category', 'project_structure_organization'); + formData.append('files', data); + + await axios + .post(IMAGE_UPLOAD, formData, HEADER_MULTIPART) + .then(res => res) + .catch((error) => error.response); + return "berhasil"; + }; + + const deleteImage = async (id) => { + const URL = IMAGE_DELETE(id, 'project_structure_organization'); + + await axios + .delete(URL, HEADER) + .then(res => res) + .catch((error) => error.response); + return "berhasil"; + }; + const editProyek = async (data) => { const { participants, milestones, approval } = data.projectCharter; + const imageObject = data.imageStructureOrg; + let urlEdit = PROYEK_EDIT(data.id); const formData = data; @@ -872,6 +931,15 @@ const CreatedProyek = ({ params, ...props }) => { const resultParticipant = await editParticipant(data.id, participants); const resultMilestone = await editMilestone(data.id, milestones); const resultApproval = await editApproval(data.id, approval); + if (imageObject) { + await deleteImage( + data.id + ); + await saveImage( + data.id, + imageObject + ); + } if (result && result.status === 200) { role_id !== "44" ? getDataProyek() : getDataProyekByCustomer(); NotificationManager.success(`Data proyek berhasil Ubah`, "Success!!"); @@ -882,7 +950,6 @@ const CreatedProyek = ({ params, ...props }) => { const editParticipant = async (id, data) => { await axios.delete(PROJECT_PARTICIPANT_DELETE_BY_PROYEK(id), HEADER); - // if (restDelete){ const request = data.map((res) => { const payload = { proyek_id: parseInt(id), @@ -1432,6 +1499,7 @@ const CreatedProyek = ({ params, ...props }) => { dataPhaseProject={dataPhaseProject} dataDivisions={dataDivisions} dataPM={dataPm} + projectImage={image} /> ), [ @@ -1441,6 +1509,7 @@ const CreatedProyek = ({ params, ...props }) => { dataPhaseProject, dataTypeProyek, idTask, + image ] ); @@ -1559,6 +1628,7 @@ const CreatedProyek = ({ params, ...props }) => { projectManager={projectPM} projectK3={projectK3Search} assignHR={projectAssignHR} + projectImage={image} /> ), [openDialogViewDetail]