Skip to content

Commit 41dfe96

Browse files
committed
Add frontend code to call ListBaselineStatusCounts
Changes: - Add the api client code to call ListBaselineStatusCounts. - Use the new api call on the stats page to display on the features chart
1 parent 200c3d1 commit 41dfe96

8 files changed

+109
-8
lines changed
3.22 KB
Loading
3.16 KB
Loading
3.34 KB
Loading
3.2 KB
Loading
3.06 KB
Loading
3.47 KB
Loading

frontend/src/static/js/api/client.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ export type BrowsersParameter = components['parameters']['browserPathParam'];
4747
type PageablePath =
4848
| '/v1/features'
4949
| '/v1/features/{feature_id}/stats/wpt/browsers/{browser}/channels/{channel}/{metric_view}'
50-
| '/v1/stats/features/browsers/{browser}/feature_counts';
50+
| '/v1/stats/features/browsers/{browser}/feature_counts'
51+
| '/v1/stats/baseline_status/low_date_feature_counts';
5152

5253
type SuccessResponsePageableData<
5354
T,
@@ -127,6 +128,10 @@ export type BrowserReleaseFeatureMetric =
127128
components['schemas']['BrowserReleaseFeatureMetric'];
128129
export type BrowserReleaseFeatureMetricsPage =
129130
components['schemas']['BrowserReleaseFeatureMetricsPage'];
131+
export type BaselineStatusMetricsPage =
132+
components['schemas']['BaselineStatusMetricsPage'];
133+
export type BaselineStatusMetric =
134+
components['schemas']['BaselineStatusMetric'];
130135

131136
// TODO. Remove once not behind UbP
132137
const temporaryFetchOptions: FetchOptions<unknown> = {
@@ -427,6 +432,37 @@ export class APIClient {
427432
} while (nextPageToken !== undefined);
428433
}
429434

435+
// Returns the count of features supported that have reached baseline
436+
// via "/v1/stats/baseline_status/low_date_feature_counts"
437+
public async *listAggregatedBaselineStatusCounts(
438+
startAtDate: Date,
439+
endAtDate: Date,
440+
): AsyncIterable<BaselineStatusMetric[]> {
441+
const startAt: string = startAtDate.toISOString().substring(0, 10);
442+
const endAt: string = endAtDate.toISOString().substring(0, 10);
443+
444+
let nextPageToken;
445+
do {
446+
const response = await this.client.GET(
447+
'/v1/stats/baseline_status/low_date_feature_counts',
448+
{
449+
...temporaryFetchOptions,
450+
params: {
451+
query: {startAt, endAt, page_token: nextPageToken},
452+
},
453+
},
454+
);
455+
const error = response.error;
456+
if (error !== undefined) {
457+
throw createAPIError(error);
458+
}
459+
const page: BaselineStatusMetricsPage =
460+
response.data as BaselineStatusMetricsPage;
461+
nextPageToken = page?.metadata?.next_page_token;
462+
yield page.data; // Yield the entire page
463+
} while (nextPageToken !== undefined);
464+
}
465+
430466
// Fetches feature counts for a browser in a date range
431467
// via "/v1/stats/features/browsers/{browser}/feature_counts"
432468
public async *getMissingOneImplementationCountsForBrowser(

frontend/src/static/js/components/webstatus-stats-page.ts

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
type APIClient,
2727
type BrowsersParameter,
2828
type BrowserReleaseFeatureMetric,
29+
BaselineStatusMetric,
2930
} from '../api/client.js';
3031
import {apiClientContext} from '../contexts/api-client-context.js';
3132
import {getFeaturesLaggingFlag} from '../utils/urls.js';
@@ -58,6 +59,9 @@ export class StatsPage extends BaseChartsPage {
5859
@state()
5960
globalFeatureSupport = new Map<string, Array<BrowserReleaseFeatureMetric>>();
6061

62+
@state()
63+
globalFeatureSupportMax = Array<BaselineStatusMetric>();
64+
6165
@state()
6266
globalFeatureSupportChartOptions = {};
6367

@@ -143,7 +147,7 @@ export class StatsPage extends BaseChartsPage {
143147
endDate: Date,
144148
) {
145149
if (typeof apiClient !== 'object') return;
146-
const promises = ALL_BROWSERS.map(async browser => {
150+
const browserPromises = ALL_BROWSERS.map(async browser => {
147151
for await (const page of apiClient.getFeatureCountsForBrowser(
148152
browser,
149153
startDate,
@@ -159,9 +163,30 @@ export class StatsPage extends BaseChartsPage {
159163
}
160164
this.globalFeatureSupportChartDataObj = this.createDisplayDataFromMap(
161165
this.globalFeatureSupport,
166+
{
167+
label: 'Total number of Baseline features',
168+
data: this.globalFeatureSupportMax,
169+
},
162170
);
163171
});
164-
await Promise.all(promises); // Wait for all browsers to finish
172+
173+
const maxPromise = (async () => {
174+
for await (const page of apiClient.listAggregatedBaselineStatusCounts(
175+
startDate,
176+
endDate,
177+
)) {
178+
const existingMaxData = this.globalFeatureSupportMax || [];
179+
this.globalFeatureSupportMax = [...existingMaxData, ...page];
180+
this.globalFeatureSupportChartDataObj = this.createDisplayDataFromMap(
181+
this.globalFeatureSupport,
182+
{
183+
label: 'Total number of Baseline features',
184+
data: this.globalFeatureSupportMax,
185+
},
186+
);
187+
}
188+
})();
189+
await Promise.all([...browserPromises, maxPromise]); // Wait for all promises to finish
165190
}
166191

167192
async _fetchMissingOneImplemenationCounts(
@@ -251,6 +276,7 @@ export class StatsPage extends BaseChartsPage {
251276
// and stats page, https://github.com/GoogleChrome/webstatus.dev/issues/964.
252277
createDisplayDataFromMap(
253278
targetMap: Map<string, Array<BrowserReleaseFeatureMetric>>,
279+
maxData?: {label: string; data: Array<BaselineStatusMetric>},
254280
): WebStatusDataObj {
255281
// Get the list of supported browsers.
256282
const browsers = this.supportedBrowsers;
@@ -260,9 +286,21 @@ export class StatsPage extends BaseChartsPage {
260286
for (const browser of browsers) {
261287
dataObj.cols.push({type: 'number', label: browser, role: 'data'});
262288
}
289+
if (maxData) {
290+
dataObj.cols.push({type: 'number', label: maxData.label, role: 'data'});
291+
}
263292

264293
// Map from date to an object with counts for each browser
265-
const dateToBrowserDataMap = new Map<number, {[key: string]: number}>();
294+
const dateToBrowserDataMap = new Map<
295+
number,
296+
{[key: string]: number | null}
297+
>();
298+
299+
// Create a template object with all browsers initialized to null
300+
const browserNullTemplate: {[key: string]: number | null} = {};
301+
for (const browser of browsers) {
302+
browserNullTemplate[browser] = null;
303+
}
266304

267305
// Merge data across all browsers into one array of rows.
268306
for (const browser of browsers) {
@@ -279,6 +317,26 @@ export class StatsPage extends BaseChartsPage {
279317
browserCounts[browser] = featureCount;
280318
}
281319
}
320+
321+
// Process the maxArray (overall max data)
322+
if (maxData) {
323+
maxData.data.sort(
324+
(a, b) =>
325+
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
326+
); // Sort maxArray if not already sorted
327+
for (const maxEntry of maxData.data) {
328+
const dateSeconds = new Date(maxEntry.timestamp).getTime();
329+
const maxCount = maxEntry.count!;
330+
331+
// If this date hasn't been encountered before, initialize it with the null template
332+
if (!dateToBrowserDataMap.has(dateSeconds)) {
333+
dateToBrowserDataMap.set(dateSeconds, {...browserNullTemplate}); // Use spread to create a copy
334+
}
335+
const browserCounts = dateToBrowserDataMap.get(dateSeconds)!;
336+
browserCounts[maxData.label] = maxCount; // Add the max count
337+
}
338+
}
339+
282340
// Create array of dateToBrowserDataMap entries and sort by dateSeconds
283341
const data = Array.from(dateToBrowserDataMap.entries()).sort(
284342
([d1], [d2]) => d1 - d2,
@@ -289,13 +347,20 @@ export class StatsPage extends BaseChartsPage {
289347
const dateSeconds = datum[0];
290348
const date = new Date(dateSeconds);
291349
const browserCounts = datum[1];
350+
351+
const row: [Date, ...Array<number | string | null>] = [date]; // Start the row with the date
352+
292353
// Make an array of browser counts, in the order of browsers.
293354
// If the browser is not in the browserCounts, add null.
294-
const browserCountArray = browsers.map(
295-
browser => browserCounts[browser] || null,
296-
);
355+
browsers.forEach(browser => {
356+
row.push(browserCounts[browser] || null);
357+
});
358+
359+
if (maxData) {
360+
row.push(browserCounts[maxData.label] || null); // Add max count (or null if missing)
361+
}
297362

298-
dataObj.rows.push([date, ...browserCountArray]);
363+
dataObj.rows.push(row);
299364
}
300365
return dataObj;
301366
}

0 commit comments

Comments
 (0)