Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ For all available CLI options see the [Basic CLI docs](https://marketsquare.gith
- 📄 **Dashboard Pages** - Overview, Dashboard, and Compare pages for multi-level insights.
- 🎛️ **Customizable Layouts** - Drag-and-drop sections with adjustable size and order.
- 📊 **Graph Customization** - Toggle legends, axis titles, labels, and control animations.
- 🔎 **Global Filters** - Filter runs by name, tags, date, metadata, or quantity.
- 🔎 **Global Filters** - Filter runs by name, tags, date, metadata, or quantity. Every filter option shows how many runs it still matches, and options that match none are greyed out.
- ⚖️ **Comparison Mode** - Compare up to 4 runs side by side with visual statistics.
- 🔗 **Automatic Log Linking** - Open Robot Framework logs directly from the dashboard.
- 🔁 **Rerun History** - Merged `--rerunfailed` outputs keep the status of every attempt per test.
Expand Down
13 changes: 13 additions & 0 deletions docs/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ The **Dashboard** page provides both **global filters** and **section-specific f

Global filters are applied to the entire dashboard, affecting all sections and graphs. Open the filter modal using the filter icon in the top navigation bar.

#### Run Counts and Unavailable Options

Every option of the Runs, Run Tags, Versions, Metadata and Custom Filters dropdowns shows how many runs it still matches:

- The number behind an option is calculated with **all other filters applied**, so it tells you what you get if you select that option. The Amount filter ("most recent X runs") is not included, as it is not a category.
- The count of a filter **ignores that filter itself**. Selecting one Run Tag therefore never changes the counts of the other Run Tags, and they never disappear from the list.
- A count always answers the same question: *how many runs remain if this option is the selection of this filter*. In **NOT** mode an option excludes its runs, so its count is what is left over.
- Options that match no runs at all are **greyed out**. They stay visible and can still be selected (the dashboard then simply shows no runs), so you never lose sight of the values in your data.
- A custom filter that is hidden on the current page (see [Settings - Filters Tab](/settings#filter-settings-filters-tab)) is not applied there, so it does not count towards the numbers of the other filters either.
- Both can be turned off in [Settings](settings.md): *Display Run Counts in Filter Options* and *Grey Out Filter Options Without Runs*.

Example: with two custom filters where `filter_1=A` only ever occurs together with `filter_2=C`, selecting `filter_1=A` shows `filter_2=D (0)` greyed out, because no run has that combination.

#### 1. Runs

- Filters the dashboard to only show data for runs of the selected project (run name).
Expand Down
4 changes: 3 additions & 1 deletion docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ The **Defaults** tab controls initial dashboard behavior and default graph selec
| **Unified Dashboard Sections** | Show all dashboard sections in a single unified view (instead of separate run/suite/test/keyword sections). |
| **Suite Statistics – Default suite selection (dropdown)** | Selects which suite(s) are shown by default in the Suite Statistics tab. Options: `All Suites Separate`, `All Suites Combined`, or any individual suite. If the selected suite is removed from the data, the first available suite is used automatically. |
| **Test Statistics – Default suite selection (dropdown)** | Selects which suite is shown by default in the Test Statistics tab. Options: `All` or any individual suite. If the selected suite is removed from the data, the first available suite is used automatically. |
| **Display Run Counts in Filter Options** | Show behind every filter option how many runs it matches with the other filters applied. See [Filtering](filtering.md#run-counts-and-unavailable-options). |
| **Grey Out Filter Options Without Runs** | Dim the filter options that match no runs with the other filters applied. They stay visible and selectable. |

### Saving Settings

Expand Down Expand Up @@ -132,7 +134,7 @@ Each dropdown only lists the attributes found in the run data, so the lists are
Hiding an attribute on a page means:

- its dropdown is left out of the Filters dialog while that page is active
- its selection is **not applied** on that page, so the runs are filtered as if the attribute were not set
- its selection is **not applied** on that page, so the runs are filtered as if the attribute were not set, and it is left out of the [run counts](/filtering#run-counts-and-unavailable-options) of the other filters
- on the Overview it is also left off the run cards

The selection you made in the dropdown is kept, so the attribute filters again as soon as you switch to a page where it is still shown.
Expand Down
6 changes: 5 additions & 1 deletion robotframework_dashboard/css/colors.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
--color-menu-text: var(--color-text);
--color-highlight: #3451b2;
--color-text: #000000;
--color-text-muted: darkgrey;
--color-text-muted: #6c757d;
--color-text-disabled: #6c757d;
--color-popover-bg: #ffffff;
--color-border: rgba(0, 0, 0, 0.175);
--color-shadow-strong: rgba(0, 0, 0, 0.5);
--color-shadow-soft: rgba(0, 0, 0, 0.3);
Expand Down Expand Up @@ -35,6 +37,8 @@
--color-highlight: #a8b1ff;
--color-text: #eee;
--color-text-muted: #9ca3af;
--color-text-disabled: #94a3b8;
--color-popover-bg: #1e293b;
--color-border: rgba(255, 255, 255, 0.15);
--color-shadow-strong: rgba(0, 0, 0, 0.5);
--color-shadow-soft: rgba(0, 0, 0, 0.3);
Expand Down
65 changes: 64 additions & 1 deletion robotframework_dashboard/css/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,79 @@
bottom: 0;
}

/* The dropdown panel paints its own opaque surface: the rows inside it use
--color-card, which is semi-transparent in dark mode, so without this the modal rows
underneath the panel bleed through and nothing in the panel is readable. */
.filterCheckBoxes {
display: none;
position: absolute;
z-index: 2;
z-index: 1056;
background-color: var(--color-popover-bg);
border: 1px solid var(--color-border);
border-radius: 0.375rem;
box-shadow: 0 0.5rem 1rem var(--color-shadow-soft);
padding: 0.25rem;
}

.filterCheckBoxes .list-group-item {
background-color: transparent;
border-color: transparent;
}

.filterCheckBoxes label {
display: block;
}

/* the search box scrolls with the option list, so pin it to the top of the panel */
.filterCheckBoxes > input.form-control,
.filterCheckBoxes > .filter-search-wrapper {
position: sticky;
top: 0;
z-index: 1;
background-color: var(--color-popover-bg);
}

/* filter options that match no runs with the other filters applied: still visible and
selectable, only marked so it is clear they cannot add anything to the result. No
opacity: it dims the checkbox and the count as well, and it is ignored on <option>
elements in native select popups anyway. */
.filter-option-unavailable {
color: var(--color-text-disabled);
}

li.filter-option-unavailable {
background-color: color-mix(in srgb, var(--color-text-muted) 8%, transparent);
}

li.filter-option-unavailable > label.form-check-label {
color: var(--color-text-disabled);
text-decoration: line-through;
text-decoration-thickness: 1px;
}

/* the count is the reason a row is greyed out, so it keeps full contrast and sits in its
own right-aligned column instead of trailing a label of arbitrary length */
.filter-option-count {
color: var(--color-text-muted);
font-size: 0.85em;
margin-left: auto;
padding-left: 0.5rem;
flex: 0 0 auto;
font-variant-numeric: tabular-nums;
}

li.filter-option-unavailable > .filter-option-count {
font-weight: 600;
}

.filterCheckBoxes li.list-group-item > label.form-check-label {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.filter-search-wrapper {
position: relative;
}
Expand Down
13 changes: 13 additions & 0 deletions robotframework_dashboard/js/eventlisteners.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import {
clear_active_profile,
capture_default_filters,
merge_two_profiles,
schedule_filter_option_availability_refresh,
set_filter_modal_open,
collect_custom_filter_dimensions,
dashboardPages,
} from "./filter.js"
Expand Down Expand Up @@ -167,6 +169,8 @@ function setup_filter_modal() {
// eventlistener to catch the closing of the filter modal
// Only recompute filtered data and update graphs in-place (no layout rebuild needed)
document.getElementById("filtersModal").addEventListener("hide.bs.modal", function () {
// no more writing into the modal while it fades out
set_filter_modal_open(false);
show_loading_overlay();
requestAnimationFrame(() => {
requestAnimationFrame(() => {
Expand All @@ -176,6 +180,11 @@ function setup_filter_modal() {
});
});
});
// count the runs behind every filter option and grey out the ones that match nothing,
// also picking up filters that were set while the modal was closed (overview drill down)
document.getElementById("filtersModal").addEventListener("show.bs.modal", function () {
set_filter_modal_open(true);
});
// eventlistener to reset the filters
document.getElementById("resetFilters").addEventListener("click", function () {
clear_all_filters();
Expand Down Expand Up @@ -411,10 +420,12 @@ function setup_filter_modal() {
filterModal.addEventListener("change", function () {
update_profile_select_display();
update_filters_button_indicator();
schedule_filter_option_availability_refresh();
});
filterModal.addEventListener("input", function () {
update_profile_select_display();
update_filters_button_indicator();
schedule_filter_option_availability_refresh();
});
}

Expand Down Expand Up @@ -557,6 +568,8 @@ function setup_settings_modal() {
{ key: "show.suitesSelectionInSuiteStats", elementId: "toggleSuitesSelectionInSuiteStats", datatype: "string", event: "change" },
{ key: "show.suitesSelectionInTestStats", elementId: "toggleSuitesSelectionInTestStats", datatype: "string", event: "change" },
{ key: "show.overviewDurationPercentage", elementId: "overviewDurationPercentage", datatype: "number", event: "change" },
{ key: "show.filterAvailability", elementId: "toggleFilterAvailability" },
{ key: "show.filterCounts", elementId: "toggleFilterCounts" },
].forEach(def => {
const handler = create_toggle_handler(def);
handler(true);
Expand Down
Loading