diff --git a/addons/api/addon/models/worker.js b/addons/api/addon/models/worker.js index 042c61554..c1fb4c8b5 100644 --- a/addons/api/addon/models/worker.js +++ b/addons/api/addon/models/worker.js @@ -36,6 +36,20 @@ export default class WorkerModel extends GeneratedWorkerModel { ); } + /** + * Returns the config tags as an array of key/value pair objects. + * @type {[object]} + */ + getConfigTagList() { + if (!this.config_tags) { + return null; + } + + return Object.entries(this.config_tags).flatMap(([key, value]) => + value.map((tag) => ({ key, value: tag })) + ); + } + @attr({ description: 'The deduplicated union of the tags reported by the worker ' + diff --git a/ui/admin/app/routes/scopes/scope/workers/index.js b/ui/admin/app/routes/scopes/scope/workers/index.js index 61b3b33e4..d275ecc1f 100644 --- a/ui/admin/app/routes/scopes/scope/workers/index.js +++ b/ui/admin/app/routes/scopes/scope/workers/index.js @@ -14,12 +14,23 @@ export default class ScopesScopeWorkersIndexRoute extends Route { const configTags = route .modelFor('scopes.scope.workers') .toArray() - .flatMap((worker) => worker.config_tags?.type) + .flatMap((worker) => worker.getConfigTagList()) .filter(Boolean); // Filter out duplicate tags - return [...new Set(configTags)]; + return configTags.reduce((uniqueConfigTags, currentTag) => { + const isDuplicateTag = uniqueConfigTags.some( + (tag) => tag.key === currentTag.key && tag.value === currentTag.value + ); + + if (!isDuplicateTag) { + uniqueConfigTags.push(currentTag); + } + return uniqueConfigTags; + }, []); }, + findBySerialized: ({ key: itemKey, value: itemValue }, { key, value }) => + itemKey === key && itemValue === value, refreshRouteOnChange: false, }) tags; @@ -32,11 +43,19 @@ export default class ScopesScopeWorkersIndexRoute extends Route { if (this.tags?.length) { // Return workers that have config tags that have at // least one intersection with the filter tags - return workers.filter( - (worker) => - worker.config_tags.type.filter(Set.prototype.has, new Set(this.tags)) - .length > 0 - ); + return workers.filter((worker) => { + if (!worker.config_tags) { + return null; + } + + const workerTags = worker.getConfigTagList(); + return this.tags.some((tag) => + workerTags.some( + (workerTag) => + tag.key === workerTag.key && tag.value === workerTag.value + ) + ); + }); } return workers; } @@ -61,6 +80,11 @@ export default class ScopesScopeWorkersIndexRoute extends Route { this.refresh(); } + @action + isEqual(firstTag, secondTag) { + return firstTag.key === secondTag.key && firstTag.value === secondTag.value; + } + setupController(controller) { const scope = this.modelFor('scopes.scope'); super.setupController(...arguments); diff --git a/ui/admin/app/templates/scopes/scope/workers/index.hbs b/ui/admin/app/templates/scopes/scope/workers/index.hbs index f489b3353..ac9cf75be 100644 --- a/ui/admin/app/templates/scopes/scope/workers/index.hbs +++ b/ui/admin/app/templates/scopes/scope/workers/index.hbs @@ -37,20 +37,30 @@ @ignoreClickInside={{true}} as |dropdown| > -