From b86ce41e682630efe80f95c08a5e55c125fe4b99 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Wed, 24 Jan 2024 10:18:28 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20use=20filter=20query=20pa?= =?UTF-8?q?ram=20to=20filter=20by=20org=20scope=20id=20(#2103)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 use filter query param to filter by org scope id ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 remove duplicate call for scopes.scope model ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 add filter to allTargets and sessions query ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 reset query params for targets and sessions on org scope change ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 remove open/close parens from filter string ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 Update logic on when to reset query parameters ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 filter sessions query by parent scope isOrg ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 update to & from transition references ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 * refactor: 💡 update to & from transition references for sessions ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12309 --------- Co-authored-by: Zhihe Li --- .../scopes/scope/projects/sessions/index.js | 13 +++- .../scopes/scope/projects/sessions/index.js | 67 +++++++++++++------ .../scopes/scope/projects/targets/index.js | 60 ++++++++++------- 3 files changed, 94 insertions(+), 46 deletions(-) diff --git a/ui/desktop/app/controllers/scopes/scope/projects/sessions/index.js b/ui/desktop/app/controllers/scopes/scope/projects/sessions/index.js index 5e9022ce0..36090783c 100644 --- a/ui/desktop/app/controllers/scopes/scope/projects/sessions/index.js +++ b/ui/desktop/app/controllers/scopes/scope/projects/sessions/index.js @@ -8,7 +8,12 @@ import { inject as service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import orderBy from 'lodash/orderBy'; -import { statusTypes } from 'api/models/session'; +import { + STATUS_SESSION_ACTIVE, + STATUS_SESSION_PENDING, + STATUS_SESSION_CANCELING, + statusTypes, +} from 'api/models/session'; export default class ScopesScopeProjectsSessionsIndexController extends Controller { // =services @@ -26,7 +31,11 @@ export default class ScopesScopeProjectsSessionsIndexController extends Controll ]; @tracked targets = []; - @tracked status = ['active', 'pending', 'canceling']; + @tracked status = [ + STATUS_SESSION_ACTIVE, + STATUS_SESSION_PENDING, + STATUS_SESSION_CANCELING, + ]; @tracked scopes = []; @tracked page = 1; @tracked pageSize = 10; diff --git a/ui/desktop/app/routes/scopes/scope/projects/sessions/index.js b/ui/desktop/app/routes/scopes/scope/projects/sessions/index.js index 9c0b1fe74..7576afe89 100644 --- a/ui/desktop/app/routes/scopes/scope/projects/sessions/index.js +++ b/ui/desktop/app/routes/scopes/scope/projects/sessions/index.js @@ -6,6 +6,11 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; +import { + STATUS_SESSION_ACTIVE, + STATUS_SESSION_PENDING, + STATUS_SESSION_CANCELING, +} from 'api/models/session'; export default class ScopesScopeProjectsSessionsIndexRoute extends Route { // =services @@ -64,8 +69,10 @@ export default class ScopesScopeProjectsSessionsIndexRoute extends Route { async model({ targets, status, scopes, page, pageSize }, transition) { const from = transition.from?.name; const projects = this.modelFor('scopes.scope.projects'); - const projectIds = projects.map((project) => project.id); - const { id: scope_id } = this.modelFor('scopes.scope'); + const orgScope = this.modelFor('scopes.scope'); + // orgFilter used to narrow down resources to only those under + // the current org scope if org is not global + const orgFilter = `"/item/scope/parent_scope_id" == "${orgScope.id}"`; const filters = { user_id: [{ equals: this.session.data.authenticated.user_id }], @@ -82,42 +89,48 @@ export default class ScopesScopeProjectsSessionsIndexRoute extends Route { scopes.forEach((scope) => { filters.scope_id.push({ equals: scope }); }); - if (scopes.length === 0) { - projectIds.forEach((projectId) => { - filters.scope_id.push({ equals: projectId }); - }); - } const queryOptions = { - scope_id, + scope_id: orgScope.id, recursive: true, query: { filters }, page, pageSize, force_refresh: true, }; + if (orgScope.isOrg && scopes.length === 0) { + queryOptions.filter = orgFilter; + } const sessions = await this.store.query('session', queryOptions); const totalItems = sessions.meta?.totalItems; // Query all sessions and all targets for defining filtering values if entering route for the first time if (from !== 'scopes.scope.projects.sessions.index') { const options = { pushToStore: false }; - this.allSessions = await this.store.query( - 'session', - { - scope_id, - recursive: true, - query: { - filters: { - user_id: [{ equals: this.session.data.authenticated.user_id }], - }, + const allSessionsQuery = { + scope_id: orgScope.id, + recursive: true, + query: { + filters: { + user_id: [{ equals: this.session.data.authenticated.user_id }], }, }, + }; + if (orgScope.isOrg && scopes.length === 0) { + allSessionsQuery.filter = orgFilter; + } + this.allSessions = await this.store.query( + 'session', + allSessionsQuery, options, ); + const allTargetsQuery = { scope_id: orgScope.id, recursive: true }; + if (orgScope.isOrg) { + allTargetsQuery.filter = orgFilter; + } this.allTargets = await this.store.query( 'target', - { scope_id, recursive: true }, + allTargetsQuery, options, ); } @@ -133,11 +146,23 @@ export default class ScopesScopeProjectsSessionsIndexRoute extends Route { } resetController(controller, isExiting, transition) { - const { to } = transition; - // Reset the scopes query param when changing org scope - if (!isExiting && to.queryParams.scopes === '[]') { + const fromScope = transition.from.find( + (routeInfo) => routeInfo.name === 'scopes.scope', + ).params.scope_id; + const toScope = transition.to.find( + (routeInfo) => routeInfo.name === 'scopes.scope', + ).params.scope_id; + + // Reset the query params when changing scope context + if (fromScope !== toScope) { controller.setProperties({ scopes: [], + targets: [], + status: [ + STATUS_SESSION_ACTIVE, + STATUS_SESSION_PENDING, + STATUS_SESSION_CANCELING, + ], }); } } diff --git a/ui/desktop/app/routes/scopes/scope/projects/targets/index.js b/ui/desktop/app/routes/scopes/scope/projects/targets/index.js index d3907c97d..f2786ab20 100644 --- a/ui/desktop/app/routes/scopes/scope/projects/targets/index.js +++ b/ui/desktop/app/routes/scopes/scope/projects/targets/index.js @@ -84,29 +84,26 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route { { search, scopes, availableSessions, types, page, pageSize }, transition, ) { - const { id: scope_id } = this.modelFor('scopes.scope'); - await this.getAllTargets(transition, scope_id); + const orgScope = this.modelFor('scopes.scope'); + // orgFilter used to narrow down resources to only those under + // the current org scope if org is not global + const orgFilter = `"/item/scope/parent_scope_id" == "${orgScope.id}"`; + await this.getAllTargets(transition, orgScope, orgFilter); const projects = this.modelFor('scopes.scope.projects'); - const projectIds = projects.map((project) => project.id); const filters = { scope_id: [], id: { values: [] }, type: [] }; scopes.forEach((scope) => { filters.scope_id.push({ equals: scope }); }); - if (scopes.length === 0) { - projectIds.forEach((projectId) => { - filters.scope_id.push({ equals: projectId }); - }); - } types.forEach((type) => { filters.type.push({ equals: type }); }); // Retrieve all sessions so that the session and activeSessions getters // in the target model always retrieve the most up-to-date sessions. - const sessions = await this.store.query('session', { + const sessionQuery = { recursive: true, - scope_id, + scope_id: orgScope.id, query: { filters: { user_id: [{ equals: this.session.data.authenticated.user_id }], @@ -117,18 +114,26 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route { }, }, force_refresh: true, - }); + }; + if (orgScope.isOrg && scopes.length === 0) { + sessionQuery.filter = orgFilter; + } + const sessions = await this.store.query('session', sessionQuery); this.addActiveSessionFilters(filters, availableSessions, sessions); - let targets = await this.store.query('target', { + const query = { recursive: true, - scope_id, + scope_id: orgScope.id, query: { search, filters }, page, pageSize, force_refresh: true, - }); + }; + if (orgScope.isOrg && scopes.length === 0) { + query.filter = orgFilter; + } + let targets = await this.store.query('target', query); const totalItems = targets.meta?.totalItems; // Filter out targets to which users do not have the connect ability @@ -146,11 +151,20 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route { } resetController(controller, isExiting, transition) { - const { to } = transition; - // Reset the scopes query param when changing org scope - if (!isExiting && to.queryParams.scopes === '[]') { + const fromScope = transition.from.find( + (routeInfo) => routeInfo.name === 'scopes.scope', + ).params.scope_id; + const toScope = transition.to.find( + (routeInfo) => routeInfo.name === 'scopes.scope', + ).params.scope_id; + + // Reset the query params when changing scope context + if (fromScope !== toScope) { controller.setProperties({ scopes: [], + availableSessions: [], + types: [], + search: '', }); } } @@ -161,17 +175,17 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route { * @param transition * @returns {Promise} */ - async getAllTargets(transition, scope_id) { + async getAllTargets(transition, orgScope, orgFilter) { const from = transition.from?.name; // Query all targets for defining filtering values if entering route for first time if (from !== 'scopes.scope.projects.targets.index') { + const query = { scope_id: orgScope.id, recursive: true }; + if (orgScope.isOrg) { + query.filter = orgFilter; + } const options = { pushToStore: false }; - const allTargets = await this.store.query( - 'target', - { scope_id, recursive: true }, - options, - ); + const allTargets = await this.store.query('target', query, options); // Filter out targets to which users do not have the connect ability this.allTargets = allTargets.filter((target) =>