feat: 🎸 target list will update according to org scope selected (#2083)
* feat: 🎸 target list will update according to org scope selected ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12205 * refactor: 💡 add comment to resetController logic ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12205 * feat: 🎸 filter sessions by org selected at global level ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12205
This commit is contained in:
1 parent
ba0c7d5683
commit
9046c01238
6 files changed
+171
-29
No files matched your search
@@ -62,6 +62,8 @@ 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 filters = {
|
||||
user_id: [{ equals: this.session.data.authenticated.user_id }],
|
||||
@@ -78,6 +80,11 @@ 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 = {
|
||||
query: { filters },
|
||||
@@ -105,8 +112,6 @@ export default class ScopesScopeProjectsSessionsIndexRoute extends Route {
|
||||
this.allTargets = await this.store.query('target', {}, options);
|
||||
}
|
||||
|
||||
const projects = this.modelFor('scopes.scope.projects');
|
||||
|
||||
return {
|
||||
sessions,
|
||||
projects,
|
||||
@@ -115,4 +120,14 @@ export default class ScopesScopeProjectsSessionsIndexRoute extends Route {
|
||||
totalItems,
|
||||
};
|
||||
}
|
||||
|
||||
resetController(controller, isExiting, transition) {
|
||||
const { to } = transition;
|
||||
// Reset the scopes query param when changing org scope
|
||||
if (!isExiting && to.queryParams.scopes === '[]') {
|
||||
controller.setProperties({
|
||||
scopes: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,11 +84,18 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route {
|
||||
transition,
|
||||
) {
|
||||
await this.getAllTargets(transition);
|
||||
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 });
|
||||
});
|
||||
@@ -124,7 +131,6 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route {
|
||||
targets = targets.filter((target) =>
|
||||
this.can.can('connect target', target),
|
||||
);
|
||||
const projects = this.modelFor('scopes.scope.projects');
|
||||
|
||||
return {
|
||||
targets,
|
||||
@@ -134,6 +140,16 @@ 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 === '[]') {
|
||||
controller.setProperties({
|
||||
scopes: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the targets but only load them once when entering the route. Ideally we would lazy load it when needed
|
||||
* but this can be revisited in the future.
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<LinkTo
|
||||
@route='scopes.scope.projects.sessions.session.index'
|
||||
@model={{B.data.id}}
|
||||
data-test-session-detail-link
|
||||
data-test-session-detail-link={{B.data.id}}
|
||||
>
|
||||
<Hds::Text::Code>{{B.data.id}}</Hds::Text::Code>
|
||||
</LinkTo>
|
||||
@@ -101,7 +101,7 @@
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<Hds::Text::Code
|
||||
data-test-session-id-copy
|
||||
data-test-session-id-copy={{B.data.id}}
|
||||
>{{B.data.id}}</Hds::Text::Code>
|
||||
</Copyable>
|
||||
{{/if}}
|
||||
|
||||
@@ -127,7 +127,9 @@
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<Hds::Text::Code>{{B.data.project.id}}</Hds::Text::Code>
|
||||
<Hds::Text::Code
|
||||
data-test-target-project-id={{B.data.project.id}}
|
||||
>{{B.data.project.id}}</Hds::Text::Code>
|
||||
</Copyable>
|
||||
</div>
|
||||
{{#if B.data.project.name}}
|
||||
|
||||
@@ -35,19 +35,25 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
org2: null,
|
||||
project: null,
|
||||
project2: null,
|
||||
},
|
||||
authMethods: {
|
||||
global: null,
|
||||
},
|
||||
user: null,
|
||||
target: null,
|
||||
target2: null,
|
||||
session: null,
|
||||
session2: null,
|
||||
};
|
||||
|
||||
const urls = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
org2: null,
|
||||
},
|
||||
authenticate: {
|
||||
global: null,
|
||||
@@ -56,7 +62,9 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
},
|
||||
},
|
||||
projects: null,
|
||||
projects2: null,
|
||||
sessions: null,
|
||||
sessions2: null,
|
||||
session: null,
|
||||
};
|
||||
|
||||
@@ -74,7 +82,10 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
authenticateSession({ user_id: instances.user.id });
|
||||
|
||||
// create scopes
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.global = this.server.create('scope', {
|
||||
id: 'global',
|
||||
name: 'Global',
|
||||
});
|
||||
const globalScope = { id: 'global', type: 'global' };
|
||||
instances.scopes.org = this.server.create('scope', {
|
||||
type: 'org',
|
||||
@@ -85,7 +96,17 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
type: 'project',
|
||||
scope: orgScope,
|
||||
});
|
||||
instances.scopes.org2 = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: globalScope,
|
||||
});
|
||||
const org2Scope = { id: instances.scopes.org2.id, type: 'org' };
|
||||
instances.scopes.project2 = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: org2Scope,
|
||||
});
|
||||
|
||||
// create resources
|
||||
instances.authMethods.global = this.server.create('auth-method', {
|
||||
scope: instances.scopes.global,
|
||||
});
|
||||
@@ -104,13 +125,33 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
},
|
||||
'withAssociations',
|
||||
);
|
||||
// create resources in second org
|
||||
instances.target2 = this.server.create(
|
||||
'target',
|
||||
{ scope: instances.scopes.project2 },
|
||||
'withAssociations',
|
||||
);
|
||||
instances.session2 = this.server.create(
|
||||
'session',
|
||||
{
|
||||
scope: instances.scopes.project2,
|
||||
target: instances.target2,
|
||||
status: STATUS_SESSION_ACTIVE,
|
||||
user: instances.user,
|
||||
},
|
||||
'withAssociations',
|
||||
);
|
||||
|
||||
urls.scopes.global = `/scopes/${instances.scopes.global.id}`;
|
||||
urls.scopes.org = `/scopes/${instances.scopes.org.id}`;
|
||||
urls.scopes.org2 = `/scopes/${instances.scopes.org2.id}`;
|
||||
urls.authenticate.global = `${urls.scopes.global}/authenticate`;
|
||||
urls.authenticate.methods.global = `${urls.authenticate.global}/${instances.authMethods.global.id}`;
|
||||
urls.projects = `${urls.scopes.org}/projects`;
|
||||
urls.projects2 = `${urls.scopes.org2}/projects`;
|
||||
urls.globalSessions = `${urls.scopes.global}/projects/sessions`;
|
||||
urls.sessions = `${urls.projects}/sessions`;
|
||||
urls.sessions2 = `${urls.projects2}/sessions`;
|
||||
urls.session = `${urls.projects}/sessions/${instances.session.id}`;
|
||||
|
||||
// Mock the postMessage interface used by IPC.
|
||||
@@ -169,7 +210,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await visit(urls.projects);
|
||||
|
||||
await click(`[href="${urls.sessions}"]`);
|
||||
await click('[data-test-session-detail-link]');
|
||||
await click(`[data-test-session-detail-link="${instances.session.id}"]`);
|
||||
|
||||
assert.strictEqual(currentURL(), urls.session);
|
||||
});
|
||||
@@ -181,9 +222,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await visit(urls.sessions);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -195,9 +234,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await click(`[href="${urls.sessions}"]`);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -209,9 +246,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await click(`[href="${urls.sessions}"]`);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -223,9 +258,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await click(`[href="${urls.sessions}"]`);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -235,12 +268,10 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await visit(urls.sessions);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.doesNotExist();
|
||||
assert
|
||||
.dom('tbody tr:first-child td:first-child [data-test-session-id-copy]')
|
||||
.dom(`[data-test-session-id-copy="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -250,12 +281,10 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
await visit(urls.sessions);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
'tbody tr:first-child td:first-child [data-test-session-detail-link]',
|
||||
)
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.doesNotExist();
|
||||
assert
|
||||
.dom('tbody tr:first-child td:first-child [data-test-session-id-copy]')
|
||||
.dom(`[data-test-session-id-copy="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
@@ -332,4 +361,41 @@ module('Acceptance | projects | sessions | index', function (hooks) {
|
||||
|
||||
assert.dom('[role="alert"].is-error').isVisible();
|
||||
});
|
||||
|
||||
test('user can change org scope and only sessions for that org will be displayed', async function (assert) {
|
||||
this.stubClientDaemonSearch(
|
||||
'sessions',
|
||||
'sessions',
|
||||
'targets',
|
||||
'targets',
|
||||
'sessions',
|
||||
'targets',
|
||||
{
|
||||
resource: 'sessions',
|
||||
func: () => [instances.session2],
|
||||
},
|
||||
'sessions',
|
||||
'targets',
|
||||
);
|
||||
await visit(urls.globalSessions);
|
||||
|
||||
assert
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.isVisible();
|
||||
assert
|
||||
.dom(`[data-test-session-detail-link="${instances.session2.id}"]`)
|
||||
.isVisible();
|
||||
|
||||
// change scope in app header
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-of-type(3)');
|
||||
// navigate to back sessions
|
||||
await click(`[href="${urls.sessions2}"]`);
|
||||
|
||||
assert
|
||||
.dom(`[data-test-session-detail-link="${instances.session.id}"]`)
|
||||
.doesNotExist();
|
||||
assert
|
||||
.dom(`[data-test-session-detail-link="${instances.session2.id}"]`)
|
||||
.isVisible();
|
||||
});
|
||||
});
|
||||
@@ -47,12 +47,15 @@ module('Acceptance | projects | targets | index', function (hooks) {
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
org2: null,
|
||||
project: null,
|
||||
project2: null,
|
||||
},
|
||||
authMethods: {
|
||||
global: null,
|
||||
},
|
||||
target: null,
|
||||
target2: null,
|
||||
session: null,
|
||||
};
|
||||
|
||||
@@ -85,7 +88,10 @@ module('Acceptance | projects | targets | index', function (hooks) {
|
||||
this.server.get('/targets', ({ targets }) => targets.all());
|
||||
|
||||
// Generate scopes
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.global = this.server.create('scope', {
|
||||
id: 'global',
|
||||
name: 'Global',
|
||||
});
|
||||
const globalScope = { id: 'global', type: 'global' };
|
||||
instances.scopes.org = this.server.create('scope', {
|
||||
type: 'org',
|
||||
@@ -96,6 +102,15 @@ module('Acceptance | projects | targets | index', function (hooks) {
|
||||
type: 'project',
|
||||
scope: orgScope,
|
||||
});
|
||||
instances.scopes.org2 = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: globalScope,
|
||||
});
|
||||
const org2Scope = { id: instances.scopes.org2.id, type: 'org' };
|
||||
instances.scopes.project2 = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: org2Scope,
|
||||
});
|
||||
|
||||
// Generate resources
|
||||
instances.authMethods.global = this.server.create('auth-method', {
|
||||
@@ -119,6 +134,10 @@ module('Acceptance | projects | targets | index', function (hooks) {
|
||||
},
|
||||
'withAssociations',
|
||||
);
|
||||
instances.target2 = this.server.create('target', {
|
||||
scope: instances.scopes.project2,
|
||||
address: 'localhost',
|
||||
});
|
||||
|
||||
// Generate route URLs for resources
|
||||
urls.scopes.global = `/scopes/${instances.scopes.global.id}`;
|
||||
@@ -412,4 +431,28 @@ module('Acceptance | projects | targets | index', function (hooks) {
|
||||
|
||||
assert.strictEqual(currentURL(), urls.session);
|
||||
});
|
||||
|
||||
test('user can change org scope and only targets for that org will be displayed', async function (assert) {
|
||||
this.stubClientDaemonSearch('targets', 'sessions', 'targets', 'sessions', {
|
||||
resource: 'targets',
|
||||
func: () => [instances.target],
|
||||
});
|
||||
|
||||
await visit(urls.scopes.global);
|
||||
|
||||
assert
|
||||
.dom(`[data-test-target-project-id="${instances.scopes.project.id}"]`)
|
||||
.exists();
|
||||
assert
|
||||
.dom(`[data-test-target-project-id="${instances.scopes.project2.id}"]`)
|
||||
.exists();
|
||||
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-of-type(2)');
|
||||
assert
|
||||
.dom(`[data-test-target-project-id="${instances.scopes.project.id}"]`)
|
||||
.exists();
|
||||
assert
|
||||
.dom(`[data-test-target-project-id="${instances.scopes.project2.id}"]`)
|
||||
.doesNotExist();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user