1
0
mirror of https://github.com/community-scripts/ProxmoxVE.git synced 2025-02-01 14:51:50 +00:00

add popup, table & chart

This commit is contained in:
CanbiZ 2025-01-30 13:43:24 +01:00
parent e2b548a7c3
commit a38e9070ef
3 changed files with 99 additions and 33 deletions

View File

@ -166,7 +166,7 @@ const DataFetcher: React.FC = () => {
{showChart ? "Hide Chart" : "Show Chart"}
</button>
</div>
{showChart && <ApplicationChart data={filteredData} />}
<ApplicationChart data={filteredData} />
<div className="mb-4 flex justify-between items-center">
<p className="text-lg font-bold">{filteredData.length} results found</p>
<select value={itemsPerPage} onChange={handleItemsPerPageChange} className="p-2 border">

View File

@ -3,7 +3,8 @@
import React, { useState } from "react";
import { Pie } from "react-chartjs-2";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import ChartDataLabels from "chartjs-plugin-datalabels";
import ChartDataLabels from "chartjs-plugin-datalabels";
import Modal from "@/components/Modal";
ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);
@ -12,6 +13,8 @@ interface ApplicationChartProps {
}
const ApplicationChart: React.FC<ApplicationChartProps> = ({ data }) => {
const [isChartOpen, setIsChartOpen] = useState(false);
const [isTableOpen, setIsTableOpen] = useState(false);
const [chartStartIndex, setChartStartIndex] = useState(0);
const appCounts: Record<string, number> = {};
@ -42,40 +45,74 @@ const ApplicationChart: React.FC<ApplicationChartProps> = ({ data }) => {
return (
<div className="mt-6 text-center">
<div className="w-1/2 mx-auto my-6">
<Pie
data={chartData}
options={{
plugins: {
legend: { display: false },
datalabels: {
color: "white",
font: { weight: "bold" },
formatter: (value, context) => {
return context.chart.data.labels?.[context.dataIndex] || "";
<button
onClick={() => setIsChartOpen(true)}
className="m-2 p-2 bg-blue-500 text-white rounded"
>
📊 Open Chart
</button>
<button
onClick={() => setIsTableOpen(true)}
className="m-2 p-2 bg-green-500 text-white rounded"
>
📋 Open Table
</button>
<Modal isOpen={isChartOpen} onClose={() => setIsChartOpen(false)}>
<h2 className="text-xl font-bold mb-4">Top Applications (Chart)</h2>
<div className="w-3/4 mx-auto">
<Pie
data={chartData}
options={{
plugins: {
legend: { display: false },
datalabels: {
color: "white",
font: { weight: "bold" },
formatter: (value, context) =>
context.chart.data.labels?.[context.dataIndex] || "",
},
},
},
}}
/>
</div>
}}
/>
</div>
<div className="flex justify-center space-x-4 mt-4">
<button
onClick={() => setChartStartIndex(Math.max(0, chartStartIndex - 20))}
disabled={chartStartIndex === 0}
className="p-2 border rounded bg-blue-500 text-white"
>
Vorherige 20
</button>
<button
onClick={() => setChartStartIndex(chartStartIndex + 20)}
disabled={chartStartIndex + 20 >= sortedApps.length}
className="p-2 border rounded bg-blue-500 text-white"
>
Nächste 20
</button>
</div>
</Modal>
<div className="flex justify-center space-x-4">
<button
onClick={() => setChartStartIndex(Math.max(0, chartStartIndex - 20))}
disabled={chartStartIndex === 0}
className={`p-2 border rounded ${chartStartIndex === 0 ? "bg-gray-400 cursor-not-allowed" : "bg-blue-500 text-white"}`}
>
Last 20
</button>
<button
onClick={() => setChartStartIndex(chartStartIndex + 20)}
disabled={chartStartIndex + 20 >= sortedApps.length}
className={`p-2 border rounded ${chartStartIndex + 20 >= sortedApps.length ? "bg-gray-400 cursor-not-allowed" : "bg-blue-500 text-white"}`}
>
Next 20
</button>
</div>
<Modal isOpen={isTableOpen} onClose={() => setIsTableOpen(false)}>
<h2 className="text-xl font-bold mb-4">Application Count Table</h2>
<table className="w-full border-collapse border border-gray-600">
<thead>
<tr className="bg-gray-800 text-white">
<th className="p-2 border">Application</th>
<th className="p-2 border">Count</th>
</tr>
</thead>
<tbody>
{sortedApps.map(([name, count]) => (
<tr key={name} className="hover:bg-gray-200">
<td className="p-2 border">{name}</td>
<td className="p-2 border">{count}</td>
</tr>
))}
</tbody>
</table>
</Modal>
</div>
);
};

View File

@ -0,0 +1,29 @@
"use client";
import React from "react";
interface ModalProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
}
const Modal: React.FC<ModalProps> = ({ isOpen, onClose, children }) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50">
<div className="bg-white p-6 rounded-lg shadow-lg w-3/4 max-w-4xl relative">
<button
onClick={onClose}
className="absolute top-2 right-2 bg-red-500 text-white p-1 rounded"
>
</button>
{children}
</div>
</div>
);
};
export default Modal;