Skip to content

Commit

Permalink
feat(web): Display preliminary instead of estimated when using TSA (#…
Browse files Browse the repository at this point in the history
…6905)

* feat(web): Display preliminary instead of estimated when using TSA

* feat(web): add estimation methods to enum

* feat(web): PR feedback, use EstimationMethods enum everywhere and add casing to translation keys

* typecheck

* improve naming
  • Loading branch information
tonypls authored Jul 3, 2024
1 parent f051f77 commit 923aa25
Show file tree
Hide file tree
Showing 21 changed files with 161 additions and 130 deletions.
33 changes: 9 additions & 24 deletions web/src/features/charts/bar-breakdown/elements/BySource.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import EstimationBadge from 'components/EstimationBadge';
import { useGetEstimationTranslation } from 'hooks/getEstimationTranslation';
import { TFunction } from 'i18next';
import { PlugCircleBoltIcon } from 'icons/plugCircleBoltIcon';
import { useAtom } from 'jotai';
import { useTranslation } from 'react-i18next';
import { TimeAverages } from 'utils/constants';
import { EstimationMethods, TimeAverages } from 'utils/constants';
import {
displayByEmissionsAtom,
productionConsumptionAtom,
Expand Down Expand Up @@ -31,23 +32,6 @@ const getText = (
return translations[period][dataType];
};

function getEstimatedText(
t: TFunction,
estimatedPercentage?: number,
estimationMethod?: string
) {
if (estimatedPercentage) {
return t('estimation-card.aggregated_estimated.pill', {
percentage: estimatedPercentage,
});
}
if (estimationMethod === 'threshold_filtered') {
return t('estimation-card.threshold_filtered.pill');
}

return t('estimation-badge.fully-estimated');
}

export default function BySource({
className,
hasEstimationPill = false,
Expand All @@ -59,7 +43,7 @@ export default function BySource({
hasEstimationPill?: boolean;
estimatedPercentage?: number;
unit?: string | number;
estimationMethod?: string;
estimationMethod?: EstimationMethods;
}) {
const { t } = useTranslation();
const [timeAverage] = useAtom(timeAverageAtom);
Expand All @@ -68,6 +52,11 @@ export default function BySource({

const dataType = displayByEmissions ? 'emissions' : mixMode;
const text = getText(timeAverage, dataType, t);
const pillText = useGetEstimationTranslation(
'pill',
estimationMethod,
estimatedPercentage
);

return (
<div className="flex flex-col pb-1 pt-4">
Expand All @@ -78,11 +67,7 @@ export default function BySource({
<PlugCircleBoltIcon />
{text}
</div>
{hasEstimationPill && (
<EstimationBadge
text={getEstimatedText(t, estimatedPercentage, estimationMethod)}
/>
)}
{hasEstimationPill && <EstimationBadge text={pillText} />}
</div>
{unit && <div className="text-sm dark:text-gray-300">{unit}</div>}
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/charts/bar-breakdown/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const zoneDetailsData = {
battery: 'electricityMap, 2021 average',
hydro: 'electricityMap, 2021 average',
},
estimationMethod: 'MEASURED',
estimationMethod: undefined,
exchange: { ES: -934 },
exchangeCapacities: {},
exchangeCo2Intensities: { ES: 187.32 },
Expand Down
36 changes: 28 additions & 8 deletions web/src/features/charts/graphUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { scaleTime } from 'd3-scale';
import { pointer } from 'd3-selection';
import { TFunction } from 'i18next';
import { ElectricityStorageType, GenerationType, Maybe, ZoneDetail } from 'types';
import { Mode, modeOrder, TimeAverages } from 'utils/constants';
import { EstimationMethods, Mode, modeOrder, TimeAverages } from 'utils/constants';
import { formatCo2, formatEnergy, formatPower } from 'utils/formatting';

import { AreaGraphElement } from './types';
Expand Down Expand Up @@ -193,19 +193,39 @@ export function getElectricityProductionValue({
return generationTypeStorage === 0 ? 0 : -generationTypeStorage;
}

function analyzeChartData(chartData: AreaGraphElement[]) {
let estimatedCount = 0;
let tsaCount = 0;
for (const chartElement of chartData) {
if (chartElement.meta.estimationMethod === EstimationMethods.TSA) {
tsaCount++;
}
if (
chartElement.meta.estimationMethod ||
chartElement.meta.estimatedPercentage === 100
) {
estimatedCount++;
}
}
return {
allTimeSlicerAverageMethod: tsaCount === chartData.length,
allEstimated: estimatedCount === chartData.length,
hasEstimation: estimatedCount > 0,
};
}

export function getBadgeText(chartData: AreaGraphElement[], t: TFunction) {
const allEstimated = chartData.every(
(day) => day.meta.estimationMethod || day.meta.estimatedPercentage === 100
);
const { allTimeSlicerAverageMethod, allEstimated, hasEstimation } =
analyzeChartData(chartData);

if (allTimeSlicerAverageMethod) {
return t(`estimation-card.${EstimationMethods.TSA}.pill`);
}

if (allEstimated) {
return t('estimation-badge.fully-estimated');
}

const hasEstimation = chartData.some(
(day) => day.meta.estimationMethod || Boolean(day.meta.estimatedPercentage)
);

if (hasEstimation) {
return t('estimation-badge.partially-estimated');
}
Expand Down
23 changes: 11 additions & 12 deletions web/src/features/charts/tooltips/AreaGraphTooltipHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import EstimationBadge from 'components/EstimationBadge';
import { useGetEstimationTranslation } from 'hooks/getEstimationTranslation';
import { useTranslation } from 'react-i18next';
import { TimeAverages } from 'utils/constants';
import { EstimationMethods, TimeAverages } from 'utils/constants';
import { formatDate } from 'utils/formatting';

import ProductionSourceIcon from '../ProductionsSourceIcons';
Expand All @@ -13,6 +14,7 @@ interface AreaGraphToolTipHeaderProps {
hasEstimationPill?: boolean;
estimatedPercentage?: number;
productionSource?: string;
estimationMethod?: EstimationMethods;
}

export default function AreaGraphToolTipHeader(props: AreaGraphToolTipHeaderProps) {
Expand All @@ -24,9 +26,14 @@ export default function AreaGraphToolTipHeader(props: AreaGraphToolTipHeaderProp
hasEstimationPill = false,
estimatedPercentage,
productionSource,
estimationMethod,
} = props;
const { t, i18n } = useTranslation();

const { i18n } = useTranslation();
const pillText = useGetEstimationTranslation(
'pill',
estimationMethod,
estimatedPercentage
);
return (
<>
<div className="mb-2 flex justify-between">
Expand All @@ -49,15 +56,7 @@ export default function AreaGraphToolTipHeader(props: AreaGraphToolTipHeaderProp
</div>
<div className="inline-flex items-center gap-x-2">
{hasEstimationPill && estimatedPercentage !== 0 && (
<EstimationBadge
text={
estimatedPercentage
? t('estimation-card.aggregated_estimated.pill', {
percentage: estimatedPercentage,
})
: t('estimation-badge.fully-estimated')
}
/>
<EstimationBadge text={pillText} />
)}
<div className="my-1 h-[32px] max-w-[165px] select-none whitespace-nowrap rounded-full bg-brand-green/10 px-3 py-2 text-sm text-brand-green dark:bg-gray-700 dark:text-white">
{formatDate(datetime, i18n.language, timeAverage)}
Expand Down
6 changes: 5 additions & 1 deletion web/src/features/charts/tooltips/BreakdownChartTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { renderToString } from 'react-dom/server';
import { useTranslation } from 'react-i18next';
import { getZoneName } from 'translation/translation';
import { ElectricityModeType, Maybe, ZoneDetail } from 'types';
import { Mode, modeColor, TimeAverages } from 'utils/constants';
import { EstimationMethods, Mode, modeColor, TimeAverages } from 'utils/constants';
import { formatCo2, formatEnergy, formatPower } from 'utils/formatting';
import {
displayByEmissionsAtom,
Expand Down Expand Up @@ -90,6 +90,7 @@ export default function BreakdownChartTooltip({
timeAverage={timeAverage}
hasEstimationPill={hasEstimationPill}
estimatedPercentage={estimatedPercentage}
estimationMethod={estimationMethod}
></BreakdownChartTooltipContent>
);
}
Expand All @@ -114,6 +115,7 @@ interface BreakdownChartTooltipContentProperties {
hasEstimationPill?: boolean;
estimatedPercentage?: number;
capacitySource?: string[] | null;
estimationMethod?: EstimationMethods;
}

export function BreakdownChartTooltipContent({
Expand All @@ -134,6 +136,7 @@ export function BreakdownChartTooltipContent({
hasEstimationPill,
estimatedPercentage,
capacitySource,
estimationMethod,
}: BreakdownChartTooltipContentProperties) {
const { t } = useTranslation();
const co2ColorScale = useCo2ColorScale();
Expand Down Expand Up @@ -174,6 +177,7 @@ export function BreakdownChartTooltipContent({
hasEstimationPill={isExchange ? false : hasEstimationPill}
estimatedPercentage={estimatedPercentage}
productionSource={isExchange ? undefined : selectedLayerKey}
estimationMethod={estimationMethod}
/>
<div
className="inline-flex flex-wrap items-center gap-x-1"
Expand Down
1 change: 1 addition & 0 deletions web/src/features/charts/tooltips/CarbonChartTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default function CarbonChartTooltip({ zoneDetail }: InnerAreaGraphTooltip
title={t('tooltips.carbonintensity')}
hasEstimationPill={hasEstimationPill}
estimatedPercentage={estimatedPercentage}
estimationMethod={estimationMethod}
/>
<CarbonIntensityDisplay
co2Intensity={intensity}
Expand Down
1 change: 1 addition & 0 deletions web/src/features/charts/tooltips/EmissionChartTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default function EmissionChartTooltip({ zoneDetail }: InnerAreaGraphToolt
title={t('country-panel.emissions')}
hasEstimationPill={hasEstimationPill}
estimatedPercentage={estimatedPercentage}
estimationMethod={estimationMethod}
/>
<p className="flex justify-center text-base">
<b className="mr-1">{formatCo2(totalEmissions)}</b> {t('ofCO2eq')}
Expand Down
17 changes: 7 additions & 10 deletions web/src/features/panels/zone/EstimationCard.cy.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { I18nextProvider } from 'react-i18next';
import i18n from 'translation/i18n';
import { EstimationMethods } from 'utils/constants';

import EstimationCard from './EstimationCard';

Expand All @@ -13,7 +14,7 @@ describe('EstimationCard with FeedbackCard', () => {
<QueryClientProvider client={queryClient}>
<EstimationCard
cardType="estimated"
estimationMethod="ESTIMATED_CONSTRUCT_BREAKDOWN"
estimationMethod={EstimationMethods.CONSTRUCT_BREAKDOWN}
zoneMessage={undefined}
/>
</QueryClientProvider>
Expand Down Expand Up @@ -50,7 +51,7 @@ describe('EstimationCard with known estimation method', () => {
<QueryClientProvider client={queryClient}>
<EstimationCard
cardType="estimated"
estimationMethod="ESTIMATED_CONSTRUCT_BREAKDOWN"
estimationMethod={EstimationMethods.CONSTRUCT_BREAKDOWN}
zoneMessage={undefined}
/>
</QueryClientProvider>
Expand Down Expand Up @@ -85,11 +86,7 @@ describe('EstimationCard', () => {
cy.mount(
<I18nextProvider i18n={i18n}>
<QueryClientProvider client={queryClient}>
<EstimationCard
cardType="estimated"
estimationMethod=""
zoneMessage={undefined}
/>
<EstimationCard cardType="estimated" zoneMessage={undefined} />
</QueryClientProvider>
</I18nextProvider>
);
Expand All @@ -105,7 +102,7 @@ describe('EstimationCard', () => {
cy.mount(
<I18nextProvider i18n={i18n}>
<QueryClientProvider client={queryClient}>
<EstimationCard cardType="" estimationMethod="" zoneMessage={undefined} />
<EstimationCard cardType="" zoneMessage={undefined} />
</QueryClientProvider>
</I18nextProvider>
);
Expand All @@ -120,7 +117,7 @@ describe('OutageCard', () => {
<QueryClientProvider client={queryClient}>
<EstimationCard
cardType="outage"
estimationMethod="ESTIMATED_CONSTRUCT_BREAKDOWN"
estimationMethod={EstimationMethods.CONSTRUCT_BREAKDOWN}
zoneMessage={{ message: 'Outage Message', issue: 'issue' }}
/>
</QueryClientProvider>
Expand Down Expand Up @@ -169,7 +166,7 @@ describe('AggregatedCard', () => {
<QueryClientProvider client={queryClient}>
<EstimationCard
cardType="aggregated"
estimationMethod="ESTIMATED_CONSTRUCT_BREAKDOWN"
estimationMethod={EstimationMethods.CONSTRUCT_BREAKDOWN}
zoneMessage={undefined}
/>
</QueryClientProvider>
Expand Down
5 changes: 3 additions & 2 deletions web/src/features/panels/zone/EstimationCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { I18nextProvider } from 'react-i18next';
import i18n from 'translation/i18n';
import { EstimationMethods } from 'utils/constants';

import EstimationCard from './EstimationCard';

Expand All @@ -27,14 +28,14 @@ export const All: Story = {
<EstimationCard
cardType="outage"
zoneMessage={instance}
estimationMethod="threshold_filtered"
estimationMethod={EstimationMethods.THRESHOLD_FILTERED}
/>
<EstimationCard cardType="estimated" zoneMessage={instance} />

<EstimationCard
cardType="estimated"
zoneMessage={instance}
estimationMethod="estimated_mode_breakdown"
estimationMethod={EstimationMethods.MODE_BREAKDOWN}
/>

<EstimationCard
Expand Down
Loading

0 comments on commit 923aa25

Please sign in to comment.