Skip to content

Commit fd286b0

Browse files
authored
Jobs filtering (#4992)
Implemented jobs filtering Fix: flutter/flutter#183898
1 parent 6af85b2 commit fd286b0

18 files changed

Lines changed: 1444 additions & 262 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Track presubmit_filter_20260319 Context
2+
3+
- [Specification](./spec.md)
4+
- [Implementation Plan](./plan.md)
5+
- [Metadata](./metadata.json)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"track_id": "presubmit_filter_20260319",
3+
"type": "feature",
4+
"status": "new",
5+
"created_at": "2026-03-19T10:00:00Z",
6+
"updated_at": "2026-03-19T10:00:00Z",
7+
"description": "In 'CocoonAppBar' of Presubmit Dashboard add filter button to lust of actions that will show filer dialog and filer jobs in '_ChecksSidebar'."
8+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Implementation Plan - Presubmit Dashboard Job Filtering
2+
3+
This plan outlines the steps to add job filtering to the Presubmit Dashboard in the Cocoon dashboard.
4+
5+
## Phase 1: State Management (PresubmitState) [checkpoint: 48bff29]
6+
In this phase, we will extend `PresubmitState` to hold and manage the filter state.
7+
8+
- [x] **Task: Add filter state variables to `PresubmitState`.**
9+
- Variables: `Set<TaskStatus> selectedStatuses`, `Set<String> selectedPlatforms`, `String? jobNameFilter`.
10+
- Initialize with all statuses and platforms selected, and `null` or empty string for regex.
11+
- [x] **Task: Add methods to update filter state.**
12+
- `updateFilters({Set<TaskStatus>? statuses, Set<String>? platforms, String? jobNameFilter})`
13+
- `clearFilters()`: Resets filters to "select all" and clear regex.
14+
- [x] **Task: Implement filtering logic in `PresubmitState`.**
15+
- Add a getter `filteredGuardResponse` (or similar) that returns a `PresubmitGuardResponse` with filtered stages and builds based on the active filters.
16+
- Platforms are extracted by splitting job names by space and taking the first part.
17+
- [x] **Task: Add unit tests for `PresubmitState` filtering logic.**
18+
- Verify filtering by status, platform, and regex.
19+
- Verify persistence when `update` is called with same PR but different SHA.
20+
- [x] **Task: Conductor - User Manual Verification 'Phase 1: State Management' (Protocol in workflow.md)**
21+
22+
## Phase 2: Filter Dialog UI [checkpoint: 2903a30]
23+
In this phase, we will create the filter dialog and its components.
24+
25+
- [x] **Task: Create `FilterDialog` widget in `dashboard/lib/widgets/filter_dialog.dart`.**
26+
- Multi-select sections for Task Status and Platform.
27+
- `TextField` for Job Name Regex (with `onChanged` or `onEditingComplete` depending on final behavior).
28+
- Validation: Ensure at least one status and one platform are always selected (disable uncheck if it's the last one).
29+
- "Clear all filters" button at the bottom.
30+
- "Show N jobs" button displaying the filtered count.
31+
- [x] **Task: Add unit tests for `FilterDialog`.**
32+
- Verify initial state shows all filters.
33+
- Verify toggling selections updates the UI and buttons.
34+
- [x] **Task: Conductor - User Manual Verification 'Phase 2: Filter Dialog UI' (Protocol in workflow.md)**
35+
36+
## Phase 3: Integration and Dashboard UI [checkpoint: b499002]
37+
In this phase, we will integrate the filter functionality into the Presubmit Dashboard.
38+
39+
- [x] **Task: Add Filter Button to `CocoonAppBar` in `PreSubmitView`.**
40+
- Icon: `Icons.filter_alt_outlined` (no filters applied) or `Icons.filter_alt` (some filters applied).
41+
- Tooltip: "Filter jobs".
42+
- Hover highlight: "Filter jobs".
43+
- [x] **Task: Update `PreSubmitView` to use `filteredGuardResponse` for `_ChecksSidebar`.**
44+
- [x] **Task: Ensure filter state persists when switching guard statuses.**
45+
- Handled by `PresubmitState` during `update` calls.
46+
- [x] **Task: Add integration tests for filtering functionality in `PreSubmitView`.**
47+
- Verify clicking the filter button opens the dialog.
48+
- Verify applying filters updates the `_ChecksSidebar`.
49+
- [x] **Task: Conductor - User Manual Verification 'Phase 3: Integration and Dashboard UI' (Protocol in workflow.md)**
50+
51+
## Phase 4: Final Polishing and Cleanup [checkpoint: e03cad0]
52+
- [x] **Task: Verify overall dashboard performance with active filters.**
53+
- [x] **Task: Ensure accessibility (ARIA labels, tooltips).**
54+
- [x] **Task: Conductor - User Manual Verification 'Phase 4: Final Polishing and Cleanup' (Protocol in workflow.md)**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Specification - Presubmit Dashboard Job Filtering (v4)
2+
3+
## Overview
4+
This track aims to enhance the Presubmit Dashboard in the Cocoon dashboard by adding a filtering mechanism for CI jobs displayed in the `_ChecksSidebar`. This will allow users to quickly narrow down relevant jobs based on status, platform, and name (via regex), improving the usability and actionable visibility of build health.
5+
6+
## Functional Requirements
7+
* **Filter Button in CocoonAppBar:**
8+
- Add a filter icon button to the `CocoonAppBar` actions in the Presubmit Dashboard.
9+
- Icon: `Icons.filter_alt_outlined` (no filters applied) or `Icons.filter_alt` (some filters applied).
10+
- Tooltip: "Filter jobs".
11+
* **Filter Dialog:**
12+
- Clicking the filter button opens a dialog.
13+
- **Status Filter:** Multi-select list of all possible task statuses (e.g., Succeeded, Failed, In Progress, Queued, Skipped, etc.).
14+
- **Platform Filter:** Multi-select list of platform names, derived by splitting all unique job names by space and taking the first part.
15+
- **Job Name Regex Filter:** Text input for a regular expression to match against job names.
16+
- **Validation:** At least one task status and at least one platform must remain checked at all times.
17+
- **Clear All Filters:** A button at the bottom to reset all filters to their default state (all selected, regex empty).
18+
- **Show N Jobs:** A button displaying the total count of filtered jobs in the `_ChecksSidebar`.
19+
* **Filtering Logic:**
20+
- Filters apply immediately when a status or platform is toggled.
21+
- Regex filter applies when the input field loses focus (onBlur).
22+
- The `_ChecksSidebar` list of jobs updates in real-time based on the active filters.
23+
* **Persistence & State:**
24+
- Filter state is managed in `PresubmitState`.
25+
- Filters should remain if the user selects a different guard status.
26+
* **Visual Elements:**
27+
- Filter button should be `Icons.filter_alt_outlined` if no filters are applied, and `Icons.filter_alt` if some filters are applied.
28+
- Filter button should have text highlight "Filter jobs" on mouse over.
29+
30+
## Non-Functional Requirements
31+
* **Material Design:** Follow Material Design principles for the dialog and filter button.
32+
* **Performance:** Filtering should be efficient, even with a large number of jobs.
33+
* **Accessibility:** Use appropriate tooltips and labels for filter controls.
34+
35+
## Acceptance Criteria
36+
- [ ] Filter button in `CocoonAppBar` changes icon based on active filter state.
37+
- [ ] Filter dialog shows all active filters correctly upon opening.
38+
- [ ] `_ChecksSidebar` correctly displays only the jobs matching the active status, platform, and regex filters.
39+
- [ ] "Show N jobs" button reflects the correct count of filtered jobs.
40+
- [ ] At least one status and one platform are always selected in the dialog.
41+
- [ ] "Clear all filters" button resets the filter state.
42+
- [ ] Filter state persists when navigating between different guard statuses.
43+
44+
## Out of Scope
45+
- [ ] Permanent persistence of filters across browser sessions (e.g., in LocalStorage).
46+
- [ ] Complex multi-regex or boolean logic filters.
47+
- [ ] Filtering logic on the backend; all filtering is performed client-side in the Flutter dashboard.

conductor/product.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Cocoon is the CI coordination and orchestration system for the Flutter project.
1919
* **Tree Status Dashboard:** A Flutter-based web application that provides a visual overview of build health across various commits and branches.
2020
* **Presubmit Check Details:** Backend APIs to retrieve detailed attempt history and status for specific presubmit checks, aiding in debugging and visibility.
2121
* **Presubmit Guard Summaries:** Backend APIs to retrieve summaries of all presubmit checks (Presubmit Guards) of the provided pull request to the dashboard.
22+
* **Presubmit Dashboard Filtering:** Interactive filtering for the Presubmit Dashboard, allowing users to narrow down visible jobs by status, platform, and regex. Filters persist within a session and automatically manage valid job selection for the details pane.
2223
* **Presubmit Guard Details:** Displays detailed information and CI check statuses for a specific presubmit check (Presubmit Guard), sorted by status (prioritizing failures) and name for better visibility. Authenticated users can trigger re-runs for individual jobs or all failed jobs directly from the dashboard.
2324
* **Merge Queue Visibility:** APIs for querying and inspecting recent GitHub Merge Queue webhook events to diagnose integration issues.
2425
* **Auto-submit Bot:** Handles automated pull request management, including label-based merges, reverts, and validation checks.

dashboard/lib/service/data_seeder.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class DataSeeder {
6666
'Mac framework_tests',
6767
'Linux android framework_tests',
6868
'Windows framework_tests',
69+
'Mac_x64 framework_misc',
70+
'Linux_android_emu android_engine_opengles_tests',
71+
'Linux_android_emu_vulkan_stable android_engine_vulkan_tests',
72+
'Mac_arm64 run_debug_test_macos',
73+
'Linux_android_emu android views',
6974
];
7075
var engineChecks = [
7176
_createPresubmitCheck(
@@ -359,6 +364,41 @@ class DataSeeder {
359364
attemptNumber: 2,
360365
creationTime: creationTime2,
361366
),
367+
_createPresubmitCheck(
368+
checkRunId: checkRunId,
369+
buildName: fusionBuilds[4],
370+
status: TaskStatus.neutral,
371+
attemptNumber: 1,
372+
creationTime: creationTime,
373+
),
374+
_createPresubmitCheck(
375+
checkRunId: checkRunId,
376+
buildName: fusionBuilds[5],
377+
status: TaskStatus.neutral,
378+
attemptNumber: 1,
379+
creationTime: creationTime,
380+
),
381+
_createPresubmitCheck(
382+
checkRunId: checkRunId,
383+
buildName: fusionBuilds[6],
384+
status: TaskStatus.neutral,
385+
attemptNumber: 1,
386+
creationTime: creationTime,
387+
),
388+
_createPresubmitCheck(
389+
checkRunId: checkRunId,
390+
buildName: fusionBuilds[7],
391+
status: TaskStatus.neutral,
392+
attemptNumber: 1,
393+
creationTime: creationTime,
394+
),
395+
_createPresubmitCheck(
396+
checkRunId: checkRunId,
397+
buildName: fusionBuilds[8],
398+
status: TaskStatus.neutral,
399+
attemptNumber: 1,
400+
creationTime: creationTime,
401+
),
362402
];
363403
guards.add(
364404
_createPresubmitGuard(

0 commit comments

Comments
 (0)