-
Notifications
You must be signed in to change notification settings - Fork 368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: [UIE-8139] - IAM RBAC: add new assigned entities table component part 1 #11588
base: develop
Are you sure you want to change the base?
feat: [UIE-8139] - IAM RBAC: add new assigned entities table component part 1 #11588
Conversation
1ca7141
to
f2f22e7
Compare
|
||
export const StyledTypography = styled(Typography, { | ||
label: 'StyledTypography', | ||
})(({ theme }) => ({ | ||
color: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we don't need it, as @jaalah-akamai mentioned earlier
Coverage Report: ✅ |
roles: EntitiesRole[] | RoleMap[]; | ||
} | ||
|
||
export const getFilteredRoles = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the same functionality in two components (AssignedRolesTable
and AssignedEntitiesTable
), with the only difference being the searchableFields
. So, I’ve combined the logic for both components and passed searchableFields as a parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make getSearchableFields
an optional field in the options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we could make getSearchableFields
optional, but for that, we need a default implementation of searchableFields
. Right now, this function is only used in two components (that I mentioned above), so making it optional would add flexibility, but it’s worth considering whether it’s necessary at this stage. If we expect to expand its usage further, introducing a default getSearchableFields
function could make sense. Otherwise, keeping it explicitly required for now might be a simpler and more controlled approach
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. At least we should make it part of the options
object, no need to have multiple arguments to this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, it makes sense, thanks @hkhalil-akamai
value?: string; | ||
} | ||
|
||
export const mapEntityTypes = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same situation here — the only difference is the ending
<DebouncedSearchTextField | ||
clearable | ||
debounceTime={250} | ||
hideLabel | ||
label="Filter" | ||
onSearch={setQuery} | ||
placeholder="Search" | ||
sx={{ marginRight: 2, width: 410 }} | ||
value={query} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the search doesn't involve any network requests, do we need to debounce it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, remove it, thanks
roles: EntitiesRole[] | RoleMap[]; | ||
} | ||
|
||
export const getFilteredRoles = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. At least we should make it part of the options
object, no need to have multiple arguments to this function.
Does this project have an API spec yet? I noticed that the return type of API Also, the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR looks really good, nice job
The failing test is just due to the name change View User Roles
> View Assigned Roles
}, | ||
]; | ||
|
||
const memoizedTableItems = React.useMemo(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this useMemo
all together. There's nothing in here that would greatly benefit from it. We wouldn't even need to worry about memoizing getFilteredRoles
since that's a pure function and memoization is more for equality checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaalah-akamai , @cpathipa , just circling back on this — would appreciate your thoughts. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally suggested using useMemo
in the previous PR to avoid recalculating on every render. I think we are using map with a map there. The idea was to optimize performance, but if it's not providing significant benefits, I’m open to revisiting that decision.
if (resource) { | ||
resourceRole.roles.forEach((r: RoleType) => { | ||
result.push({ | ||
id: r + '-' + resourceRole.resource_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: lets use template strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
|
||
if (resource) { | ||
resourceRole.roles.forEach((r: RoleType) => { | ||
result.push({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: using a map
here would a little more straightforward
data: assignedRoles, | ||
error: assignedRolesError, | ||
isLoading: assignedRolesLoading, | ||
} = useAccountUserPermissions(username ?? ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the current implementation of useAccountUserPermissions
does not handle cases where username is undefined
or empty
, which can lead to unnecessary API calls or API failures.
We might need to update useAccountUserPermissions
hook accordingly
example:
export const useAccountUserPermissions = (username?: string) => {
return useQuery<IamUserPermissions, APIError[]>(
iamQueries.user(username ?? '')._ctx.permissions,
{ enabled: Boolean(username) }
);
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for noticing that @cpathipa , I've had a look at the code and it seems like a lot of cases are missing that check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! In CM, we generally use the enabled
flag in most queries. We can always improve and update the missing ones as we revisit them.
f2f22e7
to
bda1fdf
Compare
|
||
if (resource) { | ||
result.push( | ||
...resourceRole.roles.map((r: RoleType) => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaalah-akamai , please check if this is what you mean with using map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaleksee-akamai I was more saying that by using a map
you don't need to have the results variable or push anything to the array since the map
returns an array of the values already. Spreading the results of the map and pushing that into the array is redundant.
const addResourceNamesToRoles = (
assignedRoles: IamUserPermissions,
resources: IamAccountResource
): EntitiesRole[] => {
const resourcesRoles = assignedRoles.resource_access;
const resourcesArray: IamAccountResource[] = Object.values(resources);
return resourcesRoles.flatMap((resourceRole: ResourceAccess) => {
const resourceByType = resourcesArray.find(
(r: IamAccountResource) => r.resource_type === resourceRole.resource_type
);
if (resourceByType) {
const resource = resourceByType.resources.find(
(res: Resource) => res.id === resourceRole.resource_id
);
if (resource) {
return resourceRole.roles.map((r: RoleType) => ({
id: r + '-' + resourceRole.resource_id,
resource_id: resourceRole.resource_id,
resource_name: resource.name,
resource_type: resourceRole.resource_type,
role_name: r,
}));
}
}
return [];
});
};
export const useAccountUserPermissions = (username?: string) => { | ||
return useQuery<IamUserPermissions, APIError[]>({ | ||
...iamQueries.user(username ?? '')._ctx.permissions, | ||
enabled: Boolean(username), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpathipa , please check if it's a correct implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, LGTM!
data: assignedRoles, | ||
error: assignedRolesError, | ||
isLoading: assignedRolesLoading, | ||
} = useAccountUserPermissions(username ?? ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! In CM, we generally use the enabled
flag in most queries. We can always improve and update the missing ones as we revisit them.
}, | ||
]; | ||
|
||
const memoizedTableItems = React.useMemo(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally suggested using useMemo
in the previous PR to avoid recalculating on every render. I think we are using map with a map there. The idea was to optimize performance, but if it's not providing significant benefits, I’m open to revisiting that decision.
export const useAccountUserPermissions = (username?: string) => { | ||
return useQuery<IamUserPermissions, APIError[]>({ | ||
...iamQueries.user(username ?? '')._ctx.permissions, | ||
enabled: Boolean(username), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, LGTM!
bda1fdf
to
0d1b863
Compare
Cloud Manager UI test results🔺 1 failing test on test run #4 ↗︎
Details
TroubleshootingUse this command to re-run the failing tests: yarn cy:run -s "cypress/e2e/core/volumes/create-volume.spec.ts" |
Description 📝
IAM RBAC - new assigned entities table component.
Changes 🔄
List any change(s) relevant to the reviewer.
do not include (will be introduced in the next PR):
Target release date 🗓️
2/11/25 (dev)
Preview 📷
Include a screenshot or screen recording of the change.
🔒 Use the Mask Sensitive Data setting for security.
💡 Use
<video src="" />
tag when including recordings in table.How to test 🧪
Prerequisites
(How to setup test environment)
Assigned Entities
or click on the user's menuView Assigned Entities
Verification steps
(How to verify changes)
Author Checklists
As an Author, to speed up the review process, I considered 🤔
👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support
As an Author, before moving this PR from Draft to Open, I confirmed ✅