From b5be295c54785c02d8a55c6ff1caa5246621f021 Mon Sep 17 00:00:00 2001 From: farhantock Date: Tue, 23 Jan 2024 17:31:01 +0700 Subject: [PATCH] update menu page --- .../{MasterMenu => MenuCompany}/DialogForm.js | 48 +- .../Master/MenuCompany/DialogMasterMenu.js | 418 ++++++++++++++++++ .../{MasterMenu => MenuCompany}/index.js | 89 +++- 3 files changed, 544 insertions(+), 11 deletions(-) rename src/views/Master/{MasterMenu => MenuCompany}/DialogForm.js (77%) create mode 100644 src/views/Master/MenuCompany/DialogMasterMenu.js rename src/views/Master/{MasterMenu => MenuCompany}/index.js (77%) diff --git a/src/views/Master/MasterMenu/DialogForm.js b/src/views/Master/MenuCompany/DialogForm.js similarity index 77% rename from src/views/Master/MasterMenu/DialogForm.js rename to src/views/Master/MenuCompany/DialogForm.js index be33f53..e9cbc50 100644 --- a/src/views/Master/MasterMenu/DialogForm.js +++ b/src/views/Master/MenuCompany/DialogForm.js @@ -7,7 +7,7 @@ import 'antd/dist/antd.css'; import { useTranslation } from 'react-i18next'; const { Option } = Select -const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu }) => { +const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu, listCompany, role_name, company_id }) => { const [id, setId] = useState(0) const [name, setName] = useState('') const [url, setUrl] = useState('') @@ -15,17 +15,19 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi const [icon, setIcon] = useState('') const [sequence, setSequence] = useState(0) const [parentId, setParentId] = useState(null) + const [selectedCompany, setSelectedCompany] = useState(null) const { t } = useTranslation() useEffect(() => { if (typeDialog === "Edit") { setId(dataEdit.id) - setName(dataEdit.name) + setName(dataEdit.join_first_name) setUrl(dataEdit.url) setIcon(dataEdit.icon) - setParentId(dataEdit.parent_id) + setParentId(dataEdit.parent_menu_id) setSequence(dataEdit.sequence) setAliasName(dataEdit.alias_name) + setSelectedCompany(dataEdit.company_id) } else { setId(0) setName('') @@ -61,12 +63,16 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi const err = validation(); if (!err) { if (typeDialog === "Save") { + if (role_name === 'Super Admin') { + company_id = selectedCompany + } data = { name, url, sequence: parseInt(sequence), icon, alias_name: aliasName, + company_id: company_id } if (parentId && parentId > 0) { @@ -75,6 +81,9 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi closeDialog('save', data); } else { + if (role_name === 'Super Admin') { + company_id = selectedCompany + } data = { id, name, @@ -82,12 +91,12 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi sequence: parseInt(sequence), icon, alias_name: aliasName, + company_id: company_id } if (parentId && parentId > 0) { data['parent_id'] = parentId } - closeDialog('edit', data); } setId(0) @@ -127,6 +136,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi ) } + const onChangeCompany = (val) => { + setSelectedCompany(val); + }; + const renderForm = () => { return (
@@ -135,6 +148,33 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi * Wajib diisi. + {role_name === 'Super Admin' && + + + + + + + + + } diff --git a/src/views/Master/MenuCompany/DialogMasterMenu.js b/src/views/Master/MenuCompany/DialogMasterMenu.js new file mode 100644 index 0000000..c2aef01 --- /dev/null +++ b/src/views/Master/MenuCompany/DialogMasterMenu.js @@ -0,0 +1,418 @@ +import * as XLSX from 'xlsx'; +import DialogForm from './DialogForm.js'; +import React, { useState, useEffect, useMemo } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from 'axios'; +import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; +import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE, MENU_LIST } from '../../../const/ApiConst.js'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { Pagination, Tooltip, Table, Spin } from 'antd'; +import { useTranslation } from 'react-i18next'; +const token = window.localStorage.getItem('token'); +const column = [ + { name: "Nama" }, + { name: "Url" }, + { name: "Ikon" }, + { name: "Alias" }, + { name: "Urutan" }, + { name: "Parent" }, +] + +const Index = ({ params, openDialog, toggleDialog, closeDialog }) => { + const [alertDelete, setAlertDelete] = useState(false) + const [allDataMenu, setAllDataMenu] = useState([]) + 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 [rowsPerPage, setRowsPerPage] = useState(10) + const [search, setSearch] = useState('') + const [tooltipDelete, setTooltipDelete] = useState(false) + const [tooltipEdit, setTooltipEdit] = useState(false) + const [tooltipExport, setTooltipExport] = useState(false) + const [tooltipTambah, setTooltipTambah] = useState(false) + const [totalPage, setTotalPage] = useState(0) + const [typeDialog, setTypeDialog] = useState('Save') + const [loading, SetLoading] = useState(false) + const { t } = useTranslation() + // const pageName = params.name; + + const config = { + headers: + { + Authorization: `Bearer ${token}`, + "Content-type": `application/json` + } + }; + + useEffect(() => { + getDataMenu(); + }, [search, currentPage, rowsPerPage]) + + useEffect(() => { + const cekData = dataExport || [] + if (cekData.length > 0) { + exportExcel() + } + }, [dataExport]) + + const handleSearch = e => { + const value = e.target.value + setSearch(value); + setCurrentPage(1) + }; + + const getDataAllMenu = async () => { + const result = await axios + .get(MENU_LIST, config) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code == 200) { + let arr = [] + let dataRes = result.data.data; + for (const v in dataRes) { + arr.push(dataRes[v]) + } + setAllDataMenu(arr); + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + } + } + + const getDataMenu = async () => { + SetLoading(true) + let start = 0; + + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + const payload = { + "paging": { "start": start, "length": rowsPerPage }, + "columns": [ + { "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } + ], + "joins": [{ + "name": "m_menu", + "column_join": "parent_id", + "column_results": [ + "name" + ] + }], + "orders": { "columns": ["id"], "ascending": false } + } + + const result = await axios + .post(MENU_SEARCH, payload, config) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code == 200) { + setDatatable(result.data.data); + setTotalPage(result.data.totalRecord); + SetLoading(false) + } else { + NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); + SetLoading(false) + } + } + + const handleOpenDialog = async (type) => { + await setTypeDialog(type) + getDataAllMenu(); + // setOpenDialog(true) + } + + const handleCloseDialog = (type, data) => { + if (type === "save") { + saveMenu(data); + } else if (type === "edit") { + editMenu(data); + } + setDataEdit([]) + // setOpenDialog(false) + } + + const toggleAddDialog = () => { + // setOpenDialog(!openDialog) + } + + const handleCancel = () => { + closeDialog('cancel', 'none') + // setDatatable([]); + // setBaseUrl([]); + // setAvailableBaseUrl(false); + // setLoading(false); + } + + + const onConfirmDelete = async () => { + const url = MENU_DELETE(idDelete) + const result = await axios.delete(url, config) + .then(res => res) + .catch((error) => error.response); + if (result && result.data && result.data.code === 200) { + getDataMenu() + setIdDelete(0) + setAlertDelete(false) + NotificationManager.success(`Data menu berhasil dihapus`, 'Success!!'); + } else { + setIdDelete(0) + setAlertDelete(false) + NotificationManager.error(`Data menu gagal dihapus`, 'Failed!!'); + } + } + + const saveMenu = async (data) => { + const formData = data + + const result = await axios.post(MENU_ADD, formData, config) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataMenu(); + getDataAllMenu(); + NotificationManager.success(`Data menu berhasil ditambahkan`, 'Success!!'); + } else { + NotificationManager.error(`Data menu gagal ditambahkan`, 'Failed!!'); + } + + } + + const editMenu = async (data) => { + const formData = data + const url = MENU_EDIT(data.id) + const result = await axios.put(url, formData, config) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code === 200) { + getDataMenu(); + NotificationManager.success(`Data menu berhasil diubah`, 'Success!!'); + } else { + NotificationManager.error(`Data menu gagal diubah`, `Failed!!`); + } + } + + const handleEdit = (data) => { + setDataEdit(data) + handleOpenDialog('Edit'); + } + + const handleDelete = async (id) => { + await setAlertDelete(true) + await setIdDelete(id) + } + + const onShowSizeChange = (current, pageSize) => { + setRowsPerPage(pageSize) + } + + const onPagination = (current, pageSize) => { + setCurrentPage(current) + } + + const toggle = (param) => { + if (param === "edit") { + setTooltipEdit(!tooltipEdit) + } else if (param === "delete") { + setTooltipDelete(!tooltipDelete) + } else if (param === "tambah") { + setTooltipTambah(!tooltipTambah) + } else if (param === "export") { + setTooltipExport(!tooltipExport) + } + } + + const handleExportExcel = async () => { + const payload = { + "paging": { "start": 0, "length": -1 }, + "columns": [ + { "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } + ], + "joins": [{ + "name": "m_menu", + "column_join": "parent_id", + "column_results": [ + "name" + ] + }], + "orders": { "columns": ["id"], "ascending": false } + } + + const result = await axios + .post(MENU_SEARCH, payload, config) + .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, + "Url": val.url, + "Icon": val.icon, + "Alias Name": val.alias_name, + "Urutan": val.sequence, + "Parent Name": val.join_first_name ? val.join_first_name : "-" + } + excelData.push(dataRow) + }) + await setDataExport(excelData); + } else { + NotificationManager.error('Gagal Export Data!!', 'Failed'); + } + } + + const exportExcel = () => { + const dataExcel = dataExport || []; + const fileName = `Data Master Menu.xlsx`; + const ws = XLSX.utils.json_to_sheet(dataExcel); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, `Data Master Menu`); + XLSX.writeFile(wb, fileName); + setDataExport([]) + } + + const cancelDelete = () => { + setAlertDelete(false) + setIdDelete(0) + } + + const renderTable = useMemo(() => { + const columns = [ + { + title: t('action'), + dataIndex: '', + key: 'x', + render: (text, record) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + + , + }, + { title: t('name'), dataIndex: 'name', key: 'name' }, + { title: 'Url', dataIndex: 'url', key: 'url' }, + { title: t('icon'), dataIndex: 'icon', key: 'icon' }, + { title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' }, + { title: t('order'), dataIndex: 'sequence', key: 'sequence' }, + { title: t('parentMenu'), dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") } + ]; + return ( + + ) + }, [dataTable]) + + return ( +
+ + cancelDelete()} + focusCancelBtn + > + {t('deleteMsg')} + + {/* toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + dataMenu={allDataMenu} + /> */} + + + MASTER MENU +
+ + + + + + +
+
+ + <> + + {renderTable} + + + + + + + {/* {typeDialog !== "Set" && typeDialog !== "Set-Menu" && ( + + )} */} + + +
+ {/* + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + */} + + ) +} + +export default Index; diff --git a/src/views/Master/MasterMenu/index.js b/src/views/Master/MenuCompany/index.js similarity index 77% rename from src/views/Master/MasterMenu/index.js rename to src/views/Master/MenuCompany/index.js index 88919c4..8b177cc 100644 --- a/src/views/Master/MasterMenu/index.js +++ b/src/views/Master/MenuCompany/index.js @@ -1,11 +1,12 @@ import * as XLSX from 'xlsx'; import DialogForm from './DialogForm'; +import DialogMasterMenu from './DialogMasterMenu.js' import React, { useState, useEffect, useMemo } from 'react'; import SweetAlert from 'react-bootstrap-sweetalert'; import axios from 'axios'; import { Button } from 'reactstrap'; import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; -import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE, MENU_LIST } from '../../../const/ApiConst.js'; +import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE, MENU_LIST, MENU_COMPANY_SEARCH, COMPANY_MANAGEMENT_LIST } from '../../../const/ApiConst.js'; import { NotificationContainer, NotificationManager } from 'react-notifications'; import { Pagination, Tooltip, Table } from 'antd'; import { useTranslation } from 'react-i18next'; @@ -19,7 +20,20 @@ const column = [ { name: "Parent" }, ] -const Index = ({ params }) => { +const Index = ({ params, ...props }) => { + let role_id = 0, user_id = 0, isLogin = false, token = '', company_id = 0, all_project = null, role_name = '', hierarchy = [], user_name = ''; + if (props && props.role_id && props.user_id) { + role_id = props.role_id; + user_id = props.user_id; + token = props.token; + isLogin = props.isLogin; + company_id = props.company_id; + all_project = props.all_project; + role_name = props.role_name; + isLogin = props.isLogin; + hierarchy = props.hierarchy; + user_name = props.user_name; + } const [alertDelete, setAlertDelete] = useState(false) const [allDataMenu, setAllDataMenu] = useState([]) const [clickOpenModal, setClickOpenModal] = useState(false) @@ -29,6 +43,7 @@ const Index = ({ params }) => { const [dataTable, setDatatable] = useState([]) const [idDelete, setIdDelete] = useState(0) const [openDialog, setOpenDialog] = useState(false) + const [openDialogMasterMenu, setOpenDialogMasterMenu] = useState(false) const [rowsPerPage, setRowsPerPage] = useState(10) const [search, setSearch] = useState('') const [tooltipDelete, setTooltipDelete] = useState(false) @@ -37,6 +52,7 @@ const Index = ({ params }) => { const [tooltipTambah, setTooltipTambah] = useState(false) const [totalPage, setTotalPage] = useState(0) const [typeDialog, setTypeDialog] = useState('Save') + const [listCompany, setListCompany] = useState([]) const { t } = useTranslation() const pageName = params.name; @@ -59,6 +75,21 @@ const Index = ({ params }) => { } }, [dataExport]) + useEffect(() => { + getDataCompany() + }, []) + + const getDataCompany = async () => { + const result = await axios + .get(COMPANY_MANAGEMENT_LIST, config) + .then(res => res) + .catch((error) => error.response); + + if (result && result.data && result.data.code == 200) { + setListCompany(result.data.data); + } + } + const handleSearch = e => { const value = e.target.value setSearch(value); @@ -93,11 +124,11 @@ const Index = ({ params }) => { const payload = { "paging": { "start": start, "length": rowsPerPage }, "columns": [ - { "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } + { "name": "alias_name", "logic_operator": "ilike", "value": search, "operator": "AND" } ], "joins": [{ "name": "m_menu", - "column_join": "parent_id", + "column_join": "menu_id", "column_results": [ "name" ] @@ -105,8 +136,24 @@ const Index = ({ params }) => { "orders": { "columns": ["id"], "ascending": false } } + 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" }, + ) + payload.joins.push( + { name: "m_company", column_join: "company_id", column_results: ["company_name"] } + ) + payload.columns.push( + { name: "company_name", logic_operator: "~*", value: search, table_name: "m_company" } + ) + } + const result = await axios - .post(MENU_SEARCH, payload, config) + .post(MENU_COMPANY_SEARCH, payload, config) .then(res => res) .catch((error) => error.response); @@ -123,6 +170,18 @@ const Index = ({ params }) => { getDataAllMenu(); setOpenDialog(true) } + const handleOpenDialogMasterMenu = async () => { + setOpenDialogMasterMenu(true) + } + + const handleCloseDialogMasterMenu = () => { + setOpenDialogMasterMenu(false) + } + + const toggleDialogMasterMenu = () => { + setOpenDialogMasterMenu(!openDialog) + } + const handleCloseDialog = (type, data) => { if (type === "save") { @@ -288,7 +347,10 @@ const Index = ({ params }) => { , }, - { title: t('name'), dataIndex: 'name', key: 'name' }, + ...(role_name === 'Super Admin' ? + [{ title: t('company'), dataIndex: 'join_second_company_name', key: 'join_second_company_name' }] + : []), + { title: t('name'), dataIndex: 'join_first_name', key: 'join_first_name' }, { title: 'Url', dataIndex: 'url', key: 'url' }, { title: t('icon'), dataIndex: 'icon', key: 'icon' }, { title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' }, @@ -330,6 +392,14 @@ const Index = ({ params }) => { dataEdit={dataEdit} clickOpenModal={clickOpenModal} dataMenu={allDataMenu} + listCompany={listCompany} + role_name={role_name} + company_id={company_id} + /> + toggleDialogMasterMenu} /> @@ -339,8 +409,13 @@ const Index = ({ params }) => { + {role_name === 'Super Admin' && + + + + } - +