diff --git a/src/api/Areas/Dashboard/Controllers/FileSystemItemController.cs b/src/api/Areas/Dashboard/Controllers/FileSystemItemController.cs index 16c5c6ac..31ad415d 100644 --- a/src/api/Areas/Dashboard/Controllers/FileSystemItemController.cs +++ b/src/api/Areas/Dashboard/Controllers/FileSystemItemController.cs @@ -147,8 +147,7 @@ public IActionResult FindHistory() var user = _authorization.GetUser(); if (user == null) return Forbid(); - var result = _fileSystemHistoryItemService.FindHistoryByMonth(filter.StartDate ?? DateTime.UtcNow.AddYears(-1), filter.EndDate, filter.TenantId, filter.OrganizationId, filter.OperatingSystemItemId, filter.ServerItemServiceNowKey); - // var result = _fileSystemHistoryItemService.FindForUser(user.Id, filter); + var result = _fileSystemHistoryItemService.FindHistoryByMonthForUser(user.Id, filter.StartDate ?? DateTime.UtcNow.AddYears(-1), filter.EndDate, filter.TenantId, filter.OrganizationId, filter.OperatingSystemItemId, filter.ServerItemServiceNowKey); return new JsonResult(result.Select(fsi => new FileSystemHistoryItemModel(fsi))); } } diff --git a/src/dashboard/src/app/client/dashboard/page.tsx b/src/dashboard/src/app/client/dashboard/page.tsx index 7c217f1d..c28c7201 100644 --- a/src/dashboard/src/app/client/dashboard/page.tsx +++ b/src/dashboard/src/app/client/dashboard/page.tsx @@ -3,6 +3,7 @@ import { AllocationByOS, AllocationByStorageVolume, AllocationTable, + SegmentedBarChart, StorageTrendsChart, TotalStorage, } from '@/components/charts'; @@ -17,6 +18,7 @@ export default function Page() { + ); } diff --git a/src/dashboard/src/components/charts/bar/segmentedBarChart/IVolumeData.ts b/src/dashboard/src/components/charts/bar/segmentedBarChart/IVolumeData.ts new file mode 100644 index 00000000..14d1e515 --- /dev/null +++ b/src/dashboard/src/components/charts/bar/segmentedBarChart/IVolumeData.ts @@ -0,0 +1,7 @@ +export interface IVolumeData { + serviceNowKey: string; + name: string; + capacity: number; + availableSpace: number; + createdOn: string; +} diff --git a/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.module.scss b/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.module.scss index de386a31..625b1765 100644 --- a/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.module.scss +++ b/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.module.scss @@ -1,49 +1,54 @@ @import '@/styles/utils.scss'; .panel { - @include panel-style(250px, unset, unset, 1310px); + @include panel-style(250px, unset, unset, 1310px); - button { - @include export-btn; - } + button { + @include export-btn; + } } .customLegend { - margin: 20px 0; - display: flex; - justify-content: space-evenly; + margin: 20px 0; + display: flex; + justify-content: space-evenly; +} + +.legend { + display: flex; + flex-direction: row; } .legendColors { + display: inline-block; + + span { display: inline-block; + height: 20px; + width: 55px; + position: relative; - span { - display: inline-block; - height: 20px; - width: 55px; - position: relative; - - &::after { - position: absolute; - top: 23px; - font-size: $font-size-small; - color: $info-gray; - } - - &:first-of-type::after { - content: 'Used'; - } - - &:last-of-type::after { - content: 'Unused'; - } + &::after { + position: absolute; + top: 23px; + font-size: $font-size-small; + color: $info-gray; } + + &:first-of-type::after { + content: 'Used'; + } + + &:last-of-type::after { + content: 'Unused'; + } + } } .legendLabel { - display: inline; - margin-left: 10px; - font-weight: bold; - position: relative; - bottom: 4px; + display: inline; + margin-left: 10px; + font-weight: bold; + position: relative; + bottom: 4px; } \ No newline at end of file diff --git a/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.tsx b/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.tsx index 6b0324aa..b68a6281 100644 --- a/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.tsx +++ b/src/dashboard/src/components/charts/bar/segmentedBarChart/SegmentedBarChart.tsx @@ -1,76 +1,73 @@ 'use client'; import { Button } from '@/components/buttons'; -import styles from './SegmentedBarChart.module.scss'; import { Bar } from 'react-chartjs-2'; -import { defaultData } from './defaultData'; +import styles from './SegmentedBarChart.module.scss'; -import { - CategoryScale, - Chart as ChartJS, - BarElement, - Title, - Tooltip, - Legend, -} from 'chart.js'; +import { useDashboardFileSystemHistoryItems } from '@/hooks/dashboard'; +import { useFiltered } from '@/store'; +import { BarElement, CategoryScale, Chart as ChartJS, Legend, Title, Tooltip } from 'chart.js'; +import React from 'react'; +import { defaultOptions } from './defaultOptions'; +import { useStorageTrends } from './useStorageTrends'; +import { extractVolumeName } from './utils'; ChartJS.register(CategoryScale, BarElement, Title, Tooltip, Legend); -const options = { - scales: { - x: { - stacked: true, - }, - y: { - stacked: true, - }, - }, - plugins: { - legend: { - display: false - } - }, -}; +export interface ISegmentedBarChart { + maxVolumes?: number; +} -export const SegmentedBarChart: React.FC = () => { - const numDrives = 3; - const labelsArray = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', - ]; +export const SegmentedBarChart = ({ maxVolumes = 4 }: ISegmentedBarChart) => { + const serverItem = useFiltered((state) => state.serverItem); + const { findFileSystemHistoryItems } = useDashboardFileSystemHistoryItems(); - const data = defaultData(numDrives, labelsArray); + const data = useStorageTrends(1, maxVolumes); - const CustomLegend = () => ( -
- {data.datasets.filter((_, i) => i % 2 === 0).map((dataset, index) => ( -
-
- - + React.useEffect(() => { + if (serverItem) { + // A single server was selected, fetch the history for this server. + findFileSystemHistoryItems({ serverItemServiceNowKey: serverItem.serviceNowKey }).catch( + () => {}, + ); + } + }, [findFileSystemHistoryItems, serverItem]); + + const CustomLegend = React.useMemo( + () => ( +
+ {data.datasets + .filter((_, i) => i % 2 === 0) + .map((dataset, index) => ( +
+
+ + +
+
+

{extractVolumeName((dataset as any).name)}

+

{(dataset as any).capacity}

+
+
+ ))} + {data.volumes.length * 2 > data.datasets.length && ( +
+
{data.volumes.length} volumes
-

{`Drive ${index + 1}`}

-
- ))} -
+ )} +
+ ), + [data.datasets, data.volumes.length], ); return (
-

Storage Trends - Drive Storage

- +

Storage Trends - {serverItem?.name ?? 'Drive'} Storage

+ {CustomLegend}
- +