Skip to content

Commit d8b47d4

Browse files
authored
feat: keep flakiness in table and user server-side pagination for flakiness overview (#920)
1 parent e569daf commit d8b47d4

28 files changed

+1155
-502
lines changed

client/src/app/components/pull-request-table/pull-request-table.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { PullRequestStatusIconComponent } from '@app/components/pull-request-sta
2121
import { MessageService, SortMeta } from 'primeng/api';
2222
import { provideTablerIcons, TablerIconComponent } from 'angular-tabler-icons';
2323
import { IconExternalLink, IconFilterPlus, IconGitPullRequest, IconPinned, IconPinnedOff, IconPoint, IconBrandGithub } from 'angular-tabler-icons/icons';
24-
import { PAGINATED_FILTER_OPTIONS_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
24+
import { PAGINATED_FILTER_OPTIONS_TOKEN, PAGINATION_STORAGE_KEY_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
2525
import { TableFilterPaginatedComponent } from '@app/components/table-filter-paginated/table-filter-paginated.component';
2626
import { NgTemplateOutlet } from '@angular/common';
2727

@@ -71,6 +71,7 @@ export function createPullRequestFilterOptions(keycloakService: KeycloakService)
7171
providers: [
7272
PaginatedTableService,
7373
{ provide: PAGINATED_FILTER_OPTIONS_TOKEN, useFactory: createPullRequestFilterOptions, deps: [KeycloakService] },
74+
{ provide: PAGINATION_STORAGE_KEY_TOKEN, useValue: 'pullRequestPaginationState' },
7475
provideTablerIcons({
7576
IconFilterPlus,
7677
IconPoint,

client/src/app/components/workflow-runs-table/workflow-runs-table.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { TimeAgoPipe } from '@app/pipes/time-ago.pipe';
1111
import { WorkflowRunDto } from '@app/core/modules/openapi';
1212
import { injectQuery } from '@tanstack/angular-query-experimental';
1313
import { getWorkflowRunsOptions } from '@app/core/modules/openapi/@tanstack/angular-query-experimental.gen';
14-
import { PAGINATED_FILTER_OPTIONS_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
14+
import { PAGINATED_FILTER_OPTIONS_TOKEN, PAGINATION_STORAGE_KEY_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
1515
import { TableFilterPaginatedComponent } from '@app/components/table-filter-paginated/table-filter-paginated.component';
1616
import { MessageService, SortMeta } from 'primeng/api';
1717
import { provideTablerIcons, TablerIconComponent } from 'angular-tabler-icons';
@@ -37,6 +37,7 @@ export function createWorkflowRunsFilterOptions(): PaginatedFilterOption[] {
3737
PaginatedTableService,
3838
MessageService,
3939
{ provide: PAGINATED_FILTER_OPTIONS_TOKEN, useFactory: createWorkflowRunsFilterOptions },
40+
{ provide: PAGINATION_STORAGE_KEY_TOKEN, useValue: 'workflowRunsPaginationState' },
4041
provideTablerIcons({
4142
IconFilterPlus,
4243
IconCircleCheck,

client/src/app/core/modules/openapi/@tanstack/angular-query-experimental.gen.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ import type {
144144
GetFlakinessScoresError,
145145
GetFlakinessScoresResponse,
146146
GetFlakyTestsOverviewData,
147+
GetFlakyTestsOverviewError,
148+
GetFlakyTestsOverviewResponse,
147149
GetGitRepoSettingsData,
148150
GetGroupsWithWorkflowsData,
149151
GetLatestDeploymentByEnvironmentIdData,
@@ -1262,6 +1264,43 @@ export const getFlakyTestsOverviewOptions = (options?: Options<GetFlakyTestsOver
12621264
});
12631265
};
12641266

1267+
export const getFlakyTestsOverviewInfiniteQueryKey = (options?: Options<GetFlakyTestsOverviewData>): QueryKey<Options<GetFlakyTestsOverviewData>> =>
1268+
createQueryKey('getFlakyTestsOverview', options, true);
1269+
1270+
export const getFlakyTestsOverviewInfiniteOptions = (options?: Options<GetFlakyTestsOverviewData>) => {
1271+
return infiniteQueryOptions<
1272+
GetFlakyTestsOverviewResponse,
1273+
GetFlakyTestsOverviewError,
1274+
InfiniteData<GetFlakyTestsOverviewResponse>,
1275+
QueryKey<Options<GetFlakyTestsOverviewData>>,
1276+
number | Pick<QueryKey<Options<GetFlakyTestsOverviewData>>[0], 'body' | 'headers' | 'path' | 'query'>
1277+
>(
1278+
// @ts-ignore
1279+
{
1280+
queryFn: async ({ pageParam, queryKey, signal }) => {
1281+
// @ts-ignore
1282+
const page: Pick<QueryKey<Options<GetFlakyTestsOverviewData>>[0], 'body' | 'headers' | 'path' | 'query'> =
1283+
typeof pageParam === 'object'
1284+
? pageParam
1285+
: {
1286+
query: {
1287+
page: pageParam,
1288+
},
1289+
};
1290+
const params = createInfiniteParams(queryKey, page);
1291+
const { data } = await getFlakyTestsOverview({
1292+
...options,
1293+
...params,
1294+
signal,
1295+
throwOnError: true,
1296+
});
1297+
return data;
1298+
},
1299+
queryKey: getFlakyTestsOverviewInfiniteQueryKey(options),
1300+
}
1301+
);
1302+
};
1303+
12651304
export const getLatestTestResultsByBranchQueryKey = (options: Options<GetLatestTestResultsByBranchData>) => createQueryKey('getLatestTestResultsByBranch', options);
12661305

12671306
export const getLatestTestResultsByBranchOptions = (options: Options<GetLatestTestResultsByBranchData>) => {

client/src/app/core/modules/openapi/schemas.gen.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,12 @@ export const TestCaseIdentifierSchema = {
496496
type: 'string',
497497
minLength: 1,
498498
},
499+
testSuiteName: {
500+
type: 'string',
501+
minLength: 1,
502+
},
499503
},
500-
required: ['className', 'testName'],
504+
required: ['className', 'testName', 'testSuiteName'],
501505
} as const;
502506

503507
export const TestFlakinessScoreRequestSchema = {
@@ -523,6 +527,9 @@ export const TestFlakinessScoreDtoSchema = {
523527
className: {
524528
type: 'string',
525529
},
530+
testSuiteName: {
531+
type: 'string',
532+
},
526533
flakinessScore: {
527534
type: 'number',
528535
format: 'double',
@@ -536,7 +543,7 @@ export const TestFlakinessScoreDtoSchema = {
536543
format: 'double',
537544
},
538545
},
539-
required: ['className', 'testName'],
546+
required: ['className', 'testName', 'testSuiteName'],
540547
} as const;
541548

542549
export const ReleaseCandidateCreateDtoSchema = {
@@ -1186,14 +1193,6 @@ export const FlakyTestDtoSchema = {
11861193
type: 'number',
11871194
format: 'double',
11881195
},
1189-
totalRuns: {
1190-
type: 'integer',
1191-
format: 'int32',
1192-
},
1193-
failedRuns: {
1194-
type: 'integer',
1195-
format: 'int32',
1196-
},
11971196
lastUpdated: {
11981197
type: 'string',
11991198
format: 'date-time',
@@ -1214,6 +1213,10 @@ export const FlakyTestOverviewDtoSchema = {
12141213
$ref: '#/components/schemas/FlakyTestDto',
12151214
},
12161215
},
1216+
filteredCount: {
1217+
type: 'integer',
1218+
format: 'int64',
1219+
},
12171220
},
12181221
required: ['flakyTests', 'summary'],
12191222
} as const;

client/src/app/core/modules/openapi/types.gen.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export type NotificationPreferencesWrapper = {
162162
export type TestCaseIdentifier = {
163163
testName: string;
164164
className: string;
165+
testSuiteName: string;
165166
};
166167

167168
export type TestFlakinessScoreRequest = {
@@ -171,6 +172,7 @@ export type TestFlakinessScoreRequest = {
171172
export type TestFlakinessScoreDto = {
172173
testName: string;
173174
className: string;
175+
testSuiteName: string;
174176
flakinessScore?: number;
175177
defaultBranchFailureRate?: number;
176178
combinedFailureRate?: number;
@@ -390,14 +392,13 @@ export type FlakyTestDto = {
390392
flakinessScore?: number;
391393
defaultBranchFailureRate?: number;
392394
combinedFailureRate?: number;
393-
totalRuns?: number;
394-
failedRuns?: number;
395395
lastUpdated: string;
396396
};
397397

398398
export type FlakyTestOverviewDto = {
399399
summary: FlakyTestSummary;
400400
flakyTests: Array<FlakyTestDto>;
401+
filteredCount?: number;
401402
};
402403

403404
export type FlakyTestSummary = {
@@ -1955,7 +1956,13 @@ export type GetLatestTestResultsByPullRequestIdResponse = GetLatestTestResultsBy
19551956
export type GetFlakyTestsOverviewData = {
19561957
body?: never;
19571958
path?: never;
1958-
query?: never;
1959+
query?: {
1960+
page?: number;
1961+
size?: number;
1962+
sortDirection?: string;
1963+
filterType?: 'ALL' | 'HIGH' | 'MEDIUM' | 'LOW';
1964+
searchTerm?: string;
1965+
};
19591966
url: '/api/tests/flaky';
19601967
};
19611968

client/src/app/core/services/paginated-table.service.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export type PaginatedFilterOption = {
1515
// Define an injection token for filter options
1616
export const PAGINATED_FILTER_OPTIONS_TOKEN = new InjectionToken<PaginatedFilterOption[]>('paginatedFilterOptions');
1717

18+
// Injection token for the localStorage key used to persist pagination state.
19+
// Each component that provides PaginatedTableService should supply its own unique key
20+
// via this token to prevent different tables from overwriting each other's state.
21+
export const PAGINATION_STORAGE_KEY_TOKEN = new InjectionToken<string>('paginationStorageKey');
22+
1823
export interface PaginationState {
1924
page: number;
2025
size: number;
@@ -32,6 +37,8 @@ export class PaginatedTableService {
3237
// Inject filter options
3338
filterOptions = inject<PaginatedFilterOption[]>(PAGINATED_FILTER_OPTIONS_TOKEN);
3439

40+
private storageKey = inject(PAGINATION_STORAGE_KEY_TOKEN);
41+
3542
// Pagination state
3643
page = signal(1);
3744
size = signal(20);
@@ -66,7 +73,7 @@ export class PaginatedTableService {
6673
}
6774

6875
private loadPaginationFromLocalStorage(): void {
69-
const storedStateStr = localStorage.getItem('pullRequestPaginationState');
76+
const storedStateStr = localStorage.getItem(this.storageKey);
7077
if (!storedStateStr) {
7178
console.log('No pagination state found in localStorage');
7279
return;
@@ -108,7 +115,7 @@ export class PaginatedTableService {
108115
}
109116

110117
private savePaginationToLocalStorage(state: PaginationState): void {
111-
localStorage.setItem('pullRequestPaginationState', JSON.stringify(state));
118+
localStorage.setItem(this.storageKey, JSON.stringify(state));
112119
}
113120

114121
filterType(): string {

0 commit comments

Comments
 (0)