724 lines
21 KiB
JavaScript
724 lines
21 KiB
JavaScript
|
|
import React, { useState, useEffect } from "react";
|
||
|
|
import { Button, Dropdown, Modal, Form,Row,Col,InputGroup,
|
||
|
|
FormControl,
|
||
|
|
} from "react-bootstrap";
|
||
|
|
import { Table ,Pagination,
|
||
|
|
PaginationItem,
|
||
|
|
PaginationLink,Input,Label} from 'reactstrap';
|
||
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||
|
|
import { faEdit, faTrashAlt, faPlus, faBars,
|
||
|
|
faTimes } from "@fortawesome/free-solid-svg-icons";
|
||
|
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||
|
|
import "../Dashboard/CSS/CSS/CommonStyle.css";
|
||
|
|
import { FaSearch, FaTimes } from "react-icons/fa";
|
||
|
|
import { BsJournals } from "react-icons/bs";
|
||
|
|
import Spinner from '../../UIComponants/Spinner';
|
||
|
|
import { getByUsrGrpId } from "APIServices/MenuAccessControlAPI";
|
||
|
|
import { toast } from "react-toastify";
|
||
|
|
|
||
|
|
function MenuAccessControl({ selected,Sync}) {
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [menuItems, setMenuItems] = useState([]);
|
||
|
|
const [menus,setMenus] = useState([]);
|
||
|
|
const [showAddEditModal, setShowAddEditModal] = useState(false);
|
||
|
|
const [selectedMenuId, setSelectedMenuId] = useState(null);
|
||
|
|
const [usrgrp, setUsrgrp] = useState('DefaultGroup');
|
||
|
|
const [allData, setAllData] = useState([]);
|
||
|
|
|
||
|
|
|
||
|
|
const [currentMenuItem, setCurrentMenuItem] = useState({
|
||
|
|
menuId: "",
|
||
|
|
menuItemName: "",
|
||
|
|
accessLevel: "",
|
||
|
|
isActive: false,
|
||
|
|
view: false, // For View checkbox
|
||
|
|
create: false, // For Create checkbox
|
||
|
|
edit: false, // For Edit checkbox
|
||
|
|
delete: false, // For Delete checkbox
|
||
|
|
query: false, // For Query checkbox
|
||
|
|
export: false, // For Export checkbox
|
||
|
|
});
|
||
|
|
const [alldata, setAlldata] = useState([]);
|
||
|
|
// const [slicedMenus, setSlicedMenus] = useState([]);
|
||
|
|
const [toggle, setToggle] = useState(false);
|
||
|
|
const [currentPage, setCurrentPage] = useState(1);
|
||
|
|
const [isEditing, setIsEditing] = useState(false);
|
||
|
|
const [recordsPerPage, setRecordsPerPage] = useState(10);
|
||
|
|
const [searchQuery, setSearchQuery] = useState("");
|
||
|
|
let [slicedMenus, setSlicedMenus] = useState([
|
||
|
|
{
|
||
|
|
menuId: 1,
|
||
|
|
view: false,
|
||
|
|
create: false,
|
||
|
|
edit: false,
|
||
|
|
delete: false,
|
||
|
|
query: false,
|
||
|
|
export: false,
|
||
|
|
isActive: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
menuId: 2,
|
||
|
|
view: false,
|
||
|
|
create: false,
|
||
|
|
edit: false,
|
||
|
|
delete: false,
|
||
|
|
query: false,
|
||
|
|
export: false,
|
||
|
|
isActive: false,
|
||
|
|
},
|
||
|
|
]);
|
||
|
|
const [visibleColumns, setVisibleColumns] = useState({
|
||
|
|
No:true,
|
||
|
|
menuId: true,
|
||
|
|
menuItemName: true,
|
||
|
|
view:true,
|
||
|
|
create:true,
|
||
|
|
edit:true,
|
||
|
|
delete:true,
|
||
|
|
query:true,
|
||
|
|
export:true,
|
||
|
|
isActive: true,
|
||
|
|
actions: true
|
||
|
|
});
|
||
|
|
|
||
|
|
const [newItemData, setNewItemData] = useState({
|
||
|
|
|
||
|
|
menuId: "",
|
||
|
|
menuItemName: "",
|
||
|
|
view:"",
|
||
|
|
create:"",
|
||
|
|
edit:"",
|
||
|
|
delete:"",
|
||
|
|
query:"",
|
||
|
|
export:"",
|
||
|
|
isActive: true,
|
||
|
|
});
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
// Simulate loading data
|
||
|
|
setTimeout(() => {
|
||
|
|
setLoading(false);
|
||
|
|
}, 3000); // Simulated 3 seconds loading
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
// Simulate fetching or setting a default value
|
||
|
|
// const defaultGroup = 'Admin'; // Replace with fetched or derived value
|
||
|
|
setUsrgrp();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const apiUrl = `${process.env.REACT_APP_API_URL}/api/getAllMenuItems`;
|
||
|
|
const token = localStorage.getItem("authToken");
|
||
|
|
const fetchMenuItems = async () => {
|
||
|
|
try {
|
||
|
|
const response = await fetch(apiUrl, {
|
||
|
|
method: "GET",
|
||
|
|
headers: {
|
||
|
|
"Content-Type": "application/json",
|
||
|
|
Authorization: `Bearer ${token}`,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const data = await response.json();
|
||
|
|
setMenuItems(data);
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Error fetching menu items:", error);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
fetchMenuItems();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
fetchData();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
// const fetchData = async () => {
|
||
|
|
// try {
|
||
|
|
// const data = await getByUsrGrpId(usrgrp);
|
||
|
|
// console.log("Data fetched successfully:", data);
|
||
|
|
|
||
|
|
// setAlldata(data); // Update the state with fetched data
|
||
|
|
// toast.success("Data fetched successfully!");
|
||
|
|
// } catch (error) {
|
||
|
|
// console.error('Error fetching data:', error);
|
||
|
|
// toast.error("Failed to fetch data.");
|
||
|
|
// }
|
||
|
|
// };
|
||
|
|
|
||
|
|
// const fetchData = async () => {
|
||
|
|
// try {
|
||
|
|
// console.log("Fetching data for usrgrp:", usrgrp);
|
||
|
|
// const data = await getByUsrGrpId(usrgrp);
|
||
|
|
// if (!data) {
|
||
|
|
// console.error("Received undefined data");
|
||
|
|
// toast.error("Failed to fetch data.");
|
||
|
|
// return;
|
||
|
|
// }
|
||
|
|
// console.log("Data fetched successfully:", data);
|
||
|
|
// setAlldata(data);
|
||
|
|
// toast.success("Data fetched successfully!");
|
||
|
|
// } catch (error) {
|
||
|
|
// console.error("Error fetching data:", error);
|
||
|
|
// toast.error("Failed to fetch data.");
|
||
|
|
// }
|
||
|
|
// };
|
||
|
|
|
||
|
|
const fetchData = async () => {
|
||
|
|
try {
|
||
|
|
console.log("Fetching data for usrgrp:", usrgrp);
|
||
|
|
const data = await getByUsrGrpId(usrgrp);
|
||
|
|
if (!data) {
|
||
|
|
console.error("Received undefined data");
|
||
|
|
toast.error("Failed to fetch data.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
console.log("Data fetched successfully:", data);
|
||
|
|
setAlldata(data);
|
||
|
|
toast.success("Data fetched successfully!");
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Error fetching data:", error.message || error);
|
||
|
|
toast.error("Failed to fetch data.");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
const idselected = (value) => {
|
||
|
|
setSelectedMenuId(value);
|
||
|
|
};
|
||
|
|
|
||
|
|
const toggleColumn = (column) => {
|
||
|
|
setVisibleColumns((prev) => ({
|
||
|
|
...prev,
|
||
|
|
[column]: !prev[column],
|
||
|
|
}));
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleInputChange = (event,menuId) => {
|
||
|
|
const { name, value, checked, type } = event.target;
|
||
|
|
setCurrentMenuItem(prev => ({
|
||
|
|
...prev,
|
||
|
|
[name]: type === "checkbox" ? checked : value
|
||
|
|
}));
|
||
|
|
setSlicedMenus((prevMenus) =>
|
||
|
|
prevMenus.map((menu) =>
|
||
|
|
menu.menuId === currentMenuItem.menuId // Identify the correct menu item
|
||
|
|
? { ...menu, [name]: value } // Update the specific field
|
||
|
|
: menu
|
||
|
|
)
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleSearch = (query) => {
|
||
|
|
setSearchQuery(query);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleAddItem = () => {
|
||
|
|
setIsEditing(false);
|
||
|
|
setNewItemData({
|
||
|
|
menuId: "",
|
||
|
|
menuItemName: "",
|
||
|
|
isActive: true,
|
||
|
|
});
|
||
|
|
setShowAddEditModal(true)
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleClose = () => {
|
||
|
|
setShowAddEditModal(false); // Close the modal by setting the state to false
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
const handleSubmit = (event) => {
|
||
|
|
event.preventDefault();
|
||
|
|
if (isEditing) {
|
||
|
|
setMenuItems(menuItems.map(item =>
|
||
|
|
item.menuId === currentMenuItem.menuId ? currentMenuItem : item
|
||
|
|
));
|
||
|
|
} else {
|
||
|
|
const newMenuId = `ID${menuItems.length + 1}`;
|
||
|
|
setMenuItems([...menuItems, { ...currentMenuItem, menuId: newMenuId }]);
|
||
|
|
}
|
||
|
|
setShowAddEditModal(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
const openModal = (item = { menuId: "", menuName: "", accessLevel: "", isActive: false }) => {
|
||
|
|
setIsEditing(!!item.menuId);
|
||
|
|
setCurrentMenuItem(item);
|
||
|
|
setShowAddEditModal(true);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleDelete = (menuId) => {
|
||
|
|
setMenuItems(menuItems.filter(item => item.menuId !== menuId));
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleRecordsPerPageChange=(number) =>{
|
||
|
|
setRecordsPerPage(number);
|
||
|
|
setCurrentPage(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
const totalPages = Math.ceil(menuItems.length / recordsPerPage);
|
||
|
|
const handlePageChange = (pageNumber) => {
|
||
|
|
setCurrentPage(pageNumber);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleSelectChange = (value) => {
|
||
|
|
console.log(value);
|
||
|
|
setUsrgrp(value);
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleToggleCheckbox = () => {
|
||
|
|
setToggle(!toggle);
|
||
|
|
};
|
||
|
|
|
||
|
|
slicedMenus = menuItems
|
||
|
|
.filter((item) =>
|
||
|
|
item.menuName && item.menuName.toLowerCase().includes(searchQuery.toLowerCase())
|
||
|
|
)
|
||
|
|
.slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage);
|
||
|
|
return (
|
||
|
|
<div style={{marginTop:"11rem"}}>
|
||
|
|
{loading ? (
|
||
|
|
<Spinner/>
|
||
|
|
):(
|
||
|
|
<div className="container-fluid mt-5">
|
||
|
|
<div
|
||
|
|
className="d-flex justify-content-between align-items-center mb-4"
|
||
|
|
style={{ gap: "15px" }}
|
||
|
|
>
|
||
|
|
{/* Left Side */}
|
||
|
|
<div className="d-flex align-items-center" style={{ gap: "15px" }}>
|
||
|
|
<h1 className="title_main mb-0">Menu Access Control</h1>
|
||
|
|
<span
|
||
|
|
className="badge bg-info text-white"
|
||
|
|
style={{ fontSize: "14px", padding: "5px 10px", lineHeight: "1" }}
|
||
|
|
>
|
||
|
|
Edit Mode
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Right Side */}
|
||
|
|
<div className="d-flex align-items-center" style={{ gap: "15px" }}>
|
||
|
|
<span>For</span>
|
||
|
|
<select
|
||
|
|
className="form-select"
|
||
|
|
style={{ width: "150px", height: "40px" }}
|
||
|
|
onChange={(e) => handleSelectChange(e.target.value)}
|
||
|
|
>
|
||
|
|
{alldata.map((sub) => (
|
||
|
|
<option
|
||
|
|
key={sub.usrGrp}
|
||
|
|
value={sub.usrGrp}
|
||
|
|
selected={sub.usrGrp === 40}
|
||
|
|
>
|
||
|
|
{sub.groupName}
|
||
|
|
</option>
|
||
|
|
))}
|
||
|
|
</select>
|
||
|
|
<Button
|
||
|
|
variant="primary"
|
||
|
|
className="ml-3"
|
||
|
|
style={{ height: "40px", lineHeight: "1.2" }}
|
||
|
|
onClick={() => fetchData()}
|
||
|
|
>
|
||
|
|
Reload
|
||
|
|
</Button>
|
||
|
|
<span style={{ fontWeight: "500" }}>
|
||
|
|
{toggle ? "Only Main Menu" : "Show All"}
|
||
|
|
</span>
|
||
|
|
|
||
|
|
<div className="form-check form-switch">
|
||
|
|
<input
|
||
|
|
className="form-check-input"
|
||
|
|
type="checkbox"
|
||
|
|
id="toggleSwitch"
|
||
|
|
checked={toggle}
|
||
|
|
onChange={handleToggleCheckbox}
|
||
|
|
/>
|
||
|
|
<label className="form-check-label" htmlFor="toggleSwitch">
|
||
|
|
Toggle
|
||
|
|
</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<Row className="align-items-center my-3">
|
||
|
|
{/* Left: Search Bar */}
|
||
|
|
<Col
|
||
|
|
xs={12}
|
||
|
|
md={8}
|
||
|
|
lg={6}
|
||
|
|
className="d-flex justify-content-center my-3"
|
||
|
|
>
|
||
|
|
<InputGroup
|
||
|
|
className="search-bar"
|
||
|
|
style={{
|
||
|
|
borderRadius: "10px",
|
||
|
|
overflow: "hidden",
|
||
|
|
boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)",
|
||
|
|
width: "100%",
|
||
|
|
maxWidth: "528px", // Set max-width to limit overall width
|
||
|
|
paddingRight: "-15px", // Increase padding on the right side
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<InputGroup.Text
|
||
|
|
style={{
|
||
|
|
backgroundColor: "#0E6591",
|
||
|
|
color: "#fff",
|
||
|
|
padding: "10px 15px",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<FaSearch />
|
||
|
|
</InputGroup.Text>
|
||
|
|
<FormControl
|
||
|
|
placeholder="Search"
|
||
|
|
value={searchQuery}
|
||
|
|
onChange={(e) => handleSearch(e.target.value)}
|
||
|
|
style={{
|
||
|
|
padding: "10px",
|
||
|
|
border: "none",
|
||
|
|
paddingRight: "5px", // More space on the right side of input field
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</InputGroup>
|
||
|
|
</Col>
|
||
|
|
|
||
|
|
{/*Add Icons */}
|
||
|
|
<Col xs={12} md={4} lg={6} className="d-flex justify-content-end">
|
||
|
|
<>
|
||
|
|
{/* Add Icon */}
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faPlus}
|
||
|
|
onClick={() => handleAddItem(true)}
|
||
|
|
style={{
|
||
|
|
cursor: "pointer",
|
||
|
|
fontSize: "1.5rem",
|
||
|
|
color: "#747264",
|
||
|
|
marginRight: "20px",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faBars}
|
||
|
|
style={{
|
||
|
|
cursor: "pointer",
|
||
|
|
fontSize: "1.5rem",
|
||
|
|
color: "#747264",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</>
|
||
|
|
</Col>
|
||
|
|
</Row>
|
||
|
|
|
||
|
|
<div className="table-responsive">
|
||
|
|
<Table striped responsive hover align="middle" className=" table-flush shadow-sm">
|
||
|
|
<thead className="custom_header">
|
||
|
|
<tr>
|
||
|
|
{Object.entries(visibleColumns).map(([key, visible]) =>
|
||
|
|
visible ? <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th> : null
|
||
|
|
)}
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody className="tbody">
|
||
|
|
{slicedMenus.length === 0 ? (
|
||
|
|
<tr>
|
||
|
|
<td
|
||
|
|
colSpan={
|
||
|
|
Object.keys(visibleColumns).filter((key) => visibleColumns[key])
|
||
|
|
.length
|
||
|
|
}
|
||
|
|
className="text-center"
|
||
|
|
>
|
||
|
|
No items found. Please add new items.
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
) : (
|
||
|
|
slicedMenus.map((item, index) => (
|
||
|
|
<tr key={index}>
|
||
|
|
{Object.entries(visibleColumns).map(([key, visible]) =>
|
||
|
|
visible ? (
|
||
|
|
<td key={key}>
|
||
|
|
{key === "actions" ? (
|
||
|
|
<>
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faEdit}
|
||
|
|
onClick={() => openModal(item)}
|
||
|
|
style={{
|
||
|
|
cursor: "pointer",
|
||
|
|
fontSize: "1rem",
|
||
|
|
color: "green",
|
||
|
|
marginRight: "15px",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faTrashAlt}
|
||
|
|
onClick={() => handleDelete(item.menuId)}
|
||
|
|
style={{
|
||
|
|
cursor: "pointer",
|
||
|
|
fontSize: "1rem",
|
||
|
|
color: "#dc3545",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</>
|
||
|
|
) :["view", "create", "edit", "delete", "query", "export"].includes(key) ? (
|
||
|
|
<Input
|
||
|
|
type="checkbox"
|
||
|
|
checked={item[key]}
|
||
|
|
// onChange={(e) =>
|
||
|
|
// handleInputChange({
|
||
|
|
// target: {
|
||
|
|
// name: key,
|
||
|
|
// value: e.target.checked,
|
||
|
|
// },
|
||
|
|
// })
|
||
|
|
onChange={(e) => handleInputChange(e, item.menuId)}
|
||
|
|
disabled={false}
|
||
|
|
/>
|
||
|
|
): key === "isActive" ? (
|
||
|
|
<span
|
||
|
|
className="status"
|
||
|
|
style={{
|
||
|
|
color: item.isActive ? "green" : "red",
|
||
|
|
backgroundColor: item.isActive
|
||
|
|
? "#d4f7d4"
|
||
|
|
: "#f7d4d4",
|
||
|
|
padding: "4px 8px",
|
||
|
|
borderRadius: "4px",
|
||
|
|
display: "inline-block",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{item.isActive ? "Active" : "Inactive"}
|
||
|
|
</span>
|
||
|
|
) : (
|
||
|
|
item[key]
|
||
|
|
)}
|
||
|
|
</td>
|
||
|
|
) : null
|
||
|
|
)}
|
||
|
|
</tr>
|
||
|
|
))
|
||
|
|
)}
|
||
|
|
</tbody>
|
||
|
|
</Table>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Manage Columns & Records Per Page */}
|
||
|
|
<Row className="mt-4">
|
||
|
|
<Col md={6} className="d-flex justify-content-start">
|
||
|
|
<Dropdown>
|
||
|
|
<Dropdown.Toggle
|
||
|
|
variant="outline-primary"
|
||
|
|
className="custom_manage_column_button"
|
||
|
|
>
|
||
|
|
Manage Columns
|
||
|
|
</Dropdown.Toggle>
|
||
|
|
<Dropdown.Menu>
|
||
|
|
{Object.keys(visibleColumns).map((column) => (
|
||
|
|
<Dropdown.Item
|
||
|
|
key={column}
|
||
|
|
onClick={() => toggleColumn(column)}
|
||
|
|
>
|
||
|
|
<Form.Check
|
||
|
|
type="checkbox"
|
||
|
|
label={
|
||
|
|
column.charAt(0).toUpperCase() +
|
||
|
|
column.slice(1).toLowerCase()
|
||
|
|
}
|
||
|
|
checked={visibleColumns[column]}
|
||
|
|
readOnly
|
||
|
|
className="custom-checkbox"
|
||
|
|
/>
|
||
|
|
</Dropdown.Item>
|
||
|
|
))}
|
||
|
|
</Dropdown.Menu>
|
||
|
|
</Dropdown>
|
||
|
|
</Col>
|
||
|
|
|
||
|
|
<Col md={6} className="d-flex justify-content-end">
|
||
|
|
<Dropdown>
|
||
|
|
<Dropdown.Toggle
|
||
|
|
variant="outline-primary"
|
||
|
|
className="custom_manage_column_button px-4 py-2 border-2 rounded-3 shadow-sm"
|
||
|
|
id="dropdown-custom-components"
|
||
|
|
>
|
||
|
|
<BsJournals />
|
||
|
|
</Dropdown.Toggle>
|
||
|
|
<Dropdown.Menu className="border-0 rounded-3 shadow-lg" align="end">
|
||
|
|
{[1, 5, 10, 20, 50].map((number) => (
|
||
|
|
<Dropdown.Item
|
||
|
|
key={number}
|
||
|
|
onClick={() => handleRecordsPerPageChange(number)}
|
||
|
|
className="text-dark d-flex justify-content-between align-items-center"
|
||
|
|
>
|
||
|
|
<span>{number}</span>
|
||
|
|
<i
|
||
|
|
className="fa fa-check-circle"
|
||
|
|
style={{
|
||
|
|
display: recordsPerPage === number ? "inline" : "none",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</Dropdown.Item>
|
||
|
|
))}
|
||
|
|
</Dropdown.Menu>
|
||
|
|
</Dropdown>
|
||
|
|
</Col>
|
||
|
|
</Row>
|
||
|
|
|
||
|
|
<Pagination className="pagination">
|
||
|
|
<PaginationItem disabled={currentPage === 1}>
|
||
|
|
<PaginationLink previous onClick={() => handlePageChange(currentPage - 1)} />
|
||
|
|
</PaginationItem>
|
||
|
|
{[...Array(totalPages)].map((_, index) => (
|
||
|
|
<PaginationItem key={index} active={index + 1 === currentPage}>
|
||
|
|
<PaginationLink onClick={() => handlePageChange(index + 1)} style={{ color: '#0b6592' }}>
|
||
|
|
{index + 1}
|
||
|
|
</PaginationLink>
|
||
|
|
</PaginationItem>
|
||
|
|
))}
|
||
|
|
<PaginationItem disabled={currentPage === totalPages}>
|
||
|
|
<PaginationLink next onClick={() => handlePageChange(currentPage + 1)} />
|
||
|
|
</PaginationItem>
|
||
|
|
</Pagination>
|
||
|
|
|
||
|
|
{/* Add/Edit Model */}
|
||
|
|
|
||
|
|
{/* <Modal show={showAddEditModal} onHide={() => setShowAddEditModal(false)}>
|
||
|
|
<Modal.Header >
|
||
|
|
<Modal.Title>{isEditing ? "Edit Menu Access" : "Add Menu Access"}</Modal.Title>
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faTimes}
|
||
|
|
size="lg"
|
||
|
|
onClick={handleClose}
|
||
|
|
style={{
|
||
|
|
position: "absolute",
|
||
|
|
top: "25px",
|
||
|
|
right: "25px",
|
||
|
|
cursor: "pointer",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</Modal.Header>
|
||
|
|
<Modal.Body>
|
||
|
|
<Form onSubmit={handleSubmit}>
|
||
|
|
<Form.Group controlId="formMenuName">
|
||
|
|
<Form.Label>Menu Name</Form.Label>
|
||
|
|
<Form.Control
|
||
|
|
type="text"
|
||
|
|
name="menuName"
|
||
|
|
value={currentMenuItem.menuName}
|
||
|
|
onChange={handleInputChange}
|
||
|
|
required
|
||
|
|
className="custom-hover-border"
|
||
|
|
/>
|
||
|
|
</Form.Group>
|
||
|
|
<Form.Group>
|
||
|
|
<Label for="name">Menu Name<span className="required-field">*</span></Label>
|
||
|
|
<Input type="select" style={{ width: '100%', padding: '5px', border: '1px solid #ccc', borderRadius: '4px' }} onChange={(e) => idselected(e.target.value)}>
|
||
|
|
{menus.map((sub) => (
|
||
|
|
<option key={sub.menuItemId} value={sub.menuItemId}>{sub.menuItemDesc}</option>
|
||
|
|
))}
|
||
|
|
</Input>
|
||
|
|
</Form.Group>
|
||
|
|
<Form.Group controlId="formActive">
|
||
|
|
<Form.Check
|
||
|
|
type="checkbox"
|
||
|
|
label="Active?"
|
||
|
|
name="isActive"
|
||
|
|
checked={currentMenuItem.isActive}
|
||
|
|
onChange={handleInputChange}
|
||
|
|
className="custom-checkbox"
|
||
|
|
/>
|
||
|
|
</Form.Group>
|
||
|
|
<Modal.Footer>
|
||
|
|
|
||
|
|
<Button variant="primary" type="submit" className="custom_button px-4">{isEditing ? "Update" : "Add"}</Button>
|
||
|
|
<Button variant="secondary" onClick={handleClose} className="custom_button px-4">
|
||
|
|
Cancel
|
||
|
|
</Button>
|
||
|
|
</Modal.Footer>
|
||
|
|
</Form>
|
||
|
|
</Modal.Body>
|
||
|
|
</Modal> */}
|
||
|
|
|
||
|
|
<Modal show={showAddEditModal} onHide={() => setShowAddEditModal(false)}>
|
||
|
|
<Modal.Header>
|
||
|
|
<Modal.Title>{isEditing ? "Edit Menu Access" : "Add Menu Access"}</Modal.Title>
|
||
|
|
<FontAwesomeIcon
|
||
|
|
icon={faTimes}
|
||
|
|
size="lg"
|
||
|
|
onClick={handleClose}
|
||
|
|
style={{
|
||
|
|
position: "absolute",
|
||
|
|
top: "25px",
|
||
|
|
right: "25px",
|
||
|
|
cursor: "pointer",
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</Modal.Header>
|
||
|
|
<Modal.Body>
|
||
|
|
<Form onSubmit={handleSubmit}>
|
||
|
|
{/* Menu Name Input */}
|
||
|
|
<Form.Group controlId="formMenuName">
|
||
|
|
<Form.Label>Menu Items Name</Form.Label>
|
||
|
|
<Form.Control
|
||
|
|
type="text"
|
||
|
|
name="menuName"
|
||
|
|
value={currentMenuItem.menuName}
|
||
|
|
onChange={handleInputChange}
|
||
|
|
required
|
||
|
|
className="custom-hover-border"
|
||
|
|
/>
|
||
|
|
</Form.Group>
|
||
|
|
|
||
|
|
{/* Select Menu Item */}
|
||
|
|
<Form.Group>
|
||
|
|
<Label for="name">Menu Item<span className="required-field">*</span></Label>
|
||
|
|
<Input
|
||
|
|
type="select"
|
||
|
|
style={{ width: '100%', padding: '5px', border: '1px solid #ccc', borderRadius: '4px' }}
|
||
|
|
onChange={(e) => idselected(e.target.value)}
|
||
|
|
>
|
||
|
|
{menus.map((sub) => (
|
||
|
|
<option key={sub.menuItemId} value={sub.menuItemId}>
|
||
|
|
{sub.menuItemDesc}
|
||
|
|
</option>
|
||
|
|
))}
|
||
|
|
</Input>
|
||
|
|
</Form.Group>
|
||
|
|
|
||
|
|
{/* Active Checkbox */}
|
||
|
|
<Form.Group controlId="formActive">
|
||
|
|
<Form.Check
|
||
|
|
type="checkbox"
|
||
|
|
label="Active?"
|
||
|
|
name="isActive"
|
||
|
|
checked={currentMenuItem.isActive}
|
||
|
|
onChange={handleInputChange}
|
||
|
|
className="custom-checkbox"
|
||
|
|
/>
|
||
|
|
</Form.Group>
|
||
|
|
|
||
|
|
{/* Modal Footer with buttons */}
|
||
|
|
<Modal.Footer>
|
||
|
|
<Button variant="primary" type="submit" className="custom_button px-4">
|
||
|
|
{isEditing ? "Update" : "Add"}
|
||
|
|
</Button>
|
||
|
|
<Button variant="secondary" onClick={handleClose} className="custom_button px-4">
|
||
|
|
Cancel
|
||
|
|
</Button>
|
||
|
|
</Modal.Footer>
|
||
|
|
</Form>
|
||
|
|
</Modal.Body>
|
||
|
|
</Modal>
|
||
|
|
|
||
|
|
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export default MenuAccessControl;
|