Skip to content

Commit c48033f

Browse files
author
Taniya Mathur
committed
refactor: extract shared calculateTotalPages and calculateAvgCostPerPage utilities
- Move duplicated page-counting logic to awsjson-parsers.ts - Add unit field to CostBreakdownServiceDetail type - Replace 4 inline copies with single-line utility calls
1 parent 113a947 commit c48033f

4 files changed

Lines changed: 31 additions & 39 deletions

File tree

src/ui/src/components/test-studio/TestComparison.tsx

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ import TestStudioHeader from './TestStudioHeader';
2020
import useLocalStorage from '../common/local-storage';
2121
import useConfigurationVersions from '../../hooks/use-configuration-versions';
2222
import { formatConfigVersionLink, formatConfigVersionText, type ConfigVersion as UtilsConfigVersion } from './utils/configVersionUtils';
23-
import { parseComparisonMetrics, parseWeightedOverallScores, parseConfigSettingValues } from '../../graphql/awsjson-parsers';
23+
import {
24+
parseComparisonMetrics,
25+
parseWeightedOverallScores,
26+
parseConfigSettingValues,
27+
calculateAvgCostPerPage,
28+
} from '../../graphql/awsjson-parsers';
29+
import type { CostBreakdown } from '../../graphql/awsjson-types';
2430

2531
const client = generateClient();
2632

@@ -305,14 +311,8 @@ const TestComparison = ({ preSelectedTestRunIds = [] }: TestComparisonProps): Re
305311
[
306312
'Avg Cost/Page',
307313
...Object.values(completeTestRuns).map((run) => {
308-
if (run.totalCost == null || !run.costBreakdown) return 'N/A';
309-
let totalPages = 0;
310-
Object.values(run.costBreakdown as Record<string, Record<string, Record<string, unknown>>>).forEach((services) => {
311-
Object.values(services).forEach((details) => {
312-
if (details.unit === 'pages') totalPages += Number(details.value) || 0;
313-
});
314-
});
315-
return totalPages > 0 ? `$${(Number(run.totalCost) / totalPages).toFixed(4)}` : 'N/A';
314+
const avg = calculateAvgCostPerPage(run.totalCost as number, run.costBreakdown as CostBreakdown);
315+
return avg !== null ? `$${avg.toFixed(4)}` : 'N/A';
316316
}),
317317
],
318318
[
@@ -637,16 +637,7 @@ const TestComparison = ({ preSelectedTestRunIds = [] }: TestComparisonProps): Re
637637
completedFiles: testRun.completedFiles,
638638
failedFiles: testRun.failedFiles,
639639
totalCost: testRun.totalCost,
640-
avgCostPerPage: (() => {
641-
if (testRun.totalCost == null || !testRun.costBreakdown) return null;
642-
let totalPages = 0;
643-
Object.values(testRun.costBreakdown as Record<string, Record<string, Record<string, unknown>>>).forEach((services) => {
644-
Object.values(services).forEach((details) => {
645-
if (details.unit === 'pages') totalPages += Number(details.value) || 0;
646-
});
647-
});
648-
return totalPages > 0 ? Number(testRun.totalCost) / totalPages : null;
649-
})(),
640+
avgCostPerPage: calculateAvgCostPerPage(testRun.totalCost as number, testRun.costBreakdown as CostBreakdown),
650641
averageAccuracy: testRun.overallAccuracy,
651642
averageConfidence: testRun.averageConfidence,
652643
averageWeightedOverallScore: (() => {
@@ -845,16 +836,8 @@ const TestComparison = ({ preSelectedTestRunIds = [] }: TestComparisonProps): Re
845836
metric: 'Avg Cost/Page',
846837
...Object.fromEntries(
847838
Object.entries(completeTestRuns).map(([testRunId, testRun]) => {
848-
if (testRun.totalCost == null || !testRun.costBreakdown) return [testRunId, 'N/A'];
849-
let totalPages = 0;
850-
Object.values(testRun.costBreakdown as Record<string, Record<string, Record<string, unknown>>>).forEach(
851-
(services) => {
852-
Object.values(services).forEach((details) => {
853-
if (details.unit === 'pages') totalPages += Number(details.value) || 0;
854-
});
855-
},
856-
);
857-
return [testRunId, totalPages > 0 ? `$${(Number(testRun.totalCost) / totalPages).toFixed(4)}` : 'N/A'];
839+
const avg = calculateAvgCostPerPage(testRun.totalCost as number, testRun.costBreakdown as CostBreakdown);
840+
return [testRunId, avg !== null ? `$${avg.toFixed(4)}` : 'N/A'];
858841
}),
859842
),
860843
},

src/ui/src/components/test-studio/TestResults.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import useAppContext from '../../contexts/app';
3535
import { formatConfigVersionLink } from './utils/configVersionUtils';
3636
import {
3737
parseCostBreakdown,
38+
calculateAvgCostPerPage,
3839
parseAccuracyBreakdown,
3940
parseSplitClassificationMetrics,
4041
parseFieldMetrics,
@@ -753,16 +754,7 @@ const TestResults = ({ testRunId, setSelectedTestRunId }: TestResultsProps): Rea
753754
const costBreakdown: any = results.costBreakdown ? parseCostBreakdown(results.costBreakdown as string) : null;
754755

755756
// Calculate avg cost per page from costBreakdown page counts
756-
const avgCostPerPage = (() => {
757-
if (results.totalCost == null || !costBreakdown) return null;
758-
let totalPages = 0;
759-
Object.values(costBreakdown as Record<string, Record<string, Record<string, unknown>>>).forEach((services) => {
760-
Object.values(services).forEach((details) => {
761-
if (details.unit === 'pages') totalPages += Number(details.value) || 0;
762-
});
763-
});
764-
return totalPages > 0 ? (results.totalCost as number) / totalPages : null;
765-
})();
757+
const avgCostPerPage = calculateAvgCostPerPage(results.totalCost as number, costBreakdown);
766758
// eslint-disable-next-line @typescript-eslint/no-explicit-any
767759
const accuracyBreakdown: any = results.accuracyBreakdown ? parseAccuracyBreakdown(results.accuracyBreakdown as string) : null;
768760
// eslint-disable-next-line @typescript-eslint/no-explicit-any

src/ui/src/graphql/awsjson-parsers.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ export function parseCostBreakdown(json: unknown): CostBreakdown {
5858
return safeParse<CostBreakdown>(json, {});
5959
}
6060

61+
export function calculateTotalPages(costBreakdown: CostBreakdown): number {
62+
let totalPages = 0;
63+
Object.values(costBreakdown).forEach((services) => {
64+
Object.values(services).forEach((details) => {
65+
if (details.unit === 'pages') totalPages += Number(details.value) || 0;
66+
});
67+
});
68+
return totalPages;
69+
}
70+
71+
export function calculateAvgCostPerPage(totalCost: number | null | undefined, costBreakdown: CostBreakdown | null): number | null {
72+
if (totalCost == null || !costBreakdown) return null;
73+
const totalPages = calculateTotalPages(costBreakdown);
74+
return totalPages > 0 ? totalCost / totalPages : null;
75+
}
76+
6177
export function parseTestRunConfig(json: unknown): TestRunConfig | null {
6278
return safeParse<TestRunConfig | null>(json, null);
6379
}

src/ui/src/graphql/awsjson-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface CostBreakdownServiceDetail {
3030
estimated_cost?: number;
3131
value?: number;
3232
unit_cost?: number;
33+
unit?: string;
3334
[key: string]: unknown;
3435
}
3536

0 commit comments

Comments
 (0)