feat: 🎸 Refactor session recording filters (#2981)

This commit has a few notable changes:

1. A simple attempt at establishing a pattern for using SELECT statements. This will be useful in the future for joins/subquery support.
2. Expanded usage of searching to be able to pass instead of just a string, an object that lets a consumer choose which columns to search on.
3. Decouple our session recording filters from being loaded from the route model hook which is a departure from our convention. This has the benefit of actually letting the page first load and having the filters load async so the page doesn't wait for the filters to finish. This is also much faster to query for each individual filter option from SQLite rather than returning all data to filter in application code.
This commit is contained in:
Zhihe Li authored and GitHub committed 2025-10-31 16:58:05 -04:00
1 parent 72f7c8a92d
commit fa18bfff01
18 files changed
+558 -250

No files matched your search

@@ -232,35 +232,13 @@ module('Acceptance | session-recordings | list', function (hooks) {
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 2 });
await click(commonSelectors.FILTER_DROPDOWN('user'));
await waitFor(commonSelectors.FILTER_DROPDOWN_ITEM(instances.user.id));
await click(commonSelectors.FILTER_DROPDOWN_ITEM(instances.user.id));
await click(commonSelectors.FILTER_DROPDOWN_ITEM_APPLY_BTN('user'));
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 1 });
});
test('user can filter session recordings by scope', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-01
enabled: false,
},
},
});
await visit(urls.globalScope);
await click(commonSelectors.HREF(urls.sessionRecordings));
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 2 });
await click(commonSelectors.FILTER_DROPDOWN('target'));
await click(commonSelectors.FILTER_DROPDOWN_ITEM(instances.target.id));
await click(commonSelectors.FILTER_DROPDOWN_ITEM_APPLY_BTN('target'));
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 1 });
});
test('user can filter session recordings by target', async function (assert) {
setRunOptions({
rules: {
@@ -277,7 +255,34 @@ module('Acceptance | session-recordings | list', function (hooks) {
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 2 });
await click(commonSelectors.FILTER_DROPDOWN('target'));
await waitFor(commonSelectors.FILTER_DROPDOWN_ITEM(instances.target.id));
await click(commonSelectors.FILTER_DROPDOWN_ITEM(instances.target.id));
await click(commonSelectors.FILTER_DROPDOWN_ITEM_APPLY_BTN('target'));
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 1 });
});
test('user can filter session recordings by scope', async function (assert) {
setRunOptions({
rules: {
'color-contrast': {
// [ember-a11y-ignore]: axe rule "color-contrast" automatically ignored on 2025-08-01
enabled: false,
},
},
});
await visit(urls.globalScope);
await click(commonSelectors.HREF(urls.sessionRecordings));
assert.dom(commonSelectors.TABLE_ROWS).isVisible({ count: 2 });
await click(commonSelectors.FILTER_DROPDOWN('scope'));
await waitFor(
commonSelectors.FILTER_DROPDOWN_ITEM(instances.target.scope.id),
);
await click(
commonSelectors.FILTER_DROPDOWN_ITEM(instances.target.scope.id),
);
@@ -93,44 +93,6 @@ module(
date.restore();
});
test('it exists', function (assert) {
assert.ok(controller);
});
test('filters returns expected entries', function (assert) {
assert.deepEqual(controller.filters.allFilters, {
time: [
{
id: last24Hours.toISOString(),
name: 'Last 24 hours',
},
{
id: last3Days.toISOString(),
name: 'Last 3 days',
},
{
id: last7Days.toISOString(),
name: 'Last 7 days',
},
],
users: [{ id: instances.user.id, name: instances.user.name }],
scopes: [
{
id: instances.scopes.project.id,
name: instances.scopes.project.name,
parent_scope_id: instances.scopes.project.parent_scope_id,
},
],
targets: [{ id: instances.target.id, name: instances.target.name }],
});
assert.deepEqual(controller.filters.selectedFilters, {
time: [null],
users: [],
scopes: [],
targets: [],
});
});
test('timeOptions returns expected filter options', function (assert) {
assert.deepEqual(controller.timeOptions, [
{
@@ -148,16 +110,6 @@ module(
]);
});
test('projectScopes returns an array of unique projects', function (assert) {
assert.deepEqual(controller.projectScopes, [
{
id: instances.scopes.project.id,
name: instances.scopes.project.name,
parent_scope_id: instances.scopes.project.parent_scope_id,
},
]);
});
test('handleSearchInput action sets expected values correctly', async function (assert) {
// Date mock in beforeEach is causing waitUntil to fail so I restore it
// back before running this test
@@ -186,21 +138,5 @@ module(
assert.strictEqual(controller.page, 1);
assert.deepEqual(controller.time, last24Hours.toISOString());
});
test('refresh action calls refreshAll', async function (assert) {
assert.expect(2);
controller.set('target', {
send(actionName, ...args) {
assert.strictEqual(actionName, 'refreshAll');
assert.deepEqual(
args,
[],
'refreshAll was called with the correct arguments',
);
},
});
await controller.refresh();
});
},
);