1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-27 13:49:10 +02:00

fix: Data usage metrics chart included per day annotion (#6941)

Added a small annotation to the chart on how much data is included in
the pro plan on average per day to make it easier to spot when a
customer average above the included threshold.


![image](https://github.com/Unleash/unleash/assets/158948/c3105f87-03e0-4b27-9e3f-53c749c78078)
This commit is contained in:
Ivar Conradi Østhus 2024-04-29 10:35:01 +02:00 committed by GitHub
parent 010c4ee57b
commit 3978c690e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 67 additions and 29 deletions

View File

@ -72,6 +72,7 @@
"cartesian": "^1.0.1", "cartesian": "^1.0.1",
"chart.js": "3.9.1", "chart.js": "3.9.1",
"chartjs-adapter-date-fns": "3.0.0", "chartjs-adapter-date-fns": "3.0.0",
"chartjs-plugin-annotation": "2.2.1",
"classnames": "2.5.1", "classnames": "2.5.1",
"copy-to-clipboard": "3.3.3", "copy-to-clipboard": "3.3.3",
"countries-and-timezones": "^3.4.0", "countries-and-timezones": "^3.4.0",

View File

@ -30,6 +30,7 @@ import type { Theme } from '@mui/material/styles/createTheme';
import Grid from '@mui/material/Grid'; import Grid from '@mui/material/Grid';
import { useUiFlag } from 'hooks/useUiFlag'; import { useUiFlag } from 'hooks/useUiFlag';
import { NetworkTrafficUsagePlanSummary } from './NetworkTrafficUsagePlanSummary'; import { NetworkTrafficUsagePlanSummary } from './NetworkTrafficUsagePlanSummary';
import annotationPlugin from 'chartjs-plugin-annotation';
type ChartDatasetType = ChartDataset<'bar'>; type ChartDatasetType = ChartDataset<'bar'>;
@ -185,8 +186,36 @@ const customHighlightPlugin = {
const createBarChartOptions = ( const createBarChartOptions = (
theme: Theme, theme: Theme,
tooltipTitleCallback: (tooltipItems: any) => string, tooltipTitleCallback: (tooltipItems: any) => string,
includedTraffic?: number,
): ChartOptions<'bar'> => ({ ): ChartOptions<'bar'> => ({
plugins: { plugins: {
annotation: {
clip: false,
annotations: {
line: {
type: 'line',
borderDash: [5, 5],
yMin: includedTraffic ? includedTraffic / 30 : 0,
yMax: includedTraffic ? includedTraffic / 30 : 0,
borderColor: 'gray',
borderWidth: 1,
display: !!includedTraffic,
label: {
backgroundColor: 'rgba(192, 192, 192, 0.8)',
color: 'black',
padding: {
top: 10,
bottom: 10,
left: 10,
right: 10,
},
content: 'Average daily requests included in your plan',
display: !!includedTraffic,
},
},
},
},
legend: { legend: {
position: 'bottom', position: 'bottom',
labels: { labels: {
@ -284,7 +313,7 @@ const endpointsInfo: Record<string, EndpointInfo> = {
}, },
}; };
const proPlanIncludedRequests = 53000000; const proPlanIncludedRequests = 53_000_000;
export const NetworkTrafficUsage: VFC = () => { export const NetworkTrafficUsage: VFC = () => {
usePageTitle('Network - Data Usage'); usePageTitle('Network - Data Usage');
@ -294,8 +323,14 @@ export const NetworkTrafficUsage: VFC = () => {
const record = toPeriodsRecord(selectablePeriods); const record = toPeriodsRecord(selectablePeriods);
const [period, setPeriod] = useState<string>(selectablePeriods[0].key); const [period, setPeriod] = useState<string>(selectablePeriods[0].key);
const { isOss, isPro } = useUiConfig();
const includedTraffic = isPro() ? proPlanIncludedRequests : 0;
const options = useMemo(() => { const options = useMemo(() => {
return createBarChartOptions(theme, (tooltipItems: any) => { return createBarChartOptions(
theme,
(tooltipItems: any) => {
const periodItem = record[period]; const periodItem = record[period];
const tooltipDate = new Date( const tooltipDate = new Date(
periodItem.year, periodItem.year,
@ -307,7 +342,9 @@ export const NetworkTrafficUsage: VFC = () => {
day: 'numeric', day: 'numeric',
year: 'numeric', year: 'numeric',
}); });
}); },
includedTraffic,
);
}, [theme, period]); }, [theme, period]);
const traffic = useInstanceTrafficMetrics(period); const traffic = useInstanceTrafficMetrics(period);
@ -323,7 +360,6 @@ export const NetworkTrafficUsage: VFC = () => {
datasets, datasets,
}; };
const { isOss } = useUiConfig();
const flagEnabled = useUiFlag('displayTrafficDataUsage'); const flagEnabled = useUiFlag('displayTrafficDataUsage');
useEffect(() => { useEffect(() => {
@ -368,9 +404,7 @@ export const NetworkTrafficUsage: VFC = () => {
<Grid item xs={7} md={5.5}> <Grid item xs={7} md={5.5}>
<NetworkTrafficUsagePlanSummary <NetworkTrafficUsagePlanSummary
usageTotal={usageTotal} usageTotal={usageTotal}
planIncludedRequests={ includedTraffic={includedTraffic}
proPlanIncludedRequests
}
/> />
</Grid> </Grid>
</Grid> </Grid>
@ -406,6 +440,7 @@ export const NetworkTrafficUsage: VFC = () => {
// Register dependencies that we need to draw the chart. // Register dependencies that we need to draw the chart.
ChartJS.register( ChartJS.register(
annotationPlugin,
CategoryScale, CategoryScale,
LinearScale, LinearScale,
BarElement, BarElement,

View File

@ -4,7 +4,6 @@ import Grid from '@mui/material/Grid';
import { flexRow } from 'themes/themeStyles'; import { flexRow } from 'themes/themeStyles';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Badge } from 'component/common/Badge/Badge'; import { Badge } from 'component/common/Badge/Badge';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
const StyledContainer = styled('div')(({ theme }) => ({ const StyledContainer = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@ -45,15 +44,14 @@ const StyledNumbersDiv = styled('div')(({ theme }) => ({
interface INetworkTrafficUsagePlanSummary { interface INetworkTrafficUsagePlanSummary {
usageTotal: number; usageTotal: number;
planIncludedRequests: number; includedTraffic: number;
} }
export const NetworkTrafficUsagePlanSummary = ({ export const NetworkTrafficUsagePlanSummary = ({
usageTotal, usageTotal,
planIncludedRequests, includedTraffic,
}: INetworkTrafficUsagePlanSummary) => { }: INetworkTrafficUsagePlanSummary) => {
const { isPro } = useUiConfig(); const overages = usageTotal - includedTraffic;
const overages = usageTotal - planIncludedRequests;
return ( return (
<StyledContainer> <StyledContainer>
<Grid item> <Grid item>
@ -65,11 +63,11 @@ export const NetworkTrafficUsagePlanSummary = ({
Incoming requests selected month{' '} Incoming requests selected month{' '}
<StyledNumbersDiv> <StyledNumbersDiv>
<ConditionallyRender <ConditionallyRender
condition={isPro()} condition={includedTraffic > 0}
show={ show={
<ConditionallyRender <ConditionallyRender
condition={ condition={
usageTotal <= planIncludedRequests usageTotal <= includedTraffic
} }
show={ show={
<Badge color='success'> <Badge color='success'>
@ -95,21 +93,20 @@ export const NetworkTrafficUsagePlanSummary = ({
</RowContainer> </RowContainer>
</StyledCardDescription> </StyledCardDescription>
<ConditionallyRender <ConditionallyRender
condition={isPro()} condition={includedTraffic > 0}
show={ show={
<StyledCardDescription> <StyledCardDescription>
<RowContainer> <RowContainer>
Included in your plan monthly Included in your plan monthly
<StyledNumbersDiv> <StyledNumbersDiv>
{planIncludedRequests.toLocaleString()}{' '} {includedTraffic.toLocaleString()} requests
requests
</StyledNumbersDiv> </StyledNumbersDiv>
</RowContainer> </RowContainer>
</StyledCardDescription> </StyledCardDescription>
} }
/> />
<ConditionallyRender <ConditionallyRender
condition={isPro() && overages > 0} condition={includedTraffic > 0 && overages > 0}
show={ show={
<StyledCardDescription> <StyledCardDescription>
<RowContainer> <RowContainer>

View File

@ -3136,6 +3136,11 @@ chartjs-adapter-date-fns@3.0.0:
resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz#c25f63c7f317c1f96f9a7c44bd45eeedb8a478e5" resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz#c25f63c7f317c1f96f9a7c44bd45eeedb8a478e5"
integrity sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg== integrity sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==
chartjs-plugin-annotation@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/chartjs-plugin-annotation/-/chartjs-plugin-annotation-2.2.1.tgz#b7c359e46814b27632d9648584435d64c183427c"
integrity sha512-RL9UtrFr2SXd7C47zD0MZqn6ZLgrcRt3ySC6cYal2amBdANcYB1QcwFXcpKWAYnO4SGJYRok7P5rKDDNgJMA/w==
check-error@^1.0.3: check-error@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694"