Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { PullRequestStatusIconComponent } from '@app/components/pull-request-sta
import { MessageService, SortMeta } from 'primeng/api';
import { provideTablerIcons, TablerIconComponent } from 'angular-tabler-icons';
import { IconExternalLink, IconFilterPlus, IconGitPullRequest, IconPinned, IconPinnedOff, IconPoint, IconBrandGithub } from 'angular-tabler-icons/icons';
import { PAGINATED_FILTER_OPTIONS_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
import { PAGINATED_FILTER_OPTIONS_TOKEN, PAGINATION_STORAGE_KEY_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
import { TableFilterPaginatedComponent } from '@app/components/table-filter-paginated/table-filter-paginated.component';
import { NgTemplateOutlet } from '@angular/common';

Expand Down Expand Up @@ -71,6 +71,7 @@ export function createPullRequestFilterOptions(keycloakService: KeycloakService)
providers: [
PaginatedTableService,
{ provide: PAGINATED_FILTER_OPTIONS_TOKEN, useFactory: createPullRequestFilterOptions, deps: [KeycloakService] },
{ provide: PAGINATION_STORAGE_KEY_TOKEN, useValue: 'pullRequestPaginationState' },
provideTablerIcons({
IconFilterPlus,
IconPoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TimeAgoPipe } from '@app/pipes/time-ago.pipe';
import { WorkflowRunDto } from '@app/core/modules/openapi';
import { injectQuery } from '@tanstack/angular-query-experimental';
import { getWorkflowRunsOptions } from '@app/core/modules/openapi/@tanstack/angular-query-experimental.gen';
import { PAGINATED_FILTER_OPTIONS_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
import { PAGINATED_FILTER_OPTIONS_TOKEN, PAGINATION_STORAGE_KEY_TOKEN, PaginatedFilterOption, PaginatedTableService } from '@app/core/services/paginated-table.service';
import { TableFilterPaginatedComponent } from '@app/components/table-filter-paginated/table-filter-paginated.component';
import { MessageService, SortMeta } from 'primeng/api';
import { provideTablerIcons, TablerIconComponent } from 'angular-tabler-icons';
Expand All @@ -36,6 +36,7 @@ export function createWorkflowRunsFilterOptions(): PaginatedFilterOption[] {
PaginatedTableService,
MessageService,
{ provide: PAGINATED_FILTER_OPTIONS_TOKEN, useFactory: createWorkflowRunsFilterOptions },
{ provide: PAGINATION_STORAGE_KEY_TOKEN, useValue: 'workflowRunsPaginationState' },
provideTablerIcons({
IconFilterPlus,
IconCircleCheck,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ import type {
GetFlakinessScoresError,
GetFlakinessScoresResponse,
GetFlakyTestsOverviewData,
GetFlakyTestsOverviewError,
GetFlakyTestsOverviewResponse,
GetGitRepoSettingsData,
GetGroupsWithWorkflowsData,
GetLatestDeploymentByEnvironmentIdData,
Expand Down Expand Up @@ -1114,6 +1116,43 @@ export const getFlakyTestsOverviewOptions = (options?: Options<GetFlakyTestsOver
});
};

export const getFlakyTestsOverviewInfiniteQueryKey = (options?: Options<GetFlakyTestsOverviewData>): QueryKey<Options<GetFlakyTestsOverviewData>> =>
createQueryKey('getFlakyTestsOverview', options, true);

export const getFlakyTestsOverviewInfiniteOptions = (options?: Options<GetFlakyTestsOverviewData>) => {
return infiniteQueryOptions<
GetFlakyTestsOverviewResponse,
GetFlakyTestsOverviewError,
InfiniteData<GetFlakyTestsOverviewResponse>,
QueryKey<Options<GetFlakyTestsOverviewData>>,
number | Pick<QueryKey<Options<GetFlakyTestsOverviewData>>[0], 'body' | 'headers' | 'path' | 'query'>
>(
// @ts-ignore
{
queryFn: async ({ pageParam, queryKey, signal }) => {
// @ts-ignore
const page: Pick<QueryKey<Options<GetFlakyTestsOverviewData>>[0], 'body' | 'headers' | 'path' | 'query'> =
typeof pageParam === 'object'
? pageParam
: {
query: {
page: pageParam,
},
};
const params = createInfiniteParams(queryKey, page);
const { data } = await getFlakyTestsOverview({
...options,
...params,
signal,
throwOnError: true,
});
return data;
},
queryKey: getFlakyTestsOverviewInfiniteQueryKey(options),
}
);
};

export const getLatestTestResultsByBranchQueryKey = (options: Options<GetLatestTestResultsByBranchData>) => createQueryKey('getLatestTestResultsByBranch', options);

export const getLatestTestResultsByBranchOptions = (options: Options<GetLatestTestResultsByBranchData>) => {
Expand Down
23 changes: 13 additions & 10 deletions client/src/app/core/modules/openapi/schemas.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,12 @@ export const TestCaseIdentifierSchema = {
type: 'string',
minLength: 1,
},
testSuiteName: {
type: 'string',
minLength: 1,
},
},
required: ['className', 'testName'],
required: ['className', 'testName', 'testSuiteName'],
} as const;

export const TestFlakinessScoreRequestSchema = {
Expand All @@ -523,6 +527,9 @@ export const TestFlakinessScoreDtoSchema = {
className: {
type: 'string',
},
testSuiteName: {
type: 'string',
},
flakinessScore: {
type: 'number',
format: 'double',
Expand All @@ -536,7 +543,7 @@ export const TestFlakinessScoreDtoSchema = {
format: 'double',
},
},
required: ['className', 'testName'],
required: ['className', 'testName', 'testSuiteName'],
} as const;

export const ReleaseCandidateCreateDtoSchema = {
Expand Down Expand Up @@ -1134,14 +1141,6 @@ export const FlakyTestDtoSchema = {
type: 'number',
format: 'double',
},
totalRuns: {
type: 'integer',
format: 'int32',
},
failedRuns: {
type: 'integer',
format: 'int32',
},
lastUpdated: {
type: 'string',
format: 'date-time',
Expand All @@ -1162,6 +1161,10 @@ export const FlakyTestOverviewDtoSchema = {
$ref: '#/components/schemas/FlakyTestDto',
},
},
filteredCount: {
type: 'integer',
format: 'int64',
},
},
required: ['flakyTests', 'summary'],
} as const;
Expand Down
13 changes: 10 additions & 3 deletions client/src/app/core/modules/openapi/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export type NotificationPreferencesWrapper = {
export type TestCaseIdentifier = {
testName: string;
className: string;
testSuiteName: string;
};

export type TestFlakinessScoreRequest = {
Expand All @@ -171,6 +172,7 @@ export type TestFlakinessScoreRequest = {
export type TestFlakinessScoreDto = {
testName: string;
className: string;
testSuiteName: string;
flakinessScore?: number;
defaultBranchFailureRate?: number;
combinedFailureRate?: number;
Expand Down Expand Up @@ -377,14 +379,13 @@ export type FlakyTestDto = {
flakinessScore?: number;
defaultBranchFailureRate?: number;
combinedFailureRate?: number;
totalRuns?: number;
failedRuns?: number;
lastUpdated: string;
};

export type FlakyTestOverviewDto = {
summary: FlakyTestSummary;
flakyTests: Array<FlakyTestDto>;
filteredCount?: number;
};

export type FlakyTestSummary = {
Expand Down Expand Up @@ -1779,7 +1780,13 @@ export type GetLatestTestResultsByPullRequestIdResponse = GetLatestTestResultsBy
export type GetFlakyTestsOverviewData = {
body?: never;
path?: never;
query?: never;
query?: {
page?: number;
size?: number;
sortDirection?: string;
filterType?: 'ALL' | 'HIGH' | 'MEDIUM' | 'LOW';
searchTerm?: string;
};
url: '/api/tests/flaky';
};

Expand Down
11 changes: 9 additions & 2 deletions client/src/app/core/services/paginated-table.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export type PaginatedFilterOption = {
// Define an injection token for filter options
export const PAGINATED_FILTER_OPTIONS_TOKEN = new InjectionToken<PaginatedFilterOption[]>('paginatedFilterOptions');

// Injection token for the localStorage key used to persist pagination state.
// Each component that provides PaginatedTableService should supply its own unique key
// via this token to prevent different tables from overwriting each other's state.
export const PAGINATION_STORAGE_KEY_TOKEN = new InjectionToken<string>('paginationStorageKey');

export interface PaginationState {
page: number;
size: number;
Expand All @@ -32,6 +37,8 @@ export class PaginatedTableService {
// Inject filter options
filterOptions = inject<PaginatedFilterOption[]>(PAGINATED_FILTER_OPTIONS_TOKEN);

private storageKey = inject(PAGINATION_STORAGE_KEY_TOKEN);

// Pagination state
page = signal(1);
size = signal(20);
Expand Down Expand Up @@ -66,7 +73,7 @@ export class PaginatedTableService {
}

private loadPaginationFromLocalStorage(): void {
const storedStateStr = localStorage.getItem('pullRequestPaginationState');
const storedStateStr = localStorage.getItem(this.storageKey);
if (!storedStateStr) {
console.log('No pagination state found in localStorage');
return;
Expand Down Expand Up @@ -108,7 +115,7 @@ export class PaginatedTableService {
}

private savePaginationToLocalStorage(state: PaginationState): void {
localStorage.setItem('pullRequestPaginationState', JSON.stringify(state));
localStorage.setItem(this.storageKey, JSON.stringify(state));
}

filterType(): string {
Expand Down
Loading
Loading