[Dashboards] Graph gauge chart component (#14035)

closes https://github.com/twentyhq/core-team-issues/issues/1374
figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=C0BfdTmTl69RKZvU-0

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
nitin 2025-08-22 13:05:47 +05:30 committed by GitHub
parent 953f1e7207
commit 9e9fa6325f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 799 additions and 62 deletions

View file

@ -45,8 +45,9 @@
"@lingui/core": "^5.1.2",
"@lingui/detect-locale": "^5.2.0",
"@lingui/react": "^5.1.2",
"@nivo/core": "^0.87.0",
"@nivo/line": "^0.87.0",
"@nivo/core": "^0.99.0",
"@nivo/line": "^0.99.0",
"@nivo/radial-bar": "^0.99.0",
"@react-pdf/renderer": "^4.1.6",
"@scalar/api-reference-react": "^0.4.36",
"@tiptap/core": "^2.10.4",

View file

@ -44,7 +44,7 @@ export enum AdminPanelHealthServiceStatus {
export type AdminPanelWorkerQueueHealth = {
__typename?: 'AdminPanelWorkerQueueHealth';
id: Scalars['UUID'];
id: Scalars['String'];
queueName: Scalars['String'];
status: AdminPanelHealthServiceStatus;
};
@ -2753,7 +2753,7 @@ export type QueueMetricsDataPoint = {
export type QueueMetricsSeries = {
__typename?: 'QueueMetricsSeries';
data: Array<QueueMetricsDataPoint>;
id: Scalars['UUID'];
id: Scalars['String'];
};
export enum QueueMetricsTimeRange {

View file

@ -44,7 +44,7 @@ export enum AdminPanelHealthServiceStatus {
export type AdminPanelWorkerQueueHealth = {
__typename?: 'AdminPanelWorkerQueueHealth';
id: Scalars['UUID'];
id: Scalars['String'];
queueName: Scalars['String'];
status: AdminPanelHealthServiceStatus;
};
@ -2613,7 +2613,7 @@ export type QueueMetricsDataPoint = {
export type QueueMetricsSeries = {
__typename?: 'QueueMetricsSeries';
data: Array<QueueMetricsDataPoint>;
id: Scalars['UUID'];
id: Scalars['String'];
};
export enum QueueMetricsTimeRange {

View file

@ -0,0 +1,238 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { ResponsiveRadialBar } from '@nivo/radial-bar';
import { useState } from 'react';
import {
AppTooltip,
H1Title,
H1TitleFontColor,
IconArrowUpRight,
TooltipDelay,
} from 'twenty-ui/display';
type GraphWidgetGaugeChartProps = {
value: number;
min: number;
max: number;
unit: string;
showValue?: boolean;
legendLabel: string;
tooltipHref: string;
id: string;
};
const StyledContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
width: 100%;
`;
const StyledChartContainer = styled.div`
flex: 1;
position: relative;
width: 100%;
`;
const StyledH1Title = styled(H1Title)`
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -150%);
`;
const StyledLegendContainer = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(3)};
justify-content: center;
`;
const StyledLegendItem = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
font-size: ${({ theme }) => theme.font.size.xs};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
`;
const StyledLegendLabel = styled.span`
color: ${({ theme }) => theme.font.color.light};
`;
const StyledLegendValue = styled.span`
color: ${({ theme }) => theme.font.color.primary};
`;
const StyledTooltipContent = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledTooltipRow = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.extraLight};
display: flex;
font-size: ${({ theme }) => theme.font.size.xs};
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledDot = styled.div`
background: ${({ theme }) => theme.color.blue};
border-radius: 50%;
height: 6px;
width: 6px;
flex-shrink: 0;
`;
const StyledTooltipValue = styled.span`
margin-left: auto;
white-space: nowrap;
`;
const StyledTooltipLink = styled.a`
display: flex;
align-items: center;
color: ${({ theme }) => theme.font.color.light};
cursor: pointer;
text-decoration: none;
&:hover {
color: ${({ theme }) => theme.font.color.secondary};
}
`;
export const GraphWidgetGaugeChart = ({
value,
min,
max,
unit,
showValue = true,
legendLabel,
tooltipHref,
id,
}: GraphWidgetGaugeChartProps) => {
const theme = useTheme();
const [isHovered, setIsHovered] = useState(false);
const formatValue = (val: number): string => {
if (val % 1 !== 0) {
return val.toFixed(1);
}
return val.toString();
};
const displayValue = formatValue(value);
const normalizedValue = max === min ? 0 : ((value - min) / (max - min)) * 100;
const clampedNormalizedValue = Math.max(0, Math.min(100, normalizedValue));
const data = [
{
id: 'gauge',
data: [
{ x: 'value', y: clampedNormalizedValue },
{ x: 'empty', y: 100 - clampedNormalizedValue },
],
},
];
const gradientColors = isHovered
? {
start: theme.adaptiveColors.blue4,
end: theme.adaptiveColors.blue3,
}
: {
start: theme.adaptiveColors.blue2,
end: theme.adaptiveColors.blue1,
};
const gradientId = `gaugeGradient-${id}`;
const defs = [
{
id: gradientId,
type: 'linearGradient',
colors: [
{ offset: 0, color: gradientColors.start },
{ offset: 100, color: gradientColors.end },
],
},
];
const tooltipContent = (
<StyledTooltipContent>
<StyledTooltipRow>
<StyledDot />
<span>{legendLabel}</span>
<StyledTooltipValue>{`${displayValue}${unit}`}</StyledTooltipValue>
</StyledTooltipRow>
<StyledTooltipLink href={tooltipHref}>
<span>{t`Click to see data`}</span>
<IconArrowUpRight size={theme.icon.size.sm} />
</StyledTooltipLink>
</StyledTooltipContent>
);
return (
<>
<StyledContainer
id={id}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<StyledChartContainer>
<ResponsiveRadialBar
data={data}
startAngle={-90}
endAngle={90}
innerRadius={0.7}
padding={0.2}
colors={[`url(#${gradientId})`, theme.background.tertiary]}
defs={defs}
fill={[
{
match: (d: { x: string }) => d.x === 'value',
id: gradientId,
},
]}
enableTracks={false}
enableRadialGrid={false}
enableCircularGrid={false}
enableLabels={false}
isInteractive={false}
radialAxisStart={null}
radialAxisEnd={null}
circularAxisInner={null}
circularAxisOuter={null}
/>
{showValue && (
<StyledH1Title
title={`${displayValue}${unit}`}
fontColor={H1TitleFontColor.Primary}
/>
)}
</StyledChartContainer>
<StyledLegendContainer>
<StyledLegendItem>
<StyledDot />
<StyledLegendLabel>{legendLabel}</StyledLegendLabel>
<StyledLegendValue>{`${displayValue}${unit}`}</StyledLegendValue>
</StyledLegendItem>
</StyledLegendContainer>
</StyledContainer>
<AppTooltip
anchorSelect={`#${id}`}
place="top-start"
noArrow
delay={TooltipDelay.noDelay}
clickable
>
{tooltipContent}
</AppTooltip>
</>
);
};

View file

@ -0,0 +1,253 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { CatalogDecorator, ComponentDecorator } from 'twenty-ui/testing';
import { GraphWidgetGaugeChart } from '../GraphWidgetGaugeChart';
const meta: Meta<typeof GraphWidgetGaugeChart> = {
title: 'Modules/Dashboards/Graphs/GraphWidgetGaugeChart',
component: GraphWidgetGaugeChart,
decorators: [ComponentDecorator],
parameters: {
layout: 'centered',
},
argTypes: {
value: {
control: { type: 'number' },
},
min: {
control: { type: 'number' },
},
max: {
control: { type: 'number' },
},
unit: {
control: 'text',
},
showValue: {
control: 'boolean',
},
legendLabel: {
control: 'text',
},
tooltipHref: {
control: 'text',
},
id: {
control: 'text',
},
},
};
export default meta;
type Story = StoryObj<typeof GraphWidgetGaugeChart>;
const Container = ({ children }: { children: React.ReactNode }) => (
<div style={{ width: '250px', height: '200px' }}>{children}</div>
);
export const Default: Story = {
args: {
value: 50,
min: 0,
max: 100,
unit: '%',
showValue: true,
legendLabel: 'Conversion rate',
tooltipHref: 'https://example.com',
id: 'gauge-chart-default',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};
export const Catalog: Story = {
decorators: [CatalogDecorator],
parameters: {
catalog: {
dimensions: [
{
name: 'value',
values: [0, 25, 50, 75, 100],
props: (value: number) => ({
value,
min: 0,
max: 100,
unit: '%',
id: `gauge-chart-catalog-${value}`,
}),
labels: (value: number) => {
const labelMap: Record<number, string> = {
0: 'Empty',
25: 'Quarter',
50: 'Half',
75: 'Three Quarters',
100: 'Full',
};
return labelMap[value] ?? `${value}%`;
},
},
],
},
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={true}
legendLabel="Percentage"
tooltipHref="https://example.com"
id={args.id}
/>
</Container>
),
};
export const WithoutValue: Story = {
args: {
value: 65,
min: 0,
max: 100,
unit: '%',
showValue: false,
legendLabel: 'Conversion rate',
tooltipHref: 'https://example.com',
id: 'gauge-chart-without-value',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};
export const Revenue: Story = {
args: {
value: 750,
min: 0,
max: 1000,
unit: 'K',
showValue: true,
legendLabel: 'Revenue',
tooltipHref: 'https://example.com',
id: 'gauge-chart-revenue',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};
export const Temperature: Story = {
args: {
value: 22,
min: -10,
max: 40,
unit: '°C',
showValue: true,
legendLabel: 'Temperature',
tooltipHref: 'https://example.com',
id: 'gauge-chart-temperature',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};
export const Storage: Story = {
args: {
value: 384,
min: 0,
max: 512,
unit: 'GB',
showValue: true,
legendLabel: 'Storage Used',
tooltipHref: 'https://example.com',
id: 'gauge-chart-storage',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};
export const Rating: Story = {
args: {
value: 4.2,
min: 0,
max: 5,
unit: ' ⭐',
showValue: true,
legendLabel: 'Average Rating',
tooltipHref: 'https://example.com',
id: 'gauge-chart-rating',
},
render: (args) => (
<Container>
<GraphWidgetGaugeChart
value={args.value}
min={args.min}
max={args.max}
unit={args.unit}
showValue={args.showValue}
legendLabel={args.legendLabel}
tooltipHref={args.tooltipHref}
id={args.id}
/>
</Container>
),
};

View file

@ -1,5 +1,5 @@
import styled from '@emotion/styled';
import type { Point } from '@nivo/line';
import type { Point, LineSeries } from '@nivo/line';
import { type ReactElement } from 'react';
const StyledTooltipContainer = styled.div`
@ -45,7 +45,7 @@ const StyledTooltipValue = styled.span`
type WorkerMetricsTooltipProps = {
slice: {
points: readonly Point[];
points: readonly Point<LineSeries>[];
};
};
@ -55,11 +55,11 @@ export const WorkerMetricsTooltip = ({
return (
<StyledTooltipContainer>
{slice.points.map((point) => (
<StyledTooltipItem key={point.id} color={point.serieColor}>
<StyledTooltipColorCircle color={point.serieColor} />
<StyledTooltipItem key={point.id} color={point.seriesColor}>
<StyledTooltipColorCircle color={point.seriesColor} />
<StyledTooltipDataRow>
<span>{point.serieId}</span>
<StyledTooltipValue>{String(point.data.y)}</StyledTooltipValue>
<span>{point.seriesId}</span>
<StyledTooltipValue>{point.data.yFormatted}</StyledTooltipValue>
</StyledTooltipDataRow>
</StyledTooltipItem>
))}

View file

@ -1,11 +1,10 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { AdminPanelHealthServiceStatus } from 'src/engine/core-modules/admin-panel/enums/admin-panel-health-service-status.enum';
@ObjectType()
export class AdminPanelWorkerQueueHealth {
@Field(() => UUIDScalarType)
@Field(() => String)
id: string;
@Field(() => String)

View file

@ -1,11 +1,10 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { QueueMetricsDataPoint } from 'src/engine/core-modules/admin-panel/dtos/queue-metrics-data-point.dto';
@ObjectType()
export class QueueMetricsSeries {
@Field(() => UUIDScalarType)
@Field(() => String)
id: string;
@Field(() => [QueueMetricsDataPoint])

339
yarn.lock
View file

@ -9666,34 +9666,55 @@ __metadata:
languageName: node
linkType: hard
"@nivo/annotations@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/annotations@npm:0.87.0"
"@nivo/annotations@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/annotations@npm:0.99.0"
dependencies:
"@nivo/colors": "npm:0.87.0"
"@nivo/core": "npm:0.87.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2"
"@nivo/colors": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">= 16.14.0 < 19.0.0"
checksum: 10c0/603599c5e697b987ccd360fc835fd4152b43e9facf5542369669faad9352e56a093c6b9dff8c3b4114d25267144478c89ad834fe4929b0ec223c7600795b276b
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/0aa6639fa60bf3aeb87e7e8b04150a2ad59413159fcad70e8706246ec3cdddf95b2f4f2af732e34faeffd3f894ce6c9a5ac4c60c0704f330fe8337a7657a36e2
languageName: node
linkType: hard
"@nivo/axes@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/axes@npm:0.87.0"
"@nivo/arcs@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/arcs@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.87.0"
"@nivo/scales": "npm:0.87.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2"
"@nivo/colors": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/text": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/core": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@types/d3-shape": "npm:^3.1.6"
d3-shape: "npm:^3.2.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/443b9cf8673d2159dfff6e6caf12081c6f6d00fa66d7da700adcb31437d0b7e01bedf6cb1d994856e696d657599cb819bb8429664fb54dd19fdd6f2fdd3bb60e
languageName: node
linkType: hard
"@nivo/axes@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/axes@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.99.0"
"@nivo/scales": "npm:0.99.0"
"@nivo/text": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@types/d3-format": "npm:^1.4.1"
"@types/d3-time-format": "npm:^2.3.1"
d3-format: "npm:^1.4.4"
d3-time-format: "npm:^3.0.0"
peerDependencies:
react: ">= 16.14.0 < 19.0.0"
checksum: 10c0/7af5f6ea3101ab957b171713276ff2acb1dee608fe96876a3afac8ede5327856ddfcd3046d084fbe417ef032080caa87736187d3b77d2f6f79f65c7d70fa5bb2
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/90e3f82c8dcea1db932a000e4df197f94b82444db8af37d1ee9bc40a6e36e8551f6c69bab46cae6061c9daffd787c1c5051e134014d941a05e6920979addca11
languageName: node
linkType: hard
@ -9737,7 +9758,26 @@ __metadata:
languageName: node
linkType: hard
"@nivo/core@npm:0.87.0, @nivo/core@npm:^0.87.0":
"@nivo/colors@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/colors@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@types/d3-color": "npm:^3.0.0"
"@types/d3-scale": "npm:^4.0.8"
"@types/d3-scale-chromatic": "npm:^3.0.0"
d3-color: "npm:^3.1.0"
d3-scale: "npm:^4.0.2"
d3-scale-chromatic: "npm:^3.0.0"
lodash: "npm:^4.17.21"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/391976c8d52e3a6095f1f15e9666984271e9ff15359170f2b145f658c171c9e0e15ae80b994fbd7125fe46bee3ae2e25c99f75205f2c746446ab2542bf50c883
languageName: node
linkType: hard
"@nivo/core@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/core@npm:0.87.0"
dependencies:
@ -9759,6 +9799,30 @@ __metadata:
languageName: node
linkType: hard
"@nivo/core@npm:0.99.0, @nivo/core@npm:^0.99.0":
version: 0.99.0
resolution: "@nivo/core@npm:0.99.0"
dependencies:
"@nivo/theming": "npm:0.99.0"
"@nivo/tooltip": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@types/d3-shape": "npm:^3.1.6"
d3-color: "npm:^3.1.0"
d3-format: "npm:^1.4.4"
d3-interpolate: "npm:^3.0.1"
d3-scale: "npm:^4.0.2"
d3-scale-chromatic: "npm:^3.0.0"
d3-shape: "npm:^3.2.0"
d3-time-format: "npm:^3.0.0"
lodash: "npm:^4.17.21"
react-virtualized-auto-sizer: "npm:^1.0.26"
use-debounce: "npm:^10.0.4"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/b12744a65ca6f07d663b4a72110a88bb4f53a2033a70ca37d5b4fec6e416bd509d9e339fa38e728c3e1eaa8b6d099c4dea1208209f67185ad8911f21487de0b0
languageName: node
linkType: hard
"@nivo/legends@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/legends@npm:0.87.0"
@ -9773,38 +9837,121 @@ __metadata:
languageName: node
linkType: hard
"@nivo/line@npm:^0.87.0":
version: 0.87.0
resolution: "@nivo/line@npm:0.87.0"
"@nivo/legends@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/legends@npm:0.99.0"
dependencies:
"@nivo/annotations": "npm:0.87.0"
"@nivo/axes": "npm:0.87.0"
"@nivo/colors": "npm:0.87.0"
"@nivo/core": "npm:0.87.0"
"@nivo/legends": "npm:0.87.0"
"@nivo/scales": "npm:0.87.0"
"@nivo/tooltip": "npm:0.87.0"
"@nivo/voronoi": "npm:0.87.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2"
d3-shape: "npm:^3.2.0"
"@nivo/colors": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/text": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@types/d3-scale": "npm:^4.0.8"
d3-scale: "npm:^4.0.2"
peerDependencies:
react: ">= 16.14.0 < 19.0.0"
checksum: 10c0/8ca8e4fbfe988a9c59c20f3c20caa391589f19af94d460e22925b9659e9058b82fddd4039c76e8242c6fd2676c15c6c8202041a9d3115397bdc9fe322ea7a06d
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/7baca3ce92aeb8d159ab92e0eb841417c6e84ccde4e664546c7f39cd7576664342d5ed6b71e04dbdddb240db5567490e804dcfe9f66a3d003ac9dbe28b21ca12
languageName: node
linkType: hard
"@nivo/scales@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/scales@npm:0.87.0"
"@nivo/line@npm:^0.99.0":
version: 0.99.0
resolution: "@nivo/line@npm:0.99.0"
dependencies:
"@nivo/annotations": "npm:0.99.0"
"@nivo/axes": "npm:0.99.0"
"@nivo/colors": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/legends": "npm:0.99.0"
"@nivo/scales": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@nivo/tooltip": "npm:0.99.0"
"@nivo/voronoi": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@types/d3-shape": "npm:^3.1.6"
d3-shape: "npm:^3.2.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/72c467aa48168d0ecc7a63e732783eba7a8de149d76ea416d116789485044abef5ba727edea50c9e2518d407d7d752d6d8c4a59e2b7e12736c9f2fe08fc55f4e
languageName: node
linkType: hard
"@nivo/polar-axes@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/polar-axes@npm:0.99.0"
dependencies:
"@nivo/arcs": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/scales": "npm:0.99.0"
"@nivo/text": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/29bba26e4529faef9d9b9bc7fef9cf23ff56f06c5fe108497f84a6ac91e31bfc8d4df60ad0de489d850a7d6e7fe786bda2f57f006db76a211f426349247f55f9
languageName: node
linkType: hard
"@nivo/radial-bar@npm:^0.99.0":
version: 0.99.0
resolution: "@nivo/radial-bar@npm:0.99.0"
dependencies:
"@nivo/arcs": "npm:0.99.0"
"@nivo/colors": "npm:0.99.0"
"@nivo/core": "npm:0.99.0"
"@nivo/legends": "npm:0.99.0"
"@nivo/polar-axes": "npm:0.99.0"
"@nivo/scales": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@nivo/tooltip": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
"@types/d3-scale": "npm:^4.0.8"
"@types/d3-shape": "npm:^3.1.6"
d3-scale: "npm:^4.0.2"
d3-shape: "npm:^3.2.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/85387e839074c27f09041ed446d8afb8715eed39812dcf29e61608b89177cf92559eb550172442cf899196f608c70278d720258f37373d6a72700398d4b5157c
languageName: node
linkType: hard
"@nivo/scales@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/scales@npm:0.99.0"
dependencies:
"@types/d3-interpolate": "npm:^3.0.4"
"@types/d3-scale": "npm:^4.0.8"
"@types/d3-time": "npm:^1.1.1"
"@types/d3-time-format": "npm:^3.0.0"
d3-interpolate: "npm:^3.0.1"
d3-scale: "npm:^4.0.2"
d3-time: "npm:^1.0.11"
d3-time-format: "npm:^3.0.0"
lodash: "npm:^4.17.21"
checksum: 10c0/7df01cd72fecbd82791c8aeb99439aa23ff54229ad9044e111fc02d51d0a2f7e8d67a75ed39854d829a7ab274580ca2e252931be5062eff3d08c48ab1580c7bd
checksum: 10c0/64baf2f198b8b31cdfaab61df84f5e4a0721b3f88c167bfe6bb7af6548a7f1f2ecdd39d11dbf114f2ab8aa034133d2fee5ec04a80f44de39ed1047b7ec9a2c08
languageName: node
linkType: hard
"@nivo/text@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/text@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/add071c276ad4809a771e4d42b2dbd9912e22a213828b1407c4caaa09ac623f0978854be11b6844a9c494fda130075325214b9ad75a0c0727241b335477dad88
languageName: node
linkType: hard
"@nivo/theming@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/theming@npm:0.99.0"
dependencies:
lodash: "npm:^4.17.21"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/bc69e59a632e3106e061c44b0f7c86d8f757002b147e7e9ec93a0b11286ade71d67cf90d720484867c7dc933f0b33ec4135814adc7100f70700799f6ff05f59b
languageName: node
linkType: hard
@ -9820,19 +9967,33 @@ __metadata:
languageName: node
linkType: hard
"@nivo/voronoi@npm:0.87.0":
version: 0.87.0
resolution: "@nivo/voronoi@npm:0.87.0"
"@nivo/tooltip@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/tooltip@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.87.0"
"@nivo/tooltip": "npm:0.87.0"
"@nivo/core": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@react-spring/web": "npm:9.4.5 || ^9.7.2 || ^10.0"
peerDependencies:
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/0446ce0c31f2de20854a1e793bb222ee5f26d723df7c5008de0f853f5e0deafee7865bcca9b3a0584a6cb8e2b015d7875b487a880d5ae9dab8d2489bb8e9ba5b
languageName: node
linkType: hard
"@nivo/voronoi@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/voronoi@npm:0.99.0"
dependencies:
"@nivo/core": "npm:0.99.0"
"@nivo/theming": "npm:0.99.0"
"@nivo/tooltip": "npm:0.99.0"
"@types/d3-delaunay": "npm:^6.0.4"
"@types/d3-scale": "npm:^4.0.8"
d3-delaunay: "npm:^6.0.4"
d3-scale: "npm:^4.0.2"
peerDependencies:
react: ">= 16.14.0 < 19.0.0"
checksum: 10c0/02bc6bb36ef1211bfdc440c135766f041dfba47b0d6c1e3b2748f7cde20ccec106621e559640a611b36b3e9d6a0e8d0492cace9143efbbf7aeb5499741eecf33
react: ^16.14 || ^17.0 || ^18.0 || ^19.0
checksum: 10c0/948610972553ec31785804a03304c14e81a5aabae077560803721068582d6fcde8d6d4bc71c77f0ca6c1c6350f48bb638dda15ffd3aa8878b598017c0be117f0
languageName: node
linkType: hard
@ -15076,6 +15237,18 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/animated@npm:~10.0.1":
version: 10.0.1
resolution: "@react-spring/animated@npm:10.0.1"
dependencies:
"@react-spring/shared": "npm:~10.0.1"
"@react-spring/types": "npm:~10.0.1"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/aaccd4a8b0280ac846d463b253ad8f092ee4afc9dbedc8e77616adf5399ffec755344f09fdd8487cadaf815840dff84d354d1143579c27c2fcd6937549b5fc40
languageName: node
linkType: hard
"@react-spring/animated@npm:~9.7.4":
version: 9.7.4
resolution: "@react-spring/animated@npm:9.7.4"
@ -15088,6 +15261,19 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/core@npm:9.4.5 || ^9.7.2 || ^10.0, @react-spring/core@npm:~10.0.1":
version: 10.0.1
resolution: "@react-spring/core@npm:10.0.1"
dependencies:
"@react-spring/animated": "npm:~10.0.1"
"@react-spring/shared": "npm:~10.0.1"
"@react-spring/types": "npm:~10.0.1"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/059b122dda4138e5e7e461abd49350921e326735ca9a1d8aa19b1fdbae0937661b5f71af6fe82fd8f59e8db5549627849b38cc3f7ef2ec7ee9c93c3d6225174f
languageName: node
linkType: hard
"@react-spring/core@npm:~9.7.4":
version: 9.7.4
resolution: "@react-spring/core@npm:9.7.4"
@ -15101,6 +15287,13 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/rafz@npm:~10.0.1":
version: 10.0.1
resolution: "@react-spring/rafz@npm:10.0.1"
checksum: 10c0/cba76f143d3a06f79dd0c09f7aefd17df9cca9b2c1ef7f9103255e5351326f4a42a5a1366f731a78f74380d96ba683bcc2a49312ed1e4b9e9e249e72c9ff68cb
languageName: node
linkType: hard
"@react-spring/rafz@npm:~9.7.4":
version: 9.7.4
resolution: "@react-spring/rafz@npm:9.7.4"
@ -15108,6 +15301,18 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/shared@npm:~10.0.1":
version: 10.0.1
resolution: "@react-spring/shared@npm:10.0.1"
dependencies:
"@react-spring/rafz": "npm:~10.0.1"
"@react-spring/types": "npm:~10.0.1"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/f056aaa018b3744afd8244e8eea24534d32f92fad9ace815b80e159b296fb5db148e2c9bd840ad9a5188e7a3c0778fd564b8af9ae02cd500e019a228398fb3cf
languageName: node
linkType: hard
"@react-spring/shared@npm:~9.7.4":
version: 9.7.4
resolution: "@react-spring/shared@npm:9.7.4"
@ -15120,6 +15325,13 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/types@npm:~10.0.1":
version: 10.0.1
resolution: "@react-spring/types@npm:10.0.1"
checksum: 10c0/260890f9c156dc69b77c846510017156d8c0a07cce70edc7c108e57b0cf4122b26a15e724b191481a51b2c914296de9e81d56618b2c339339d4b221930691baa
languageName: node
linkType: hard
"@react-spring/types@npm:~9.7.4":
version: 9.7.4
resolution: "@react-spring/types@npm:9.7.4"
@ -15142,6 +15354,21 @@ __metadata:
languageName: node
linkType: hard
"@react-spring/web@npm:9.4.5 || ^9.7.2 || ^10.0":
version: 10.0.1
resolution: "@react-spring/web@npm:10.0.1"
dependencies:
"@react-spring/animated": "npm:~10.0.1"
"@react-spring/core": "npm:~10.0.1"
"@react-spring/shared": "npm:~10.0.1"
"@react-spring/types": "npm:~10.0.1"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/a0c788c9fd881ccb834feb22fc0694e74e59f7b76e498f0096f5b65e2c9812513955bf45ee27d7c5348f56a7bba7c5a6961d4be663728bb2172fe5aa6b6bdfc4
languageName: node
linkType: hard
"@react-stately/calendar@npm:^3.7.0":
version: 3.7.0
resolution: "@react-stately/calendar@npm:3.7.0"
@ -19331,7 +19558,7 @@ __metadata:
languageName: node
linkType: hard
"@types/d3-interpolate@npm:*":
"@types/d3-interpolate@npm:*, @types/d3-interpolate@npm:^3.0.4":
version: 3.0.4
resolution: "@types/d3-interpolate@npm:3.0.4"
dependencies:
@ -45865,6 +46092,16 @@ __metadata:
languageName: node
linkType: hard
"react-virtualized-auto-sizer@npm:^1.0.26":
version: 1.0.26
resolution: "react-virtualized-auto-sizer@npm:1.0.26"
peerDependencies:
react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/788b438c9cb55f94a0561ef07e6bb6e5051ad3d5ececd9b2131014324ffe773b507ac7060f965e44c84bd8d6aa85c686754ac944384878c97f7304c0473a7754
languageName: node
linkType: hard
"react@npm:18.3.1, react@npm:^18, react@npm:^18.2.0":
version: 18.3.1
resolution: "react@npm:18.3.1"
@ -50724,8 +50961,9 @@ __metadata:
"@lingui/react": "npm:^5.1.2"
"@lingui/swc-plugin": "npm:^5.6.0"
"@lingui/vite-plugin": "npm:^5.1.2"
"@nivo/core": "npm:^0.87.0"
"@nivo/line": "npm:^0.87.0"
"@nivo/core": "npm:^0.99.0"
"@nivo/line": "npm:^0.99.0"
"@nivo/radial-bar": "npm:^0.99.0"
"@react-pdf/renderer": "npm:^4.1.6"
"@scalar/api-reference-react": "npm:^0.4.36"
"@tiptap/core": "npm:^2.10.4"
@ -52497,6 +52735,15 @@ __metadata:
languageName: node
linkType: hard
"use-debounce@npm:^10.0.4":
version: 10.0.5
resolution: "use-debounce@npm:10.0.5"
peerDependencies:
react: "*"
checksum: 10c0/8232538aa2e2b1252716ef2918204709f16bd53661b56a3a29ad790bf61bc7cbf3bb1126d888408db276a2b05fa6a941e9452149be14bfe438aa22054ccf4e4a
languageName: node
linkType: hard
"use-isomorphic-layout-effect@npm:^1.1.1":
version: 1.1.2
resolution: "use-isomorphic-layout-effect@npm:1.1.2"