first commit
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate, useParams,useLocation } from 'react-router-dom';
|
||||
import {toast} from 'react-toastify'; // You can use a different notification system if needed
|
||||
import DashboardBuilderService from "../../../../APIServices/DashboardBuilderService"; // Update with your service path
|
||||
import { Badge } from "reactstrap";
|
||||
|
||||
const EditFormNewDash = () => {
|
||||
const { id } = useParams(); // Access the id from the URL params
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [header, setHeader] = useState({
|
||||
dashboard_name: '',
|
||||
secuirity_profile: '',
|
||||
description: '',
|
||||
add_to_home: false,
|
||||
});
|
||||
const [updated, setUpdated] = useState(false);
|
||||
const [techStacks, setTechStacks] = useState([]);
|
||||
const objectTypes = ["form", "bi", "report", "api"];
|
||||
const subObjectTypes = [
|
||||
"only header",
|
||||
"only line",
|
||||
"header line",
|
||||
"header multiline",
|
||||
"workflow",
|
||||
"setup",
|
||||
"std report",
|
||||
"bi report",
|
||||
"rest api",
|
||||
];
|
||||
|
||||
// Fetch data by ID when component mounts
|
||||
// useEffect(() => {
|
||||
// if (id) {
|
||||
// getById(id);
|
||||
// }
|
||||
// }, [id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.dashboard) {
|
||||
setHeader(location.state.dashboard);
|
||||
} else {
|
||||
// Fetch data if not passed in state
|
||||
getById(id);
|
||||
}
|
||||
}, [id, location.state]);
|
||||
|
||||
// Get dashboard data by ID
|
||||
// const getById = (id) => {
|
||||
// DashboardService.getById(id)
|
||||
// .then((data) => {
|
||||
// console.log(data);
|
||||
// setHeader(data);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
||||
// };
|
||||
|
||||
const getById = (id,data) => {
|
||||
|
||||
DashboardBuilderService.getById(id)
|
||||
.then((data) => {
|
||||
console.log("get dashbord by id: ",data);
|
||||
setHeader(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
// Static error handling
|
||||
console.error("Error fetching dashboard by ID:", err);
|
||||
toast.error('Failed to fetch dashboard data. Please try again later.');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const handleInputChange = (e) => {
|
||||
const { name, value, type, checked } = e.target;
|
||||
setHeader((prev) => ({
|
||||
...prev,
|
||||
...header,
|
||||
[name]: type === 'checkbox' ? checked : value,
|
||||
}));
|
||||
};
|
||||
|
||||
const update = async () => {
|
||||
|
||||
console.log("Submitted Data:", header); // Log the data to verify it's correct
|
||||
const staticTestData = { ...header}; // Mock updated data with additional fields if needed
|
||||
console.log("Static Updated Data:", staticTestData);
|
||||
toast.success('Dashboard updated successfully');
|
||||
// navigate('/admin/dashboard-new-all',{ state: { updatedDashboard: staticTestData } });
|
||||
|
||||
try {
|
||||
const updatedDashboard = await DashboardBuilderService.updateDash(header); // Await the API response
|
||||
|
||||
if (updatedDashboard) {
|
||||
setUpdated(true);
|
||||
toast.success('Dashboard updated successfully');
|
||||
navigate('/admin/dashboard-new-all'); // Pass updated data to the next page
|
||||
} else {
|
||||
throw new Error("No response from server");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error updating dashboard:", error);
|
||||
toast.error('Failed to update the dashboard. Please try again later.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Handle form submission
|
||||
const onSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
setUpdated(true);
|
||||
update();
|
||||
};
|
||||
|
||||
// Handle the back button
|
||||
const onBack = () => {
|
||||
navigate('/admin/dashboard-new-all');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h4 style={{ fontWeight: 300, display: 'inline' }}><b> Dashboard</b></h4>
|
||||
<Badge
|
||||
color="info" // This sets the blue color
|
||||
style={{ display: "inline", marginLeft: 10 }}
|
||||
>
|
||||
Edit Mode
|
||||
</Badge>
|
||||
<hr /><br />
|
||||
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="row">
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="dashboard_name">Dashboard Name</label>
|
||||
<input
|
||||
id="dashboard_name"
|
||||
type="text"
|
||||
name="dashboard_name"
|
||||
value={header.dashboard_name || ''}
|
||||
// onChange={(e) => setHeader({ ...header, dashboard_name: e.target.value })}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter Dashboard Name"
|
||||
className="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="secuirity_profile">Security Profile</label>
|
||||
<input
|
||||
id="secuirity_profile"
|
||||
type="text"
|
||||
name="secuirity_profile"
|
||||
value={header.secuirity_profile || ''}
|
||||
// onChange={(e) => setHeader({ ...header, secuirity_profile: e.target.value })}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter Security Profile"
|
||||
className="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="description">Description</label>
|
||||
<textarea
|
||||
cols="10"
|
||||
rows="2"
|
||||
name="description"
|
||||
value={header.description || ''}
|
||||
// onChange={(e) => setHeader({ ...header, description: e.target.value })}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter Description"
|
||||
className="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="workflow_name" style={{ marginTop: "1rem" }}>Add to Dashboard</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="add_to_home"
|
||||
checked={header.add_to_home || ''}
|
||||
// onChange={(e) => setHeader({ ...header, add_to_home: e.target.checked })}
|
||||
onChange={handleInputChange}
|
||||
className="form-check-input"
|
||||
style={{ marginTop: "3rem", marginLeft: "-8rem" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<div className="text-center">
|
||||
<button type="button" className="btn btn-outline-secondary" onClick={onBack}>BACK</button>
|
||||
<button type="submit" className="btn btn-primary">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditFormNewDash;
|
||||
605
src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js
Normal file
605
src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js
Normal file
@@ -0,0 +1,605 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import 'react-grid-layout/css/styles.css';
|
||||
import 'react-resizable/css/styles.css';
|
||||
import { Responsive, WidthProvider } from 'react-grid-layout';
|
||||
import { FormControl, Input, Select, Checkbox, Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography, Card, CardContent, MenuItem, Box } from '@mui/material';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faTrash, faGripLines, faPen } from '@fortawesome/free-solid-svg-icons';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import DashboardBuilderService from "../../../../APIServices/DashboardBuilderService";
|
||||
|
||||
// Import chart components
|
||||
import LineChartComponent from '../gadgets/line-chart/LineChart';
|
||||
import PieChartComponent from '../gadgets/pie-chart/Piechart';
|
||||
import PolarChartComponent from '../gadgets/polar-chart/PolarChart';
|
||||
import RadarChartComponent from '../gadgets/radar-chart/RadarChart';
|
||||
import BubbleChart from '../gadgets/bubble-chart/BubbleChart';
|
||||
import BarChart from '../gadgets/bar-chart/BarChart';
|
||||
import DoughnutChart from '../gadgets/doughnut-charts/DoughnutChart';
|
||||
import DynamicChart from '../gadgets/dynamic-chart/DynamicChart';
|
||||
import FinancialChart from '../gadgets/financial-chart/FinancialChart';
|
||||
import GridViewComponent from '../gadgets/grid-view/GridView';
|
||||
import ScatterChartComponent from '../gadgets/scatter-chart/ScatterChart';
|
||||
import ToDoChartComponent from '../gadgets/to-do-chart/TodoChart';
|
||||
|
||||
// Use WidthProvider to handle responsive behavior
|
||||
const ResponsiveGridLayout = WidthProvider(Responsive);
|
||||
|
||||
const EditNewDash = () => {
|
||||
const { id } = useParams(); // fetching id from the url
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [editModalOpen, setEditModalOpen] = useState(false);
|
||||
const [currentEditWidget, setCurrentEditWidget] = useState({});
|
||||
const [dashboardName, setDashboardName] = useState();
|
||||
const [dashboardLine, setDashboardLine] = useState();
|
||||
const [columnData] = useState(['Column1', 'Column2', 'Column3']);
|
||||
const [dashboardWidgets, setDashboardWidgets] = useState([]);
|
||||
const [dashboardlineId, setDashboardlineId]= useState();
|
||||
|
||||
// Define available widgets
|
||||
const [availableWidgets] = useState([
|
||||
{ identifier: 'radar_chart', name: 'Radar Chart' },
|
||||
{ identifier: 'polar_chart', name: 'Polar Chart' },
|
||||
{ identifier: 'pie_chart', name: 'Pie Chart' },
|
||||
{ identifier: 'bar_chart', name: 'Bar Chart' },
|
||||
{ identifier: 'bubble_chart', name: 'Bubble Chart' },
|
||||
{ identifier: 'line_chart', name: 'Line Chart' },
|
||||
{ identifier: 'doughnut_chart', name: 'Doughnut Chart' },
|
||||
{ identifier: 'dynamic_chart', name: 'Dynamic Chart' },
|
||||
{ identifier: 'financial_chart', name: 'Financial Chart' },
|
||||
{ identifier: 'grid_view', name: 'Grid View' },
|
||||
{ identifier: 'scatter_chart', name: 'Scatter Chart' },
|
||||
{ identifier: 'todo_chart', name: 'Todo Chart' },
|
||||
]);
|
||||
|
||||
// Define component mapping object for easier lookup
|
||||
const componentMap = {
|
||||
'radar_chart': RadarChartComponent,
|
||||
'polar_chart': PolarChartComponent,
|
||||
'pie_chart': PieChartComponent,
|
||||
'bar_chart': BarChart,
|
||||
'bubble_chart': BubbleChart,
|
||||
'line_chart': LineChartComponent,
|
||||
'doughnut_chart': DoughnutChart,
|
||||
'dynamic_chart': DynamicChart,
|
||||
'financial_chart': FinancialChart,
|
||||
'grid_view': GridViewComponent,
|
||||
'scatter_chart': ScatterChartComponent,
|
||||
'todo_chart': ToDoChartComponent
|
||||
};
|
||||
|
||||
// Component name to identifier mapping for reverse lookup
|
||||
const componentNameToIdentifier = {
|
||||
'Radar Chart': 'radar_chart',
|
||||
'Polar Chart': 'polar_chart',
|
||||
'Pie Chart': 'pie_chart',
|
||||
'Bar Chart': 'bar_chart',
|
||||
'Bubble Chart': 'bubble_chart',
|
||||
'Line Chart': 'line_chart',
|
||||
'Doughnut Chart': 'doughnut_chart',
|
||||
'Dynamic Chart': 'dynamic_chart',
|
||||
'Financial Chart': 'financial_chart',
|
||||
'Grid View': 'grid_view',
|
||||
'Scatter Chart': 'scatter_chart',
|
||||
'Todo Chart': 'todo_chart'
|
||||
};
|
||||
|
||||
// fetching dashboard data by id (id is fetched from the url)
|
||||
useEffect(() => {
|
||||
fetchDashboardData();
|
||||
}, []);
|
||||
|
||||
const fetchDashboardData = async () => {
|
||||
try {
|
||||
const response = await DashboardBuilderService.getById(id);
|
||||
console.log("Raw API response:", response);
|
||||
console.log("dashboardid: ",response.dashbord1_Line[0].id)
|
||||
setDashboardlineId(response.dashbord1_Line[0].id)
|
||||
setDashboardName(response.dashboard_name);
|
||||
setDashboardLine(response.dashbord1_Line);
|
||||
|
||||
if (response.dashbord1_Line && response.dashbord1_Line[0]?.model) {
|
||||
try {
|
||||
const modelData = response.dashbord1_Line[0].model;
|
||||
console.log("Model Data:", modelData);
|
||||
|
||||
const parsedModel = JSON.parse(modelData);
|
||||
console.log("Parsed Model:", parsedModel);
|
||||
|
||||
// Transform the data format to match what ResponsiveGridLayout expects
|
||||
const transformedWidgets = Array.isArray(parsedModel.dashboard)
|
||||
? parsedModel.dashboard.map((widget, index) => {
|
||||
// Create a widget ID if not present
|
||||
const widgetId = widget.i || `widget-${index}`;
|
||||
|
||||
// Get the component identifier from name if component is provided as a string
|
||||
const typeIdentifier = widget.type ||
|
||||
(widget.component && typeof widget.component === 'string'
|
||||
? componentNameToIdentifier[widget.component] || widget.component.toLowerCase().replace(' ', '_')
|
||||
: 'unknown');
|
||||
|
||||
// Get component reference from the component map
|
||||
const componentRef = componentMap[typeIdentifier] || null;
|
||||
|
||||
// Map the widget properties to the expected format
|
||||
return {
|
||||
i: widgetId,
|
||||
x: widget.x || 0,
|
||||
y: widget.y || 0,
|
||||
w: widget.cols || 6, // Convert cols to w
|
||||
h: widget.rows || 8, // Convert rows to h
|
||||
type: typeIdentifier,
|
||||
name: widget.name || availableWidgets.find(w => w.identifier === typeIdentifier)?.name || 'Unknown Widget',
|
||||
component: componentRef,
|
||||
chartTitle: widget.chartTitle,
|
||||
showLegend: widget.showLegend,
|
||||
showLabel: widget.showLabel,
|
||||
xAxis: widget.xAxis,
|
||||
yAxis: widget.yAxis
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
console.log("Transformed widgets:", transformedWidgets);
|
||||
setDashboardWidgets(transformedWidgets);
|
||||
} catch (parseError) {
|
||||
console.error("Error parsing dashboard model:", parseError);
|
||||
setDashboardWidgets([]);
|
||||
}
|
||||
} else {
|
||||
console.log("No valid model data, setting empty widgets.");
|
||||
setDashboardWidgets([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching dashboard data:", error);
|
||||
setDashboardWidgets([]);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Updated dashboardWidgets:", dashboardWidgets);
|
||||
}, [dashboardWidgets]);
|
||||
|
||||
const [dashboardForm, setDashboardForm] = useState({
|
||||
donut: '',
|
||||
chartlegend: '',
|
||||
showlabel: '',
|
||||
charturl: '',
|
||||
chartparameter: '',
|
||||
datastore: '',
|
||||
table: '',
|
||||
datasource: '',
|
||||
charttitle: '',
|
||||
id: '',
|
||||
fieldName: '',
|
||||
chartcolor: '',
|
||||
slices: '',
|
||||
yAxis: '',
|
||||
xAxis: '',
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Handle widget drag from sidebar
|
||||
const onDragStart = (e, widget) => {
|
||||
e.dataTransfer.setData('widgetType', widget.identifier);
|
||||
};
|
||||
|
||||
// Handle widget drop onto dashboard
|
||||
const onDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const onDrop = (e) => {
|
||||
e.preventDefault();
|
||||
const widgetType = e.dataTransfer.getData('widgetType');
|
||||
|
||||
if (!widgetType) return;
|
||||
|
||||
// Calculate drop position relative to the grid
|
||||
const gridRect = e.currentTarget.getBoundingClientRect();
|
||||
const x = Math.floor((e.clientX - gridRect.left) / 100) * 2;
|
||||
const y = Math.floor((e.clientY - gridRect.top) / 100) * 2;
|
||||
|
||||
// Create new widget based on type
|
||||
let maxChartId = dashboardWidgets?.reduce((maxId, item) => Math.max(maxId, item.chartid || 0), 0);
|
||||
console.log("maxChartId",maxChartId)
|
||||
const newWidgetId = `widget-${Date.now()}`;
|
||||
const componentRef = componentMap[widgetType] || null;
|
||||
const widgetName = availableWidgets.find(w => w.identifier === widgetType)?.name || 'Unknown Widget';
|
||||
|
||||
const newWidget = {
|
||||
i: newWidgetId,
|
||||
x: x,
|
||||
y: y,
|
||||
w: 6,
|
||||
h: 8,
|
||||
type: widgetType,
|
||||
name: widgetName,
|
||||
component: componentRef, // Add the component reference here
|
||||
chartTitle: widgetName, // Add default chart title
|
||||
showLegend: true, // Add default values for chart config
|
||||
showLabel: true,
|
||||
xAxis: 'Month',
|
||||
yAxis: 'Value'
|
||||
};
|
||||
|
||||
setDashboardWidgets(prev => [...prev, newWidget]);
|
||||
};
|
||||
|
||||
// Handle layout changes
|
||||
const onLayoutChange = (layout) => {
|
||||
// Update widget positions when layout changes
|
||||
const updatedWidgets = dashboardWidgets.map(widget => {
|
||||
const updatedPosition = layout.find(item => item.i === widget.i);
|
||||
if (updatedPosition) {
|
||||
return { ...widget, x: updatedPosition.x, y: updatedPosition.y, w: updatedPosition.w, h: updatedPosition.h };
|
||||
}
|
||||
return widget;
|
||||
});
|
||||
|
||||
setDashboardWidgets(updatedWidgets);
|
||||
};
|
||||
|
||||
// Remove widget
|
||||
const removeWidget = (widgetId) => {
|
||||
setDashboardWidgets(prev => prev.filter(widget => widget.i !== widgetId));
|
||||
};
|
||||
|
||||
// Edit widget
|
||||
const editWidget = (widget) => {
|
||||
setCurrentEditWidget(widget);
|
||||
setEditModalOpen(true);
|
||||
};
|
||||
|
||||
// Save edited widget
|
||||
const saveWidgetChanges = () => {
|
||||
setDashboardWidgets(prev =>
|
||||
prev.map(widget =>
|
||||
widget.i === currentEditWidget.i ? { ...widget, ...currentEditWidget } : widget
|
||||
)
|
||||
);
|
||||
setEditModalOpen(false);
|
||||
};
|
||||
|
||||
// Navigate back
|
||||
const goBack = () => {
|
||||
navigate('/admin/dashboard-new-all');
|
||||
};
|
||||
|
||||
const dashbord1_Line = {
|
||||
model:''
|
||||
}
|
||||
// Save dashboard
|
||||
const saveDashboard = async () => {
|
||||
try {
|
||||
// Ensure dashboardWidgets is not empty before saving
|
||||
if (!dashboardWidgets || dashboardWidgets.length === 0) {
|
||||
console.warn("No widgets to save.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the dashboard data
|
||||
const dashboardData = {
|
||||
dashboard: dashboardWidgets.map(widget => ({
|
||||
x: widget.x ?? 0, // Default values to prevent errors
|
||||
y: widget.y ?? 0,
|
||||
cols: widget.w ?? 1,
|
||||
rows: widget.h ?? 1,
|
||||
component: widget.name || "Unknown",
|
||||
name: widget.name || "Unknown",
|
||||
// type: widget.type || "Generic",
|
||||
})),
|
||||
};
|
||||
|
||||
console.log("Saving dashboard:", dashboardData);
|
||||
console.log("Saving dashboard:", JSON.stringify(dashboardData))
|
||||
dashbord1_Line.model = JSON.stringify(dashboardData)
|
||||
console.log("dashbord1_Line: ", dashbord1_Line)
|
||||
// Call the API to update the dashboard data
|
||||
const response = await DashboardBuilderService.updateLineData(dashboardlineId, dashbord1_Line);
|
||||
|
||||
if (response) {
|
||||
console.log("Dashboard saved successfully:", response.data);
|
||||
// Optionally navigate after saving
|
||||
navigate('/admin/dashboard-new-all');
|
||||
} else {
|
||||
console.error("Failed to save dashboard. Server response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error saving dashboard:", error.message || error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
padding: 3
|
||||
}}>
|
||||
{/* Toolbar */}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
marginBottom: 3
|
||||
}}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
>
|
||||
{sidebarOpen ? 'Hide Components' : 'Add Components'}
|
||||
</Button>
|
||||
|
||||
<Typography variant="h5">{dashboardName}</Typography>
|
||||
|
||||
<Box>
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{ marginRight: 1 }}
|
||||
onClick={goBack}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={saveDashboard}
|
||||
>
|
||||
Save Dashboard
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Main content */}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
width: '100%',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
{/* Sidebar */}
|
||||
{sidebarOpen && (
|
||||
<Box sx={{
|
||||
width: 250,
|
||||
backgroundColor: '#f5f5f5',
|
||||
padding: 2,
|
||||
overflowY: 'auto',
|
||||
borderRight: '1px solid #e0e0e0'
|
||||
}}>
|
||||
<Typography variant="h6" sx={{ marginBottom: 2 }}>
|
||||
Available Components
|
||||
</Typography>
|
||||
<Box component="ul" sx={{
|
||||
listStyleType: 'none',
|
||||
padding: 0,
|
||||
margin: 0
|
||||
}}>
|
||||
{availableWidgets.map(widget => (
|
||||
<Box
|
||||
component="li"
|
||||
key={widget.identifier}
|
||||
sx={{
|
||||
padding: 1.5,
|
||||
marginBottom: 1,
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 1,
|
||||
cursor: 'move',
|
||||
border: '1px solid #e0e0e0',
|
||||
'&:hover': {
|
||||
backgroundColor: '#f0f7ff'
|
||||
}
|
||||
}}
|
||||
draggable
|
||||
onDragStart={(e) => onDragStart(e, widget)}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<FontAwesomeIcon icon={faGripLines} style={{ marginRight: 10 }} />
|
||||
{widget.name}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Dashboard grid */}
|
||||
<Box
|
||||
sx={{
|
||||
flex: 1,
|
||||
padding: 2,
|
||||
overflow: 'auto',
|
||||
backgroundColor: '#fafafa'
|
||||
}}
|
||||
onDragOver={onDragOver}
|
||||
onDrop={onDrop}
|
||||
>
|
||||
<ResponsiveGridLayout
|
||||
className="layout"
|
||||
layouts={{
|
||||
lg: dashboardWidgets.map(widget => ({
|
||||
i: widget.i,
|
||||
x: widget.x,
|
||||
y: widget.y,
|
||||
w: widget.w,
|
||||
h: widget.h,
|
||||
minW: 3,
|
||||
minH: 3
|
||||
}))
|
||||
}}
|
||||
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
|
||||
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
|
||||
rowHeight={30}
|
||||
onLayoutChange={onLayoutChange}
|
||||
isDraggable
|
||||
isResizable
|
||||
margin={[20, 20]}
|
||||
>
|
||||
{dashboardWidgets.map(widget => (
|
||||
<Box key={widget.i} sx={{ overflow: 'hidden' }}>
|
||||
<Card sx={{
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)'
|
||||
}}>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: 1,
|
||||
borderBottom: '1px solid #eee'
|
||||
}}>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 'bold' }}>
|
||||
{widget.name}
|
||||
</Typography>
|
||||
<Box>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => editWidget(widget)}
|
||||
sx={{ minWidth: 'auto', padding: '4px' }}
|
||||
>
|
||||
<FontAwesomeIcon icon={faPen} />
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => removeWidget(widget.i)}
|
||||
sx={{ minWidth: 'auto', padding: '4px', ml: 1 }}
|
||||
>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<CardContent sx={{
|
||||
flex: 1,
|
||||
padding: 2,
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: 'calc(100% - 50px)' // Subtracting header height
|
||||
}}>
|
||||
{widget.component && (
|
||||
<Box sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<widget.component
|
||||
chartTitle={widget.chartTitle || widget.name}
|
||||
showLegend={widget.showLegend !== undefined ? widget.showLegend : true}
|
||||
showLabel={widget.showLabel !== undefined ? widget.showLabel : true}
|
||||
xAxis={widget.xAxis || 'Month'}
|
||||
yAxis={widget.yAxis || 'Value'}
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Box>
|
||||
))}
|
||||
</ResponsiveGridLayout>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Edit widget dialog */}
|
||||
<Dialog open={editModalOpen} onClose={() => setEditModalOpen(false)} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>Edit {currentEditWidget.name}</DialogTitle>
|
||||
<DialogContent sx={{ paddingTop: 2 }}>
|
||||
<FormControl fullWidth sx={{ marginBottom: 2 }}>
|
||||
<Typography variant="subtitle2" sx={{ marginBottom: 1 }}>Chart Title</Typography>
|
||||
<Input
|
||||
value={currentEditWidget.chartTitle || ''}
|
||||
onChange={(e) => setCurrentEditWidget({
|
||||
...currentEditWidget,
|
||||
chartTitle: e.target.value
|
||||
})}
|
||||
placeholder="Enter chart title"
|
||||
fullWidth
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
{currentEditWidget.name !== 'Grid View' && currentEditWidget.name !== 'Todo Chart' && (
|
||||
<>
|
||||
<Box sx={{ display: 'flex', gap: 2, marginBottom: 2 }}>
|
||||
<FormControl sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Checkbox
|
||||
checked={currentEditWidget.showLegend || false}
|
||||
onChange={(e) => setCurrentEditWidget({
|
||||
...currentEditWidget,
|
||||
showLegend: e.target.checked
|
||||
})}
|
||||
/>
|
||||
<Typography>Show Legend</Typography>
|
||||
</FormControl>
|
||||
|
||||
<FormControl sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Checkbox
|
||||
checked={currentEditWidget.showLabel || false}
|
||||
onChange={(e) => setCurrentEditWidget({
|
||||
...currentEditWidget,
|
||||
showLabel: e.target.checked
|
||||
})}
|
||||
/>
|
||||
<Typography>Show Labels</Typography>
|
||||
</FormControl>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormControl fullWidth sx={{ marginBottom: 2 }}>
|
||||
<Typography variant="subtitle2" sx={{ marginBottom: 1 }}>X-Axis</Typography>
|
||||
<Select
|
||||
value={currentEditWidget.xAxis || ''}
|
||||
onChange={(e) => setCurrentEditWidget({
|
||||
...currentEditWidget,
|
||||
xAxis: e.target.value
|
||||
})}
|
||||
displayEmpty
|
||||
>
|
||||
<MenuItem value="" disabled>Select X-Axis</MenuItem>
|
||||
{columnData.map((col, index) => (
|
||||
<MenuItem key={index} value={col}>{col}</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormControl fullWidth sx={{ marginBottom: 2 }}>
|
||||
<Typography variant="subtitle2" sx={{ marginBottom: 1 }}>Y-Axis</Typography>
|
||||
<Select
|
||||
value={currentEditWidget.yAxis || ''}
|
||||
onChange={(e) => setCurrentEditWidget({
|
||||
...currentEditWidget,
|
||||
yAxis: e.target.value
|
||||
})}
|
||||
displayEmpty
|
||||
>
|
||||
<MenuItem value="" disabled>Select Y-Axis</MenuItem>
|
||||
{columnData.map((col, index) => (
|
||||
<MenuItem key={index} value={col}>{col}</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ padding: 2 }}>
|
||||
<Button onClick={() => setEditModalOpen(false)} color="inherit">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={saveWidgetChanges} variant="contained" color="primary">
|
||||
Save Changes
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditNewDash;
|
||||
@@ -0,0 +1,381 @@
|
||||
// import React,{useState,useEffect} from 'react'
|
||||
// import { useForm, useFieldArray } from "react-hook-form";
|
||||
// import { useNavigate } from "react-router-dom";
|
||||
// import { toast } from "react-toastify";
|
||||
// import "react-toastify/dist/ReactToastify.css";
|
||||
// import { Badge } from "reactstrap";
|
||||
|
||||
// const DashboardbuilderAdd = () => {
|
||||
|
||||
// const [moduleId, setModuleId] = useState(null);
|
||||
// const [techStacks, setTechStacks] = useState([]);
|
||||
// const objectTypes = ["form", "bi", "report", "api"];
|
||||
// const subObjectTypes = [
|
||||
// "only header",
|
||||
// "only line",
|
||||
// "header line",
|
||||
// "header multiline",
|
||||
// "workflow",
|
||||
// "setup",
|
||||
// "std report",
|
||||
// "bi report",
|
||||
// "rest api",
|
||||
// ];
|
||||
|
||||
// const fieldModels = {
|
||||
// dashboard: [
|
||||
// {
|
||||
// cols: 4,
|
||||
// rows: 5,
|
||||
// x: 0,
|
||||
// y: 0,
|
||||
// name: "Radar Chart",
|
||||
// component: "Radar Chart",
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
|
||||
// const navigate = useNavigate();
|
||||
// const {
|
||||
// register,
|
||||
// handleSubmit,
|
||||
// control,
|
||||
// formState: { errors },
|
||||
// } = useForm({
|
||||
// defaultValues: {
|
||||
// dashboard_name: "",
|
||||
// description: "",
|
||||
// secuirity_profile: "",
|
||||
// module_id: null,
|
||||
// tech_Stack: "",
|
||||
// object_type: "",
|
||||
// sub_object_type: "",
|
||||
// add_to_home: true,
|
||||
// dashbord1_Line: [
|
||||
// {
|
||||
// model: JSON.stringify(fieldModels),
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// });
|
||||
|
||||
// const { fields } = useFieldArray({
|
||||
// control,
|
||||
// name: "dashbord1_Line",
|
||||
// });
|
||||
|
||||
// useEffect(() => {
|
||||
// // Simulate module ID fetching logic
|
||||
// setModuleId("exampleModuleId");
|
||||
// }, []);
|
||||
|
||||
// const onSubmit = (data) => {
|
||||
// console.log("Form Data:", data);
|
||||
// if (!data.dashboard_name || !data.secuirity_profile || !data.description) {
|
||||
// toast.error("Please fill out all required fields.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// data.module_id = moduleId;
|
||||
|
||||
// // DashboardService.create(data)
|
||||
// // .then((response) => {
|
||||
// // console.log(response);
|
||||
// // toast.success("Added successfully");
|
||||
// // navigate("../all");
|
||||
// // })
|
||||
// // .catch((error) => {
|
||||
// // console.error(error);
|
||||
// // toast.error("Error while adding dashboard");
|
||||
// // });
|
||||
// };
|
||||
|
||||
// const onValid = (data) => {
|
||||
// console.log('Form Submitted Successfully:', data);
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div className="container">
|
||||
// <h4 style={{ fontWeight: 300, display: "inline" }}>
|
||||
// <b>Define Dashboard</b>
|
||||
// </h4>
|
||||
// <Badge
|
||||
// color="info" // This sets the blue color
|
||||
// style={{ display: "inline", marginLeft: 10 }}
|
||||
// >
|
||||
// Add Mode
|
||||
// </Badge>
|
||||
// <hr />
|
||||
// <br />
|
||||
|
||||
// <form onSubmit={handleSubmit(onSubmit)}>
|
||||
// <div className="row">
|
||||
// <div className="col-md-6 col-sm-12">
|
||||
// <label htmlFor="dashboard_name">Dashboard Name</label>
|
||||
// <input
|
||||
// id="dashboard_name"
|
||||
// type="text"
|
||||
// {...register("dashboard_name", { required: true })}
|
||||
// className="form-control"
|
||||
// placeholder="Enter dashboard name"
|
||||
// />
|
||||
// {errors.dashboard_name && <p className="text-danger">This field is required.</p>}
|
||||
// </div>
|
||||
|
||||
// <div className="col-md-6 col-sm-12">
|
||||
// <label htmlFor="secuirity_profile">Security Profile</label>
|
||||
// <input
|
||||
// id="secuirity_profile"
|
||||
// type="text"
|
||||
// {...register("secuirity_profile", { required: true })}
|
||||
// className="form-control"
|
||||
// placeholder="Enter security profile"
|
||||
// />
|
||||
// {errors.secuirity_profile && <p className="text-danger">This field is required.</p>}
|
||||
// </div>
|
||||
|
||||
// <div className="col-md-6 col-sm-12">
|
||||
// <label htmlFor="description">Description</label>
|
||||
// <textarea
|
||||
// id="description"
|
||||
// {...register("description", { required: true })}
|
||||
// className="form-control"
|
||||
// placeholder="Enter description"
|
||||
// />
|
||||
// {errors.description && <p className="text-danger">This field is required.</p>}
|
||||
// </div>
|
||||
|
||||
// <div className="col-md-6 col-sm-12" >
|
||||
// <label htmlFor="add_to_home" style={{ marginTop: "1rem"}}>Add to Dashboard</label>
|
||||
// <input
|
||||
// type="checkbox"
|
||||
// {...register("add_to_home")}
|
||||
// className="form-check-input"
|
||||
// style={{marginTop:"3rem" , marginLeft:"-8rem"}}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// <br />
|
||||
|
||||
// <div className="text-center">
|
||||
// <button
|
||||
// type="button"
|
||||
// className="btn btn-outline-secondary"
|
||||
// onClick={() => navigate("/admin/dashboard-new-all")}
|
||||
// >
|
||||
// Back
|
||||
// </button>
|
||||
// <button type="submit" className="btn btn-primary" onClick={handleSubmit()}>
|
||||
// Submit
|
||||
// </button>
|
||||
// </div>
|
||||
// </form>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
|
||||
// export default DashboardbuilderAdd
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useForm, useFieldArray } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { Badge } from "reactstrap";
|
||||
import DashboardBuilderService from "../../../../APIServices/DashboardBuilderService";
|
||||
|
||||
const DashboardbuilderAdd = () => {
|
||||
const [moduleId, setModuleId] = useState(null);
|
||||
const [techStacks, setTechStacks] = useState([]);
|
||||
const objectTypes = ["form", "bi", "report", "api"];
|
||||
const subObjectTypes = [
|
||||
"only header",
|
||||
"only line",
|
||||
"header line",
|
||||
"header multiline",
|
||||
"workflow",
|
||||
"setup",
|
||||
"std report",
|
||||
"bi report",
|
||||
"rest api",
|
||||
];
|
||||
const [dashboards, setDashboards] = useState([]);
|
||||
|
||||
const fieldModels = {
|
||||
dashboard: [
|
||||
{
|
||||
cols: 4,
|
||||
rows: 5,
|
||||
x: 0,
|
||||
y: 0,
|
||||
name: "Radar Chart",
|
||||
component: "Radar Chart",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const navigate = useNavigate();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
defaultValues: {
|
||||
dashboard_name: "",
|
||||
description: "",
|
||||
secuirity_profile: "",
|
||||
module_id: null,
|
||||
tech_Stack: "",
|
||||
object_type: "",
|
||||
sub_object_type: "",
|
||||
add_to_home: true,
|
||||
dashbord1_Line: [
|
||||
{
|
||||
model: JSON.stringify(fieldModels),
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const { fields } = useFieldArray({
|
||||
control,
|
||||
name: "dashbord1_Line",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Simulate module ID fetching logic
|
||||
setModuleId("exampleModuleId");
|
||||
}, []);
|
||||
|
||||
// #############
|
||||
const onSubmit = (data) => {
|
||||
|
||||
console.log("Form Data:", data);
|
||||
if (!data.dashboard_name || !data.secuirity_profile || !data.description) {
|
||||
toast.error("Please fill out all required fields.");
|
||||
return;
|
||||
}
|
||||
|
||||
const newDashboard = {
|
||||
...data,
|
||||
// module_id: Number(moduleId), // Ensure this is an integer
|
||||
// id: Date.now(), // Simulate a unique ID
|
||||
};
|
||||
|
||||
console.log("New Dashboard:", newDashboard);
|
||||
const existingDashboards =
|
||||
JSON.parse(localStorage.getItem("dashboards")) || [];
|
||||
console.log("Existing Dashboards:", existingDashboards);
|
||||
|
||||
localStorage.setItem(
|
||||
"dashboards",
|
||||
JSON.stringify([...existingDashboards, newDashboard])
|
||||
);
|
||||
|
||||
setDashboards((prevDashboards) => [...prevDashboards, newDashboard]);
|
||||
|
||||
|
||||
|
||||
// API call to save the new dashboard
|
||||
DashboardBuilderService.create(newDashboard)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
toast.success("Dashboard Added successfully");
|
||||
navigate("/admin/dashboard-new-all");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
toast.error("Error while adding dashboard");
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h4 style={{ fontWeight: 300, display: "inline" }}>
|
||||
<b>Define Dashboard</b>
|
||||
</h4>
|
||||
<Badge
|
||||
color="info" // This sets the blue color
|
||||
style={{ display: "inline", marginLeft: 10 }}
|
||||
>
|
||||
Add Mode
|
||||
</Badge>
|
||||
<hr />
|
||||
<br />
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="row">
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="dashboard_name">Dashboard Name</label>
|
||||
<input
|
||||
id="dashboard_name"
|
||||
type="text"
|
||||
{...register("dashboard_name", { required: true })}
|
||||
className="form-control"
|
||||
placeholder="Enter dashboard name"
|
||||
/>
|
||||
{errors.dashboard_name && (
|
||||
<p className="text-danger">This field is required.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="secuirity_profile">Security Profile</label>
|
||||
<input
|
||||
id="secuirity_profile"
|
||||
type="text"
|
||||
{...register("secuirity_profile", { required: true })}
|
||||
className="form-control"
|
||||
placeholder="Enter security profile"
|
||||
/>
|
||||
{errors.secuirity_profile && (
|
||||
<p className="text-danger">This field is required.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="description">Description</label>
|
||||
<textarea
|
||||
id="description"
|
||||
{...register("description", { required: true })}
|
||||
className="form-control"
|
||||
placeholder="Enter description"
|
||||
/>
|
||||
{errors.description && (
|
||||
<p className="text-danger">This field is required.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-md-6 col-sm-12">
|
||||
<label htmlFor="add_to_home" style={{ marginTop: "1rem" }}>
|
||||
Add to Dashboard
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
{...register("add_to_home")}
|
||||
className="form-check-input"
|
||||
style={{ marginTop: "3rem", marginLeft: "-8rem" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div className="text-center">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={() => navigate("/admin/dashboard-new-all")}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<button type="submit" className="btn btn-primary">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardbuilderAdd;
|
||||
@@ -0,0 +1,441 @@
|
||||
// import React, { useState } from "react";
|
||||
// import {
|
||||
// Button,
|
||||
// Modal,
|
||||
// Table,
|
||||
// Form,
|
||||
// Spinner,
|
||||
// Tooltip,
|
||||
// OverlayTrigger
|
||||
// } from "react-bootstrap";
|
||||
|
||||
// const DashboardNewAll = () => {
|
||||
// const [addModal, setAddModal] = useState(false);
|
||||
// const [deleteModal, setDeleteModal] = useState(false);
|
||||
// const [selectedRow, setSelectedRow] = useState(null);
|
||||
// const[data,setData] = useState([]);
|
||||
// const[loading,setLoading] = useState();
|
||||
// const [error,setError] = useState();
|
||||
// const[translate,setTranslate] = useState();
|
||||
|
||||
// const handleAddClick = () => setAddModal(true);
|
||||
// const handleDeleteClick = (row) => {
|
||||
// setSelectedRow(row);
|
||||
// setDeleteModal(true);
|
||||
// };
|
||||
|
||||
// const handleDeleteConfirm = () => {
|
||||
// console.log("Deleting row: ", selectedRow.id);
|
||||
// setDeleteModal(false);
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div className="dg-wrapper">
|
||||
// <div className="d-flex justify-content-between align-items-center mb-3">
|
||||
// <h3>{translate("Dashboard_builder")}</h3>
|
||||
// <div>
|
||||
// <Button variant="primary" onClick={() => console.log("Go to Runner")}>
|
||||
// <i className="bi bi-grid"></i> {translate("Dashboard_runner")}
|
||||
// </Button>
|
||||
// <Button
|
||||
// variant="outline-secondary"
|
||||
// className="mx-2"
|
||||
// onClick={() => console.log("Export")}
|
||||
// >
|
||||
// <i className="bi bi-file-earmark-excel"></i> {translate("EXPORT_XLSX")}
|
||||
// </Button>
|
||||
// <Button variant="primary" onClick={handleAddClick}>
|
||||
// <i className="bi bi-plus"></i> {translate("ADD")}
|
||||
// </Button>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <Table striped bordered hover>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>{translate("Go_to")}</th>
|
||||
// <th>{translate("Dashboard_Name")}</th>
|
||||
// <th>{translate("Description")}</th>
|
||||
// <th>{translate("Security_Profile")}</th>
|
||||
// <th>{translate("Add_to_home")}</th>
|
||||
// <th>{translate("Action")}</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// {loading ? (
|
||||
// <tr>
|
||||
// <td colSpan="6" className="text-center">
|
||||
// <Spinner animation="border" /> {translate("Loading")} ......
|
||||
// </td>
|
||||
// </tr>
|
||||
// ) : error ? (
|
||||
// <tr>
|
||||
// <td colSpan="6" className="text-center text-danger">
|
||||
// {error}
|
||||
// </td>
|
||||
// </tr>
|
||||
// ) : (
|
||||
// data?.slice()?.reverse()?.map((user) => (
|
||||
// <tr key={user.id}>
|
||||
// <td>
|
||||
// <span
|
||||
// className="badge bg-info text-dark"
|
||||
// style={{ cursor: "pointer" }}
|
||||
// onClick={() => console.log("Go to Edit", user.id)}
|
||||
// >
|
||||
// {translate("SET_UP")}
|
||||
// </span>
|
||||
// </td>
|
||||
// <td>{user.dashboard_name}</td>
|
||||
// <td>{user.description}</td>
|
||||
// <td>{user.security_profile}</td>
|
||||
// <td>{user.add_to_home}</td>
|
||||
// <td>
|
||||
// <OverlayTrigger
|
||||
// placement="top"
|
||||
// overlay={<Tooltip>{translate("Delete")}</Tooltip>}
|
||||
// >
|
||||
// <i
|
||||
// className="bi bi-trash text-danger"
|
||||
// style={{ cursor: "pointer" }}
|
||||
// onClick={() => handleDeleteClick(user)}
|
||||
// ></i>
|
||||
// </OverlayTrigger>
|
||||
// <OverlayTrigger
|
||||
// placement="top"
|
||||
// overlay={<Tooltip>{translate("Edit")}</Tooltip>}
|
||||
// >
|
||||
// <i
|
||||
// className="bi bi-pencil text-primary mx-2"
|
||||
// style={{ cursor: "pointer" }}
|
||||
// onClick={() => console.log("Edit", user.id)}
|
||||
// ></i>
|
||||
// </OverlayTrigger>
|
||||
// </td>
|
||||
// </tr>
|
||||
// ))
|
||||
// )}
|
||||
// </tbody>
|
||||
// </Table>
|
||||
|
||||
// {/* Add Modal */}
|
||||
// <Modal show={addModal} onHide={() => setAddModal(false)} size="lg" centered>
|
||||
// <Modal.Body>
|
||||
// <div className="d-flex justify-content-around">
|
||||
// <div
|
||||
// className="chart-box text-center"
|
||||
// onClick={() => console.log("Start from Scratch")}
|
||||
// >
|
||||
// <img
|
||||
// src="/assets/images/fromscratch.png"
|
||||
// alt="Start from Scratch"
|
||||
// height="90"
|
||||
// width="90"
|
||||
// />
|
||||
// <h5>{translate("Start_from_scratch")}</h5>
|
||||
// </div>
|
||||
// <div
|
||||
// className="chart-box text-center"
|
||||
// onClick={() => console.log("Import from Template")}
|
||||
// >
|
||||
// <img
|
||||
// src="/assets/images/copytemplate.png"
|
||||
// alt="Import from Template"
|
||||
// height="90"
|
||||
// width="90"
|
||||
// />
|
||||
// <h5>{translate("Import_from_template")}</h5>
|
||||
// </div>
|
||||
// <div
|
||||
// className="chart-box text-center"
|
||||
// onClick={() => console.log("Import from Public Project")}
|
||||
// >
|
||||
// <img
|
||||
// src="/assets/images/database.png"
|
||||
// alt="Import from Public Project"
|
||||
// height="90"
|
||||
// width="90"
|
||||
// />
|
||||
// <h5>{translate("Import_from_public_project")}</h5>
|
||||
// </div>
|
||||
// </div>
|
||||
// </Modal.Body>
|
||||
// </Modal>
|
||||
|
||||
// {/* Delete Modal */}
|
||||
// <Modal show={deleteModal} onHide={() => setDeleteModal(false)} centered>
|
||||
// <Modal.Body>
|
||||
// <h1 className="text-danger text-center">
|
||||
// {translate("Are_you_sure_want_to_delete")}
|
||||
// </h1>
|
||||
// <h2 className="text-center">{selectedRow?.id}</h2>
|
||||
// <div className="d-flex justify-content-around mt-4">
|
||||
// <Button variant="outline-secondary" onClick={() => setDeleteModal(false)}>
|
||||
// {translate("Cancel")}
|
||||
// </Button>
|
||||
// <Button variant="primary" onClick={handleDeleteConfirm}>
|
||||
// {translate("Delete")}
|
||||
// </Button>
|
||||
// </div>
|
||||
// </Modal.Body>
|
||||
// </Modal>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default DashboardNewAll;
|
||||
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
Table,
|
||||
Spinner,
|
||||
Tooltip,
|
||||
OverlayTrigger,
|
||||
} from "react-bootstrap";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import * as XLSX from "xlsx";
|
||||
import { toast } from "react-toastify";
|
||||
import ConfirmModal from "../../../common/ConfirmModal"
|
||||
import DashboardBuilderService from "../../../../APIServices/DashboardBuilderService";
|
||||
|
||||
const DashboardNewAll = () => {
|
||||
const { t: translate } = useTranslation(); // Use `translate` as the translation function
|
||||
const [addModal, setAddModal] = useState(false);
|
||||
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
||||
const [deleteModal, setDeleteModal] = useState(false);
|
||||
const [selectedRow, setSelectedRow] = useState(null);
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const storedDashboards = JSON.parse(localStorage.getItem("dashboards")) || [];
|
||||
setData(storedDashboards);
|
||||
console.log("Stored Dashboards:", storedDashboards);
|
||||
|
||||
if (location.state?.updatedDashboard) {
|
||||
const updatedDashboard = location.state.updatedDashboard;
|
||||
setData(prevData => prevData.map(dashboard =>
|
||||
dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard
|
||||
));
|
||||
location.state.updatedDashboard = null;
|
||||
}
|
||||
setLoading(false);
|
||||
}, [refresh, location.state?.updatedDashboard]);
|
||||
|
||||
const handleAddClick = () => {
|
||||
navigate("/admin/dashboard-new-add");
|
||||
}
|
||||
const handleDeleteClick = (row) => {
|
||||
setSelectedRow(row);
|
||||
setShowConfirmModal(true);
|
||||
};
|
||||
|
||||
const handleDeleteConfirm = async () => {
|
||||
try {
|
||||
// Call the delete API
|
||||
await DashboardBuilderService.deleteField(selectedRow.id);
|
||||
|
||||
// Update the UI after successful deletion
|
||||
setData((prevData) => prevData.filter((dashboard) => dashboard.id !== selectedRow.id));
|
||||
toast.success("Dashboard deleted successfully!");
|
||||
} catch (error) {
|
||||
console.error("Error deleting dashboard field:", error);
|
||||
toast.error("Failed to delete dashboard. Please try again.");
|
||||
}
|
||||
};
|
||||
const handleRunner = () => {
|
||||
console.log("Go to Runner");
|
||||
navigate("/admin/dashboard-runner-all");
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchAllDashboards();
|
||||
}, []);
|
||||
|
||||
const fetchAllDashboards = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const dashboards = await DashboardBuilderService.getAllDash(); // Call service
|
||||
console.log('Fetched Dashboards:', dashboards); // Verify data
|
||||
setData(dashboards); // Update state with the array
|
||||
toast.success("Dashboards fetched successfully.");
|
||||
} catch (error) {
|
||||
console.error('Error fetching dashboards:', error);
|
||||
toast.error('Failed to fetch dashboards.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditClick = (dashboard) => {
|
||||
navigate(`/admin/dashboard-new-edit/${dashboard.id}`, { state: { dashboard } }); // Pass the ID in the URL
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
console.log("Export to Excel");
|
||||
// Create a new workbook and a worksheet
|
||||
const workbook = XLSX.utils.book_new();
|
||||
const worksheet = XLSX.utils.json_to_sheet(data);
|
||||
|
||||
// Append the worksheet to the workbook
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
|
||||
|
||||
// Write the workbook and download the file
|
||||
XLSX.writeFile(workbook, "exported_data.xlsx");
|
||||
}
|
||||
|
||||
const handleSetUp = (id) => {
|
||||
console.log("dashboard id : ", id)
|
||||
navigate(`/admin/edit-new-dash/${id}`,{dashboardId:id});
|
||||
}
|
||||
const refreshData = () => {
|
||||
setRefresh((prev) => !prev); // Toggle the refresh state to trigger re-fetch
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="dg-wrapper">
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3>{translate("Dashboard Builder")}</h3>
|
||||
<div>
|
||||
<Button variant="primary" onClick={() => handleRunner()}>
|
||||
<i className="bi bi-grid"></i> {translate("Dashboard_runner")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline-secondary"
|
||||
className="mx-2"
|
||||
onClick={() => handleExport()}
|
||||
>
|
||||
<i className="bi bi-file-earmark-excel"></i> {translate("EXPORT_XLSX")}
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleAddClick}>
|
||||
<i className="bi bi-plus"></i> {translate("ADD")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Table striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Go To</th>
|
||||
<th>Dashboard Name</th>
|
||||
<th>Description</th>
|
||||
<th>Security Profile</th>
|
||||
<th>Add to Home</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loading ? (
|
||||
<tr>
|
||||
<td colSpan="6" className="text-center">
|
||||
<Spinner animation="border" /> Loading...
|
||||
</td>
|
||||
</tr>
|
||||
) : data.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan="6" className="text-center">No dashboards available.</td>
|
||||
</tr>
|
||||
) : (
|
||||
data.map((dashboard) => (
|
||||
<tr key={dashboard.id}>
|
||||
<td>
|
||||
<span
|
||||
className="badge bg-info text-dark"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => handleSetUp(dashboard.id)}
|
||||
>
|
||||
SET UP
|
||||
</span>
|
||||
</td>
|
||||
<td>{dashboard.dashboard_name}</td>
|
||||
<td>{dashboard.description}</td>
|
||||
<td>{dashboard.secuirity_profile}</td>
|
||||
<td>{dashboard.add_to_home ? "Yes" : "No"}</td>
|
||||
<td>
|
||||
<i
|
||||
className="bi bi-trash text-danger"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => handleDeleteClick(dashboard)}
|
||||
></i>
|
||||
<i
|
||||
className="bi bi-pencil text-primary mx-2"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => handleEditClick(dashboard)}
|
||||
></i>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
</tbody>
|
||||
</Table>
|
||||
{/* Add Modal */}
|
||||
<Modal show={addModal} onHide={() => setAddModal(false)} size="lg" centered>
|
||||
<Modal.Body>
|
||||
<div className="d-flex justify-content-around">
|
||||
<div
|
||||
className="chart-box text-center"
|
||||
onClick={() => console.log("Start from Scratch")}
|
||||
>
|
||||
<img
|
||||
src="/assets/images/fromscratch.png"
|
||||
alt="Start from Scratch"
|
||||
height="90"
|
||||
width="90"
|
||||
/>
|
||||
<h5>{translate("Start_from_scratch")}</h5>
|
||||
</div>
|
||||
<div
|
||||
className="chart-box text-center"
|
||||
onClick={() => console.log("Import from Template")}
|
||||
>
|
||||
<img
|
||||
src="/assets/images/copytemplate.png"
|
||||
alt="Import from Template"
|
||||
height="90"
|
||||
width="90"
|
||||
/>
|
||||
<h5>{translate("Import_from_template")}</h5>
|
||||
</div>
|
||||
<div
|
||||
className="chart-box text-center"
|
||||
onClick={() => console.log("Import from Public Project")}
|
||||
>
|
||||
<img
|
||||
src="/assets/images/database.png"
|
||||
alt="Import from Public Project"
|
||||
height="90"
|
||||
width="90"
|
||||
/>
|
||||
<h5>{translate("Import_from_public_project")}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
|
||||
{/* Confirmation Modal */}
|
||||
<ConfirmModal
|
||||
show={showConfirmModal}
|
||||
onHide={() => setShowConfirmModal(false)}
|
||||
onConfirm={handleDeleteConfirm}
|
||||
title="Delete Dashboard"
|
||||
message={`Are you sure you want to delete "${selectedRow?.dashboard_name || 'this dashboard'}"? This action cannot be undone.`}
|
||||
confirmLabel="Delete"
|
||||
cancelLabel="Cancel"
|
||||
variant="danger"
|
||||
/>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardNewAll;
|
||||
@@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import { Bar } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
BarElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from 'chart.js';
|
||||
|
||||
|
||||
|
||||
const BarChart = () => {
|
||||
const barChartLabels = ['Apple', 'Banana', 'Kiwifruit', 'Blueberry', 'Orange', 'Grapes'];
|
||||
const barChartData = {
|
||||
labels: barChartLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Best Fruits',
|
||||
data: [45, 37, 60, 70, 46, 33],
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const options = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
beginAtZero: true,
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const handleChartClick = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
const { index } = elements[0];
|
||||
console.log(`Clicked on ${barChartLabels[index]}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChartHover = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
console.log('Hovered on chart element:', elements);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block', width: '600px', margin: 'auto' }}>
|
||||
<Bar
|
||||
data={barChartData}
|
||||
options={options}
|
||||
onClick={(event, elements) => handleChartClick(event, elements)}
|
||||
onHover={(event, elements) => handleChartHover(event, elements)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BarChart;
|
||||
@@ -0,0 +1,92 @@
|
||||
// BubbleChart.js
|
||||
import React from 'react';
|
||||
import { Bubble } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
Tooltip,
|
||||
Legend,
|
||||
Title,
|
||||
} from 'chart.js';
|
||||
|
||||
// ChartJS.register(LinearScale, PointElement, Tooltip, Legend, Title);
|
||||
|
||||
const BubbleChart = () => {
|
||||
const bubbleChartOptions = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Bubble Chart',
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
min: 0,
|
||||
max: 30,
|
||||
},
|
||||
y: {
|
||||
min: 0,
|
||||
max: 30,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const bubbleChartData = {
|
||||
datasets: [
|
||||
{
|
||||
data: [
|
||||
{ x: 10, y: 10, r: 10 },
|
||||
{ x: 15, y: 5, r: 15 },
|
||||
{ x: 26, y: 12, r: 23 },
|
||||
{ x: 7, y: 8, r: 8 },
|
||||
],
|
||||
label: 'Investment Equities',
|
||||
backgroundColor: 'rgba(255, 0, 0, 0.6)', // Red
|
||||
borderColor: 'blue',
|
||||
hoverBackgroundColor: 'purple',
|
||||
hoverBorderColor: 'red',
|
||||
},
|
||||
{
|
||||
data: [
|
||||
{ x: 5, y: 15, r: 12 },
|
||||
{ x: 20, y: 7, r: 8 },
|
||||
{ x: 12, y: 18, r: 15 },
|
||||
{ x: 8, y: 6, r: 10 },
|
||||
],
|
||||
label: 'Investment Bonds',
|
||||
backgroundColor: 'rgba(0, 255, 0, 0.6)', // Green
|
||||
borderColor: 'green',
|
||||
hoverBackgroundColor: 'yellow',
|
||||
hoverBorderColor: 'blue',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const handleChartClick = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
const { datasetIndex, index } = elements[0].element.$context;
|
||||
console.log(`Clicked on:`, bubbleChartData.datasets[datasetIndex].data[index]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChartHover = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
console.log('Hovered over:', elements);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block', width: '600px', margin: 'auto' }}>
|
||||
<Bubble
|
||||
options={bubbleChartOptions}
|
||||
data={bubbleChartData}
|
||||
onClick={(event, elements) => handleChartClick(event, elements)}
|
||||
onHover={(event, elements) => handleChartHover(event, elements)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BubbleChart;
|
||||
@@ -0,0 +1,72 @@
|
||||
// DoughnutChart.js
|
||||
import React from 'react';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
ArcElement,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from 'chart.js';
|
||||
|
||||
//
|
||||
|
||||
const DoughnutChart = () => {
|
||||
const doughnutChartData = {
|
||||
labels: ["Download Sales", "In-Store Sales", "Mail-Order Sales"],
|
||||
datasets: [
|
||||
{
|
||||
data: [350, 450, 100],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.6)',
|
||||
'rgba(54, 162, 235, 0.6)',
|
||||
'rgba(255, 206, 86, 0.6)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255, 99, 132, 1)',
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 206, 86, 1)'
|
||||
],
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const doughnutChartOptions = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Doughnut Chart',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const handleChartClick = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
const { index } = elements[0].element.$context;
|
||||
console.log(`Clicked on:`, doughnutChartData.labels[index]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChartHover = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
console.log('Hovered over:', elements);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block', width: '600px', margin: 'auto' }}>
|
||||
<Doughnut
|
||||
data={doughnutChartData}
|
||||
options={doughnutChartOptions}
|
||||
onClick={(event, elements) => handleChartClick(event, elements)}
|
||||
onHover={(event, elements) => handleChartHover(event, elements)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DoughnutChart;
|
||||
@@ -0,0 +1,79 @@
|
||||
// DynamicChart.js
|
||||
import React, { useState } from 'react';
|
||||
import { Bar } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
BarElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from 'chart.js';
|
||||
|
||||
//
|
||||
|
||||
const DynamicChart = () => {
|
||||
const [chartType, setChartType] = useState('bar');
|
||||
|
||||
const barChartOptions = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Dynamic Chart',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const dynamicChartLabels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
|
||||
|
||||
const dynamicChartData = {
|
||||
labels: dynamicChartLabels,
|
||||
datasets: [
|
||||
{ data: [65, 59, 90, 81, 56, 55, 40], label: 'Series A', backgroundColor: 'rgba(75, 192, 192, 0.6)' },
|
||||
{ data: [28, 48, 40, 19, 96, 27, 100], label: 'Series B', backgroundColor: 'rgba(153, 102, 255, 0.6)' },
|
||||
],
|
||||
};
|
||||
|
||||
const handleChartClick = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
const { index } = elements[0].element.$context;
|
||||
console.log(`Clicked on:`, dynamicChartLabels[index]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChartHover = (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
console.log('Hovered over:', elements);
|
||||
}
|
||||
};
|
||||
|
||||
const randomize = () => {
|
||||
setChartType((prevType) => (prevType === 'bar' ? 'line' : 'bar'));
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block', width: '800px', margin: 'auto' }}>
|
||||
<Bar
|
||||
data={dynamicChartData}
|
||||
options={barChartOptions}
|
||||
type={chartType}
|
||||
onClick={(event, elements) => handleChartClick(event, elements)}
|
||||
onHover={(event, elements) => handleChartHover(event, elements)}
|
||||
/>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
style={{ marginTop: '20px' }}
|
||||
onClick={randomize}
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DynamicChart;
|
||||
@@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from 'chart.js';
|
||||
|
||||
// ✅ Register Chart.js components
|
||||
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend);
|
||||
|
||||
// ✅ Default stock data (used if no data is passed)
|
||||
const defaultStockData = [
|
||||
{ date: '2024-03-01', price: 120 },
|
||||
{ date: '2024-03-02', price: 125 },
|
||||
{ date: '2024-03-03', price: 130 },
|
||||
{ date: '2024-03-04', price: 128 },
|
||||
{ date: '2024-03-05', price: 135 },
|
||||
];
|
||||
|
||||
const FinancialChart = ({ data }) => {
|
||||
// ✅ Use default data if no data is provided
|
||||
const stockData = data && data.length > 0 ? data : defaultStockData;
|
||||
|
||||
const chartData = {
|
||||
labels: stockData.map(item => item.date), // X-axis labels (dates)
|
||||
datasets: [
|
||||
{
|
||||
label: 'Stock Price',
|
||||
data: stockData.map(item => item.price), // Y-axis values (prices)
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
fill: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const chartOptions = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Financial Data Chart',
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (tooltipItem) => `$${tooltipItem.raw.toFixed(2)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Date',
|
||||
},
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Price (USD)',
|
||||
},
|
||||
ticks: {
|
||||
callback: (value) => `$${value.toFixed(2)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return <Line data={chartData} options={chartOptions} />;
|
||||
};
|
||||
|
||||
export default FinancialChart;
|
||||
@@ -0,0 +1,102 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Table, Spinner, Pagination, Form } from "react-bootstrap";
|
||||
import {toast} from "react-toastify"; // if you want to use Toast notifications, or use a React version of it
|
||||
import moment from "moment";
|
||||
// import { ExcelService } from "src/app/services/excel.service";
|
||||
// import { UsergrpmaintainceService } from "src/app/services/admin/usergrpmaintaince.service";
|
||||
// import { MenuGroupService } from "src/app/services/admin/menu-group.service";
|
||||
|
||||
const GridViewComponent = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [givendata, setGivendata] = useState([]);
|
||||
const [error, setError] = useState(null);
|
||||
const [modalAdd, setModalAdd] = useState(false);
|
||||
const [modalEdit, setModalEdit] = useState(false);
|
||||
const [modalDelete, setModalDelete] = useState(false);
|
||||
const [rowSelected, setRowSelected] = useState({});
|
||||
const [orders, setOrders] = useState([]);
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// // Fetching the data on component mount
|
||||
// setLoading(true);
|
||||
// UsergrpmaintainceService.getAll()
|
||||
// .then((data) => {
|
||||
// setLoading(false);
|
||||
// setGivendata(data);
|
||||
// if (data.length === 0) {
|
||||
// setError("No data Available");
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// setLoading(false);
|
||||
// setError("Server Error");
|
||||
// });
|
||||
// }, []);
|
||||
|
||||
const handleRowSelect = (row) => {
|
||||
setRowSelected(row);
|
||||
};
|
||||
|
||||
const handlePagination = (page) => {
|
||||
// Handle pagination logic here
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: "block" }}>
|
||||
<div className="dg-wrapper">
|
||||
<div className="clr-row">
|
||||
<div className="clr-col-8">
|
||||
<h3>User Group Maintenance</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{loading ? (
|
||||
<div>
|
||||
<Spinner animation="border" /> Loading...
|
||||
</div>
|
||||
) : error ? (
|
||||
<div>{error}</div>
|
||||
) : (
|
||||
<Table striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User Group No</th>
|
||||
<th>Group Name</th>
|
||||
<th>Description</th>
|
||||
<th>Group Level</th>
|
||||
<th>Status</th>
|
||||
<th>Updated Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{givendata.reverse().map((user, index) => (
|
||||
<tr key={index} onClick={() => handleRowSelect(user)}>
|
||||
<td>{user.usrGrp}</td>
|
||||
<td>{user.groupName}</td>
|
||||
<td>{user.groupDesc}</td>
|
||||
<td>{user.groupLevel}</td>
|
||||
<td>{user.status}</td>
|
||||
<td>{user.updateDateFormated}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{/* Pagination logic */}
|
||||
<Pagination>
|
||||
{/* Add pagination items here */}
|
||||
<Pagination.Item onClick={() => handlePagination(1)}>1</Pagination.Item>
|
||||
<Pagination.Item onClick={() => handlePagination(2)}>2</Pagination.Item>
|
||||
{/* Pagination logic based on the fetched data */}
|
||||
</Pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GridViewComponent;
|
||||
@@ -0,0 +1,236 @@
|
||||
// import React, { useState, useEffect } from 'react';
|
||||
// import { Line } from 'react-chartjs-2'; // Assuming you're using react-chartjs-2 for the chart rendering
|
||||
// import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js';
|
||||
|
||||
// //
|
||||
|
||||
// const LineChartComponent = () => {
|
||||
// const [lineChartData, setLineChartData] = useState([
|
||||
// { data: [65, 59, 80, 81, 56, 55, 40], label: 'Series A' },
|
||||
// { data: [28, 48, 40, 19, 86, 27, 90], label: 'Series B' },
|
||||
// { data: [18, 48, 77, 9, 100, 27, 40], label: 'Series C' },
|
||||
// ]);
|
||||
|
||||
// const [lineChartLabels] = useState(['January', 'February', 'March', 'April', 'May', 'June', 'July']);
|
||||
// const [lineChartOptions] = useState({
|
||||
// responsive: true,
|
||||
// });
|
||||
|
||||
// const [lineChartColors] = useState([
|
||||
// {
|
||||
// backgroundColor: 'rgba(148,159,177,0.2)',
|
||||
// borderColor: 'rgba(148,159,177,1)',
|
||||
// pointBackgroundColor: 'rgba(148,159,177,1)',
|
||||
// pointBorderColor: '#fff',
|
||||
// pointHoverBackgroundColor: '#fff',
|
||||
// pointHoverBorderColor: 'rgba(148,159,177,0.8)',
|
||||
// },
|
||||
// {
|
||||
// backgroundColor: 'rgba(77,83,96,0.2)',
|
||||
// borderColor: 'rgba(77,83,96,1)',
|
||||
// pointBackgroundColor: 'rgba(77,83,96,1)',
|
||||
// pointBorderColor: '#fff',
|
||||
// pointHoverBackgroundColor: '#fff',
|
||||
// pointHoverBorderColor: 'rgba(77,83,96,1)',
|
||||
// },
|
||||
// {
|
||||
// backgroundColor: 'rgba(148,159,177,0.2)',
|
||||
// borderColor: 'rgba(148,159,177,1)',
|
||||
// pointBackgroundColor: 'rgba(148,159,177,1)',
|
||||
// pointBorderColor: '#fff',
|
||||
// pointHoverBackgroundColor: '#fff',
|
||||
// pointHoverBorderColor: 'rgba(148,159,177,0.8)',
|
||||
// },
|
||||
// ]);
|
||||
|
||||
// const [lineChartLegend] = useState(true);
|
||||
// const [lineChartType] = useState('line');
|
||||
|
||||
// // Function to randomize chart data
|
||||
// const randomize = () => {
|
||||
// const _lineChartData = lineChartData.map((series) => ({
|
||||
// ...series,
|
||||
// data: series.data.map(() => Math.floor(Math.random() * 100) + 1),
|
||||
// }));
|
||||
// setLineChartData(_lineChartData);
|
||||
// };
|
||||
|
||||
// // Chart hover and click events
|
||||
// const chartClicked = (e) => {
|
||||
// console.log(e);
|
||||
// };
|
||||
|
||||
// const chartHovered = (e) => {
|
||||
// console.log(e);
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div style={{ display: 'block' }}>
|
||||
// <Line
|
||||
// data={{
|
||||
// labels: lineChartLabels,
|
||||
// datasets: lineChartData,
|
||||
// }}
|
||||
// options={lineChartOptions}
|
||||
// legend={lineChartLegend}
|
||||
// type={lineChartType}
|
||||
// onHover={chartHovered}
|
||||
// onClick={chartClicked}
|
||||
// />
|
||||
// {/* You can add a button here to call randomize() */}
|
||||
// <button onClick={randomize}>Randomize Data</button>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default LineChartComponent;
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend
|
||||
} from 'chart.js';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import { Box, Button } from '@mui/material';
|
||||
|
||||
// Register Chart.js components
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend
|
||||
);
|
||||
|
||||
const LineChartComponent = ({
|
||||
chartTitle = 'Line Chart',
|
||||
showLegend = true,
|
||||
showLabel = true,
|
||||
xAxis = 'Category',
|
||||
yAxis = 'Value',
|
||||
width = '100%',
|
||||
height = '100%'
|
||||
}) => {
|
||||
const [lineChartData, setLineChartData] = useState({
|
||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Series A',
|
||||
data: [65, 59, 80, 81, 56, 55, 40],
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: 'rgba(75, 192, 192, 1)',
|
||||
pointBorderColor: '#fff',
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
pointHoverBorderColor: 'rgba(75, 192, 192, 1)',
|
||||
tension: 0.1
|
||||
},
|
||||
{
|
||||
label: 'Series B',
|
||||
data: [28, 48, 40, 19, 86, 27, 90],
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: 'rgba(54, 162, 235, 1)',
|
||||
pointBorderColor: '#fff',
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
pointHoverBorderColor: 'rgba(54, 162, 235, 1)',
|
||||
tension: 0.1
|
||||
},
|
||||
{
|
||||
label: 'Series C',
|
||||
data: [18, 48, 77, 9, 100, 27, 40],
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||
borderColor: 'rgba(255, 99, 132, 1)',
|
||||
borderWidth: 2,
|
||||
pointBackgroundColor: 'rgba(255, 99, 132, 1)',
|
||||
pointBorderColor: '#fff',
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
pointHoverBorderColor: 'rgba(255, 99, 132, 1)',
|
||||
tension: 0.1
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
// Options for the chart
|
||||
const options = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: showLegend,
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: chartTitle,
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: showLabel,
|
||||
text: xAxis
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: showLabel,
|
||||
text: yAxis
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Function to randomize chart data
|
||||
const randomize = () => {
|
||||
setLineChartData(prevData => ({
|
||||
...prevData,
|
||||
datasets: prevData.datasets.map(dataset => ({
|
||||
...dataset,
|
||||
data: Array.from({ length: 7 }, () => Math.floor(Math.random() * 100) + 1)
|
||||
}))
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
width,
|
||||
height,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
position: 'relative'
|
||||
}}>
|
||||
<Box sx={{ flex: 1, minHeight: 0 }}>
|
||||
<Line data={lineChartData} options={options} />
|
||||
</Box>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
pt: 1
|
||||
}}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onClick={randomize}
|
||||
sx={{ fontSize: '0.75rem' }}
|
||||
>
|
||||
Randomize Data
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default LineChartComponent;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Pie } from 'react-chartjs-2'; // Import Pie chart from react-chartjs-2
|
||||
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';
|
||||
|
||||
// Register required elements for Pie chart
|
||||
|
||||
const PieChartComponent = () => {
|
||||
// Define pie chart data and labels
|
||||
const [pieChartData] = useState([30, 50, 20]);
|
||||
const [pieChartLabels] = useState(['SciFi', 'Drama', 'Comedy']);
|
||||
const [pieChartType] = useState('pie');
|
||||
|
||||
// Handle chart hover and click events
|
||||
const chartClicked = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
const chartHovered = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block' }}>
|
||||
<Pie
|
||||
data={{
|
||||
labels: pieChartLabels,
|
||||
datasets: [
|
||||
{
|
||||
data: pieChartData,
|
||||
backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], // Customize the colors
|
||||
},
|
||||
],
|
||||
}}
|
||||
type={pieChartType}
|
||||
onHover={chartHovered}
|
||||
onClick={chartClicked}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PieChartComponent;
|
||||
@@ -0,0 +1,125 @@
|
||||
// import React, { useState } from 'react';
|
||||
// import { Polar } from 'react-chartjs-2'; // Import PolarArea chart from react-chartjs-2
|
||||
// import { Chart as ChartJS, PolarAreaElement, Tooltip, Legend } from 'chart.js';
|
||||
|
||||
// ChartJS.register(PolarAreaElement, Tooltip, Legend); // Register the required elements for Polar Area chart
|
||||
|
||||
// const PolarChartComponent = () => {
|
||||
// // Define polar area chart data, labels, and type
|
||||
// const [polarAreaChartLabels] = useState([
|
||||
// 'Download Sales',
|
||||
// 'In-Store Sales',
|
||||
// 'Mail Sales',
|
||||
// 'Telesales',
|
||||
// 'Corporate Sales'
|
||||
// ]);
|
||||
// const [polarAreaChartData] = useState([
|
||||
// { data: [300, 500, 100, 40, 120], label: 'Series 1' }
|
||||
// ]);
|
||||
// const [polarAreaChartType] = useState('polarArea');
|
||||
|
||||
// // Handle chart hover and click events
|
||||
// const chartClicked = (e) => {
|
||||
// console.log(e);
|
||||
// };
|
||||
|
||||
// const chartHovered = (e) => {
|
||||
// console.log(e);
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div style={{ display: 'block' }}>
|
||||
// <Polar
|
||||
// data={{
|
||||
// labels: polarAreaChartLabels,
|
||||
// datasets: polarAreaChartData,
|
||||
// }}
|
||||
// type={polarAreaChartType}
|
||||
// onHover={chartHovered}
|
||||
// onClick={chartClicked}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default PolarChartComponent;
|
||||
|
||||
import React from 'react';
|
||||
import { PolarArea as Polar } from 'react-chartjs-2';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
RadialLinearScale,
|
||||
ArcElement,
|
||||
Tooltip,
|
||||
Legend,
|
||||
} from 'chart.js';
|
||||
|
||||
// Register required Chart.js components
|
||||
|
||||
|
||||
const PolarChartComponent = () => {
|
||||
// Chart data
|
||||
const data = {
|
||||
labels: [
|
||||
'Download Sales',
|
||||
'In-Store Sales',
|
||||
'Mail Sales',
|
||||
'Telesales',
|
||||
'Corporate Sales',
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
data: [300, 500, 100, 40, 120],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.6)',
|
||||
'rgba(54, 162, 235, 0.6)',
|
||||
'rgba(255, 206, 86, 0.6)',
|
||||
'rgba(75, 192, 192, 0.6)',
|
||||
'rgba(153, 102, 255, 0.6)',
|
||||
],
|
||||
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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Chart options
|
||||
const options = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (tooltipItem) => {
|
||||
return `${tooltipItem.label}: ${tooltipItem.raw}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
onClick: (event, elements) => {
|
||||
if (elements.length > 0) {
|
||||
const datasetIndex = elements[0].datasetIndex;
|
||||
const dataIndex = elements[0].index;
|
||||
console.log(
|
||||
`Clicked on dataset ${datasetIndex}, data index ${dataIndex}`
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ width: '50%', margin: 'auto' }}>
|
||||
<Polar data={data} options={options} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PolarChartComponent;
|
||||
@@ -0,0 +1,44 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Radar } from 'react-chartjs-2'; // Import Radar chart from react-chartjs-2
|
||||
import { Chart as ChartJS, RadarElement, Tooltip, Legend, PointElement, LineElement } from 'chart.js';
|
||||
|
||||
// ChartJS.register(RadarElement, Tooltip, Legend, PointElement, LineElement); // Register required chart elements for Radar chart
|
||||
|
||||
const RadarChartComponent = () => {
|
||||
// Define radar chart data, labels, and type
|
||||
const [radarChartLabels] = useState([
|
||||
'Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'
|
||||
]);
|
||||
|
||||
const [radarChartData] = useState([
|
||||
{ data: [65, 59, 90, 81, 56, 55, 40], label: 'Series A' },
|
||||
{ data: [28, 48, 40, 19, 96, 27, 100], label: 'Series B' }
|
||||
]);
|
||||
|
||||
const [radarChartType] = useState('radar');
|
||||
|
||||
// Handle chart hover and click events
|
||||
const chartClicked = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
const chartHovered = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block' }}>
|
||||
<Radar
|
||||
data={{
|
||||
labels: radarChartLabels,
|
||||
datasets: radarChartData,
|
||||
}}
|
||||
type={radarChartType}
|
||||
onHover={chartHovered}
|
||||
onClick={chartClicked}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RadarChartComponent;
|
||||
@@ -0,0 +1,55 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Scatter } from 'react-chartjs-2'; // Import Scatter chart from react-chartjs-2
|
||||
import { Chart as ChartJS, Tooltip, Legend, ScatterElement, PointElement } from 'chart.js';
|
||||
|
||||
// ChartJS.register(Tooltip, Legend, ScatterElement, PointElement); // Register required chart elements for scatter chart
|
||||
|
||||
const ScatterChartComponent = () => {
|
||||
// Define scatter chart data, labels, and type
|
||||
const [scatterChartLabels] = useState([
|
||||
'Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'
|
||||
]);
|
||||
|
||||
const [scatterChartData] = useState([
|
||||
{
|
||||
data: [
|
||||
{ x: 1, y: 1 },
|
||||
{ x: 2, y: 3 },
|
||||
{ x: 3, y: -2 },
|
||||
{ x: 4, y: 4 },
|
||||
{ x: 5, y: -3, r: 20 },
|
||||
],
|
||||
label: 'Series A',
|
||||
pointRadius: 10,
|
||||
backgroundColor: [
|
||||
'red', 'green', 'blue', 'purple', 'yellow', 'brown', 'magenta', 'cyan', 'orange', 'pink'
|
||||
]
|
||||
},
|
||||
]);
|
||||
|
||||
const [scatterChartType] = useState('scatter');
|
||||
|
||||
// Handle chart hover and click events
|
||||
const chartClicked = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
const chartHovered = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'block' }}>
|
||||
<Scatter
|
||||
data={{
|
||||
datasets: scatterChartData,
|
||||
}}
|
||||
type={scatterChartType}
|
||||
onHover={chartHovered}
|
||||
onClick={chartClicked}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ScatterChartComponent;
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const ToDoChartComponent = () => {
|
||||
// State to store todo list and current todo input value
|
||||
const [todo, setTodo] = useState('');
|
||||
const [todoList, setTodoList] = useState(['todo 1']);
|
||||
|
||||
// Add a new todo to the list
|
||||
const addTodo = (newTodo) => {
|
||||
if (newTodo.trim()) {
|
||||
setTodoList([...todoList, newTodo]);
|
||||
setTodo(''); // Clear the input field after adding
|
||||
}
|
||||
};
|
||||
|
||||
// Remove a todo from the list by index
|
||||
const removeTodo = (index) => {
|
||||
const updatedTodoList = todoList.filter((_, i) => i !== index);
|
||||
setTodoList(updatedTodoList);
|
||||
};
|
||||
|
||||
return (
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="c-col">#</th>
|
||||
<th>Item</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{todoList.map((todoItem, index) => (
|
||||
<tr className="ui basic segment" key={index}>
|
||||
<td className="c-col">{index + 1}</td>
|
||||
<td>{todoItem}</td>
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<button
|
||||
onClick={() => removeTodo(index)}
|
||||
style={{ background: 'none', border: 'none' }}
|
||||
>
|
||||
<i className="clr-icon times"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input
|
||||
value={todo}
|
||||
onChange={(e) => setTodo(e.target.value)}
|
||||
placeholder="Add Todo"
|
||||
className="clr-input"
|
||||
/>
|
||||
</td>
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<button
|
||||
onClick={() => addTodo(todo)}
|
||||
style={{ background: 'none', border: 'none' }}
|
||||
>
|
||||
<i className="clr-icon plus"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
|
||||
export default ToDoChartComponent;
|
||||
11
src/components/Dashboard/dashboardnew/schedule/Schedule.js
Normal file
11
src/components/Dashboard/dashboardnew/schedule/Schedule.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
const ScheduleComponent = () => {
|
||||
return (
|
||||
<div>
|
||||
<p>Schedule works!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ScheduleComponent;
|
||||
Reference in New Issue
Block a user