Skip to content

Conversation

@rodonnel-akamai
Copy link
Contributor

Description 📝

Adding in the functionality behind the Assign New Roles drawer for a single user

Changes 🔄

List any change(s) relevant to the reviewer.

  • Added Autocomplete for multiple roles to be selected
  • Allow user to add and remove roles within the drawer

Does not include (will be introduced in a future PR - TODO are listed in code):

  • Actual backend call - merely logs the results of the user selection when Assign is clicked
  • Link for help text
  • "Hide details" link, whose behavior is still not completely defined

Target release date 🗓️

(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.

Before (Figma) After
Screenshot 2025-03-12 at 11 50 58 AM Screenshot 2025-03-12 at 11 42 33 AM

How to test 🧪

Prerequisites

(How to setup test environment)

  • Ensure the Identity and Access Beta flag is enabled in dev tools
  • Ensure the MSW is enabled in dev tools
  • Click on the any username in the users table and go to the tab Assigned Roles or click on the user's menu View User Roles
  • Click on Assign New Role

Verification steps

(How to verify changes)

  • Confirm drawer opens
  • Multiple roles can be selected and removed
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


  • I have read and considered all applicable items listed above.

As an Author, before moving this PR from Draft to Open, I confirmed ✅

  • All unit tests are passing
  • TypeScript compilation succeeded without errors
  • Code passes all linting rules

@rodonnel-akamai rodonnel-akamai requested a review from a team as a code owner March 12, 2025 15:54
@rodonnel-akamai rodonnel-akamai requested review from dwiley-akamai and hana-akamai and removed request for a team March 12, 2025 15:54
@cpathipa cpathipa requested review from cpathipa and removed request for hana-akamai March 12, 2025 16:42
Copy link
Contributor

@jaalah-akamai jaalah-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rodonnel-akamai I tried to explain things as thoroughly as I could this time around since you've asked. There may be some gaps in what I suggested, but read our docs and look at some other examples already in IAM. Happy to clarify any questions! 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're going to want to refactor this to use React Hook Form so a lot of this is going to change.

Essentially, you'll want to do something like:

const form = useForm<AssignNewRoleFormValues>({
  defaultValues: {
    roles: [{ role: null }],
  },
});

// shared/utilities
export interface AssignNewRoleFormValues {
  roles: {
    role: RolesType | null;
  }[];
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing roles will be handled by remove handler provided by RHF

  const { control, handleSubmit, watch, reset } = form;
  const { append, fields, remove } = useFieldArray({
    control,
    name: 'roles',
  });

  // We want to watch changes to this value since we're conditionally rendering "Add another role"
  const roles = watch('roles');

Comment on lines 75 to 85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we're getting the roles from our RHF fields, this will have to change:

fields.map((field, index) => (
  <AssignSingleRole
    index={index}
    key={field.id}
    onRemove={() => remove(index)}
    options={allRoles}
    permissions={accountPermissions}
    selectedOption={field.role}
  />
))}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use values from RHF
values.roles.map((r) => r.role).filter(Boolean)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the roles that we're watching:

{roles.length > 0 && roles.every((field) => field.role) && (

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the built in append:

<LinkButton onClick={() => append({ role: null })}>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will no need for selectedOption anymore with RHF

Comment on lines 31 to 36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just inline this now that things are simpler:

<AssignedPermissionsPanel
  role={getRoleByName(permissions, value.value)}
/>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, we'll need to pass down the control via context:

const { control } = useFormContext<AssignNewRoleFormValues>();

Comment on lines 52 to 70
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to wrap this in a Controller from RHF so that it can update the parent fields:

<Controller
  render={({ field: { onChange, value } }) => (
    <>
      <Autocomplete
        onChange={(event, newValue) => {
          onChange(newValue);
        }}
        renderOption={(props, option) => (
          <li {...props} key={option.label}>
            {option.label}
          </li>
        )}
        label="Assign New Roles"
        options={options}
        placeholder="Select a Role"
        textFieldProps={{ hideLabel: true }}
        value={value || null}
      />
      {value && (
        <AssignedPermissionsPanel
          role={getRoleByName(permissions, value.value)}
        />
      )}
    </>
  )}
  control={control}
  name={`roles.${index}.role`}
/>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing with spacing tokens

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd petition UX to revisit having an X button that's always disabled rather than just not showing it. Less code, cleaner, and better accessibility.

@github-project-automation github-project-automation bot moved this from Review to Changes Requested in Cloud Manager Mar 12, 2025
Copy link
Contributor

@dwiley-akamai dwiley-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have the ESLint extension on the IDE you are using?

Comment on lines 41 to 42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
display={'flex'}
flexDirection={'column'}
display="flex"
flexDirection="column"

Comment on lines 46 to 50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Divider
sx={(theme) => ({
marginBottom: theme.spacing(1.5),
})}
></Divider>
<Divider
sx={(theme) => ({
marginBottom: theme.spacing(1.5),
})}
/>

@aaleksee-akamai
Copy link
Contributor

@jaalah-akamai thanks a lot for such a detailed explanation - it helped a lot! I’ve updated this PR according to your comments.

Copy link
Contributor

@cpathipa cpathipa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aaleksee-akamai This looks much better now. Thank you for addressing the feedback.

@cpathipa cpathipa added Add'tl Approval Needed Waiting on another approval! and removed Requires Changes labels Mar 17, 2025
@github-actions
Copy link

github-actions bot commented Mar 17, 2025

Coverage Report:
Base Coverage: 79.96%
Current Coverage: 79.96%

@aaleksee-akamai aaleksee-akamai force-pushed the UIE-8140-assign-roles-drawer branch from ba507a1 to 9066886 Compare March 18, 2025 16:12
@aaleksee-akamai
Copy link
Contributor

@cpathipa , I've resolved conflicts

@cpathipa cpathipa requested a review from dwiley-akamai March 25, 2025 15:13
Copy link
Contributor

@jaalah-akamai jaalah-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better 👍

@github-project-automation github-project-automation bot moved this from Changes Requested to Approved in Cloud Manager Mar 25, 2025
@jaalah-akamai jaalah-akamai added Approved Multiple approvals and ready to merge! and removed Add'tl Approval Needed Waiting on another approval! labels Mar 25, 2025
@linode-gh-bot
Copy link
Collaborator

Cloud Manager UI test results

🎉 533 passing tests on test run #11 ↗︎

❌ Failing✅ Passing↪️ Skipped🕐 Duration
0 Failing533 Passing4 Skipped92m 41s

@cpathipa cpathipa merged commit 129b9b4 into linode:develop Mar 25, 2025
25 checks passed
@github-project-automation github-project-automation bot moved this from Approved to Merged in Cloud Manager Mar 25, 2025
bill-akamai pushed a commit to bill-akamai/manager that referenced this pull request Mar 25, 2025
…11834)

* UIE-8140: Assign New Roles drawer update

* Added changeset: Adding in the functionality behind the Assign New Roles drawer for a single user in IAM

* fix with using FormProvider

* resolve conflicts and update the drawer for changing role

---------

Co-authored-by: Anastasiia Alekseenko <[email protected]>
Co-authored-by: cpathipa <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved Multiple approvals and ready to merge! IAM (Identity & Access Management)

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

6 participants