-
Notifications
You must be signed in to change notification settings - Fork 367
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
upcoming: [M3-7429] - Add Parent/Proxy 'Switch Account' button and drawer to user profile dropdown menu #10031
Merged
mjac0bs
merged 13 commits into
linode:develop
from
mjac0bs:M3-7429-user-profile-dropdown-menu
Jan 8, 2024
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
8d029c8
Add switch account button and basic drawer
mjac0bs d31b711
List child accounts in drawer
mjac0bs 09248ec
Use render function
mjac0bs 204e92b
Correct comments so as not to confuse myself
mjac0bs 0431acf
Correct the button text
mjac0bs c520b4b
Clean up and make styling more closely match mocks
mjac0bs a730ba5
Make a component out of Switch Account button; add icon
mjac0bs 172e9de
More styling and clean up
mjac0bs c3c76ae
Added changeset: Add parent/proxy 'Switch Account' button and drawer β¦
mjac0bs d8676d5
Clean up and add WIP unit tests
mjac0bs 8dcd1c6
Clean up and fix z-index so user menu is focused on drawer close
mjac0bs ac786bf
Add tests for SwitchAccountDrawer
mjac0bs 0c983a8
Address feedback: use startIcon
mjac0bs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
packages/manager/.changeset/pr-10031-upcoming-features-1704467384095.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@linode/manager": Upcoming Features | ||
--- | ||
|
||
Add parent/proxy 'Switch Account' button and drawer to user profile dropdown menu ([#10031](https://github.com/linode/manager/pull/10031)) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions
12
packages/manager/src/features/Account/SwitchAccountButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import * as React from 'react'; | ||
|
||
import SwapIcon from 'src/assets/icons/swapSmall.svg'; | ||
import { Button, ButtonProps } from 'src/components/Button/Button'; | ||
|
||
export const SwitchAccountButton = (props: ButtonProps) => { | ||
return ( | ||
<Button startIcon={<SwapIcon />} {...props}> | ||
Switch Account | ||
</Button> | ||
); | ||
}; |
89 changes: 89 additions & 0 deletions
89
packages/manager/src/features/Account/SwitchAccountDrawer.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { fireEvent, within } from '@testing-library/react'; | ||
import * as React from 'react'; | ||
|
||
import { accountFactory } from 'src/factories/account'; | ||
import { accountUserFactory } from 'src/factories/accountUsers'; | ||
import { makeResourcePage } from 'src/mocks/serverHandlers'; | ||
import { rest, server } from 'src/mocks/testServer'; | ||
import { renderWithTheme } from 'src/utilities/testHelpers'; | ||
|
||
import { SwitchAccountDrawer } from './SwitchAccountDrawer'; | ||
|
||
const props = { | ||
onClose: vi.fn(), | ||
open: true, | ||
username: 'mock-user', | ||
}; | ||
|
||
describe('SwitchAccountDrawer', () => { | ||
it('should have a title', () => { | ||
const { getByText } = renderWithTheme(<SwitchAccountDrawer {...props} />); | ||
expect(getByText('Switch Account')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display helper text about the accounts', () => { | ||
const { getByText } = renderWithTheme(<SwitchAccountDrawer {...props} />); | ||
expect( | ||
getByText( | ||
'Select an account to view and manage its settings and configurations', | ||
{ exact: false } | ||
) | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('should include a link to switch back to the parent account if the active user is a proxy user', async () => { | ||
server.use( | ||
rest.get('*/account/users/*', (req, res, ctx) => { | ||
return res(ctx.json(accountUserFactory.build({ user_type: 'proxy' }))); | ||
}) | ||
); | ||
|
||
const { findByLabelText, getByText } = renderWithTheme( | ||
<SwitchAccountDrawer {...props} /> | ||
); | ||
|
||
expect( | ||
getByText( | ||
'Select an account to view and manage its settings and configurations', | ||
{ exact: false } | ||
) | ||
).toBeInTheDocument(); | ||
expect(await findByLabelText('parent-account-link')).toHaveTextContent( | ||
'switch back to your account' | ||
); | ||
}); | ||
|
||
it('should display a list of child accounts', async () => { | ||
server.use( | ||
rest.get('*/account/child-accounts', (req, res, ctx) => { | ||
return res( | ||
ctx.json( | ||
makeResourcePage( | ||
accountFactory.buildList(5, { company: 'Child Co.' }) | ||
) | ||
) | ||
); | ||
}) | ||
); | ||
|
||
const { findByTestId } = renderWithTheme( | ||
<SwitchAccountDrawer {...props} /> | ||
); | ||
|
||
const childAccounts = await findByTestId('child-account-list'); | ||
expect( | ||
within(childAccounts).getAllByText('Child Co.', { exact: false }) | ||
).toHaveLength(5); | ||
}); | ||
|
||
it('should close when the close icon is clicked', () => { | ||
const { getByLabelText } = renderWithTheme( | ||
<SwitchAccountDrawer {...props} /> | ||
); | ||
|
||
const closeIconButton = getByLabelText('Close drawer'); | ||
fireEvent.click(closeIconButton); | ||
|
||
expect(props.onClose).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
104 changes: 104 additions & 0 deletions
104
packages/manager/src/features/Account/SwitchAccountDrawer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Typography, styled } from '@mui/material'; | ||
import { AxiosHeaders } from 'axios'; | ||
import React from 'react'; | ||
|
||
import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; | ||
import { CircleProgress } from 'src/components/CircleProgress'; | ||
import { Drawer } from 'src/components/Drawer'; | ||
import { Notice } from 'src/components/Notice/Notice'; | ||
import { Stack } from 'src/components/Stack'; | ||
import { useFlags } from 'src/hooks/useFlags'; | ||
import { useChildAccounts } from 'src/queries/account'; | ||
import { useAccountUser } from 'src/queries/accountUsers'; | ||
import { useProfile } from 'src/queries/profile'; | ||
import { authentication } from 'src/utilities/storage'; | ||
|
||
interface Props { | ||
onClose: () => void; | ||
open: boolean; | ||
username: string; | ||
} | ||
|
||
export const SwitchAccountDrawer = (props: Props) => { | ||
const { onClose, open } = props; | ||
|
||
const flags = useFlags(); | ||
|
||
const handleClose = () => { | ||
onClose(); | ||
}; | ||
|
||
const { data: profile } = useProfile(); | ||
const { data: user } = useAccountUser(profile?.username ?? ''); | ||
|
||
// From proxy accounts, make a request on behalf of the parent account to fetch child accounts. | ||
const headers = | ||
flags.parentChildAccountAccess && user?.user_type === 'proxy' | ||
? new AxiosHeaders({ Authorization: authentication.token.get() }) // TODO: Parent/Child - M3-7430: replace this token with the parent token in local storage. | ||
: undefined; | ||
const { data: childAccounts, error, isLoading } = useChildAccounts({ | ||
headers, | ||
}); | ||
|
||
const renderChildAccounts = React.useCallback(() => { | ||
if (isLoading) { | ||
return <CircleProgress mini />; | ||
} | ||
|
||
if (childAccounts?.results === 0) { | ||
return <Notice variant="info">There are no child accounts.</Notice>; | ||
} | ||
|
||
if (error) { | ||
return ( | ||
<Notice variant="error"> | ||
There was an error loading child accounts. | ||
</Notice> | ||
); | ||
} | ||
|
||
return childAccounts?.data.map((childAccount, idx) => ( | ||
<StyledChildAccountLinkButton | ||
onClick={() => { | ||
// TODO: Parent/Child - M3-7430 | ||
// handleAccountSwitch(); | ||
}} | ||
key={`child-account-link-button-${idx}`} | ||
> | ||
{childAccount.company} | ||
</StyledChildAccountLinkButton> | ||
)); | ||
}, [childAccounts, error, isLoading]); | ||
|
||
return ( | ||
<Drawer onClose={handleClose} open={open} title="Switch Account"> | ||
<StyledTypography> | ||
Select an account to view and manage its settings and configurations | ||
{user?.user_type === 'proxy' && ( | ||
<> | ||
{' '} | ||
or {/* TODO: Parent/Child - M3-7430 */} | ||
<StyledLinkButton | ||
aria-label="parent-account-link" | ||
onClick={() => null} | ||
> | ||
switch back to your account | ||
</StyledLinkButton> | ||
</> | ||
)} | ||
. | ||
</StyledTypography> | ||
<Stack alignItems={'flex-start'} data-testid="child-account-list"> | ||
{renderChildAccounts()} | ||
</Stack> | ||
</Drawer> | ||
); | ||
}; | ||
|
||
const StyledTypography = styled(Typography)(({ theme }) => ({ | ||
margin: `${theme.spacing(3)} 0`, | ||
})); | ||
|
||
const StyledChildAccountLinkButton = styled(StyledLinkButton)(({ theme }) => ({ | ||
marginBottom: theme.spacing(2), | ||
})); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The SwitchAccountButton will be reused on the Account landing page for parent/proxy users. (M3-7475)