Chore optimize iam queries (#1198)
* chore: 🤖 add scope column to role principals and group members * chore: 🤖 add recursion and filtering to user and group mocks * feat: 🎸 expose groups and roles on projects * feat: 🎸 enable cross-scope assignment of group members * chore: 🤖 query group members in a single call via filtering * chore: 🤖 query role prinicipals in two calls via filtering * chore: 🤖 use const instead of let
This commit is contained in:
1 parent
bc76d49729
commit
ca1b2ce278
3 files changed
+55
-42
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { hash, all } from 'rsvp';
|
||||
import { hash } from 'rsvp';
|
||||
import { loading } from 'ember-loading';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
@@ -11,6 +11,7 @@ export default class ScopesScopeGroupsGroupMembersRoute extends Route {
|
||||
|
||||
@service intl;
|
||||
@service notify;
|
||||
@service resourceFilterStore;
|
||||
|
||||
// =methods
|
||||
|
||||
@@ -19,15 +20,16 @@ export default class ScopesScopeGroupsGroupMembersRoute extends Route {
|
||||
* @return {Promise{group: GroupModel, members: Promise{[UserModel]}}}
|
||||
*/
|
||||
model() {
|
||||
const { id: scopeID } = this.modelFor('scopes.scope');
|
||||
const group = this.modelFor('scopes.scope.groups.group');
|
||||
return hash({
|
||||
group,
|
||||
members: all(
|
||||
group.member_ids.map((id) =>
|
||||
this.store.findRecord('user', id, { adapterOptions: { scopeID } })
|
||||
)
|
||||
),
|
||||
members: group.member_ids?.length
|
||||
? this.resourceFilterStore.queryBy(
|
||||
'user',
|
||||
{ id: group.member_ids },
|
||||
{ scope_id: 'global', recursive: true }
|
||||
)
|
||||
: [],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { all, hash } from 'rsvp';
|
||||
import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { loading } from 'ember-loading';
|
||||
@@ -10,6 +9,7 @@ export default class ScopesScopeRolesRolePrincipalsRoute extends Route {
|
||||
// =services
|
||||
@service intl;
|
||||
@service notify;
|
||||
@service resourceFilterStore;
|
||||
|
||||
// =methods
|
||||
|
||||
@@ -18,31 +18,43 @@ export default class ScopesScopeRolesRolePrincipalsRoute extends Route {
|
||||
* @param {object} params
|
||||
* @return {Promise{RoleModel}}
|
||||
*/
|
||||
model() {
|
||||
const adapterOptions = { scopeID: this.modelFor('scopes.scope').id };
|
||||
async model() {
|
||||
const role = this.modelFor('scopes.scope.roles.role');
|
||||
const users = role.principals
|
||||
|
||||
// Gather user and group IDs as separate arrays, since these
|
||||
// will be queried in separate API queries.
|
||||
const userIDs = role.principals
|
||||
.filterBy('type', 'user')
|
||||
.map(({ principal_id }) =>
|
||||
this.store
|
||||
.findRecord('user', principal_id, { adapterOptions })
|
||||
.then((model) => ({
|
||||
type: 'user',
|
||||
model,
|
||||
}))
|
||||
);
|
||||
const groups = role.principals
|
||||
.map(({ principal_id }) => principal_id);
|
||||
const groupIDs = role.principals
|
||||
.filterBy('type', 'group')
|
||||
.map(({ principal_id }) =>
|
||||
this.store.findRecord('group', principal_id).then((model) => ({
|
||||
type: 'group',
|
||||
model,
|
||||
}))
|
||||
);
|
||||
return hash({
|
||||
.map(({ principal_id }) => principal_id);
|
||||
|
||||
// Query for users.
|
||||
const users = userIDs?.length
|
||||
? (
|
||||
await this.resourceFilterStore.queryBy(
|
||||
'user',
|
||||
{ id: userIDs },
|
||||
{ scope_id: 'global', recursive: true }
|
||||
)
|
||||
).map((model) => model)
|
||||
: [];
|
||||
// Query for groups.
|
||||
const groups = groupIDs?.length
|
||||
? (
|
||||
await this.resourceFilterStore.queryBy(
|
||||
'group',
|
||||
{ id: groupIDs },
|
||||
{ scope_id: 'global', recursive: true }
|
||||
)
|
||||
).map((model) => model)
|
||||
: [];
|
||||
|
||||
return {
|
||||
role,
|
||||
principals: all(users.concat(groups)),
|
||||
});
|
||||
principals: users.concat(groups),
|
||||
};
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
@@ -46,36 +46,38 @@
|
||||
{{#each @model.principals as |principal|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell>
|
||||
{{principal.model.displayName}}
|
||||
{{#if principal.model.accountName}}
|
||||
<br /><Rose::Badge
|
||||
>{{principal.model.accountName}}</Rose::Badge>
|
||||
{{principal.displayName}}
|
||||
{{#if principal.accountName}}
|
||||
<br /><Rose::Badge>{{principal.accountName}}</Rose::Badge>
|
||||
{{/if}}
|
||||
</row.headerCell>
|
||||
<row.cell>
|
||||
<Copyable
|
||||
@text={{principal.model.id}}
|
||||
@text={{principal.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{principal.model.id}}</code>
|
||||
<code>{{principal.id}}</code>
|
||||
</Copyable>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<Rose::Badge
|
||||
@icon={{if
|
||||
(eq principal.type 'group')
|
||||
(eq principal.constructor.modelName 'group')
|
||||
'flight-icons/svg/folder-users-16'
|
||||
'flight-icons/svg/user-16'
|
||||
}}
|
||||
>
|
||||
{{t
|
||||
(concat 'resources.role.principal.types.' principal.type)
|
||||
(concat
|
||||
'resources.role.principal.types.'
|
||||
principal.constructor.modelName
|
||||
)
|
||||
}}
|
||||
</Rose::Badge>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<ScopeBadge @scope={{principal.model.scopeModel}} />
|
||||
<ScopeBadge @scope={{principal.scopeModel}} />
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
{{#if (can 'removePrincipals role' @model.role)}}
|
||||
@@ -89,10 +91,7 @@
|
||||
>
|
||||
<dropdown.button
|
||||
@style='danger'
|
||||
{{on
|
||||
'click'
|
||||
(route-action 'removePrincipal' principal.model)
|
||||
}}
|
||||
{{on 'click' (route-action 'removePrincipal' principal)}}
|
||||
>
|
||||
{{t 'actions.remove'}}
|
||||
</dropdown.button>
|
||||
|
||||
Reference in new issue
Block a user