fix: 🐛 Fix filters sometimes not being displayed (#3050)

One of the changes that was made was not retrieving all resources for the dropdown filters. 
This had an unintended consequence when displaying the selected filters as it's possible for the selected filter to not be in the list of allFilters.

There's two main scenarios this happens (the prerequisite is having more filter options than we display which is 250):

* When filtering down the dropdown filters which means it might not be in the allFilters options. This was fixed by keeping track of all the searched options to be able to display.
* A user uses a query string or bookmarked a URL and goes to it directly. If the option isn't in the initial load, we won't have the actual option. In this case, I changed it to at least just display the ID instead of not showing up at all. Otherwise I'd have to load these selected options separately from the initial load which doesn't seem worth for this edge case.
This commit is contained in:
Zhihe Li authored and GitHub committed 2025-11-11 11:57:04 -05:00
1 parent 189a453e8b
commit 58cc9e56fc
3 files changed
+52 -13

No files matched your search

@@ -17,16 +17,27 @@ export default class FilterTagsIndexComponent extends Component {
get filters() {
const { allFilters, selectedFilters } = this.args.filters;
return Object.entries(allFilters).flatMap(([key, value]) => {
assert(`Tags must be an array for key ${key}`, Array.isArray(value));
const paramsSet = new Set(selectedFilters[key]);
const filters = value.filter((item) => paramsSet.has(item.id));
return Object.entries(allFilters).flatMap(([key, values]) => {
assert(`Tags must be an array for key ${key}`, Array.isArray(values));
const uniqueSelectedFilters = [...new Set(selectedFilters[key])];
if (!uniqueSelectedFilters.length) {
return [];
}
return filters.map((item) => ({
id: item.id,
name: item.name,
type: key,
}));
const valueMap = new Map(values.map((value) => [value.id, value.name]));
return uniqueSelectedFilters.filter(Boolean).map((item) => {
const filter = {
id: item,
type: key,
};
if (valueMap.has(item)) {
filter.name = valueMap.get(item);
}
return filter;
});
});
}
@@ -22,4 +22,14 @@ module('Integration | Component | filter-tags/index', function (hooks) {
assert.dom('.hds-tag__text').hasText('Project 1');
});
test('it renders id if allFilter does not have corresponding value', async function (assert) {
this.set('filter', {
allFilters: { scopes: [{ id: '2', name: 'Project 2' }] },
selectedFilters: { scopes: ['1'] },
});
await render(hbs`<FilterTags @filters={{this.filter}} />`);
assert.dom('.hds-tag__text').hasText('1');
});
});
@@ -12,7 +12,25 @@ import { restartableTask } from 'ember-concurrency';
class FilterOptions {
@tracked search;
@tracked options = [];
@tracked _options = [];
#allOptions = new Map();
get options() {
return this._options;
}
set options(newOptions) {
this._options = newOptions;
newOptions.forEach((option) => {
this.#allOptions.set(option.id, option);
});
}
// Keep track of all filter options that are loaded so they can be
// displayed in the selected filters regardless of search input
get allOptions() {
return Array.from(this.#allOptions.values());
}
}
export default class ScopesScopeSessionRecordingsIndexController extends Controller {
@@ -60,9 +78,9 @@ export default class ScopesScopeSessionRecordingsIndexController extends Control
return {
allFilters: {
time: this.timeOptions,
users: this.userFilters.options,
scopes: this.scopeFilters.options,
targets: this.targetFilters.options,
users: this.userFilters.allOptions,
scopes: this.scopeFilters.allOptions,
targets: this.targetFilters.allOptions,
},
selectedFilters: {
time: [this.time],