From 4083fce78bfb1822d3ad42baf6080a19005bd37d Mon Sep 17 00:00:00 2001 From: Jaalah Ramos <jaalah.ramos@gmail.com> Date: Mon, 11 Mar 2024 11:23:12 -0400 Subject: [PATCH 1/4] upcoming: [M3-7857] - Account Management Copy/Updates --- packages/manager/src/MainContent.tsx | 1 + .../Account/CloseAccountSetting.test.tsx | 11 ++++------ .../features/Account/CloseAccountSetting.tsx | 22 ++++++++++++++----- .../features/Account/SwitchAccountDrawer.tsx | 3 ++- .../manager/src/features/Account/constants.ts | 9 ++++---- .../UpdateContactInformationForm.tsx | 9 +++++++- .../Profile/APITokens/APITokenTable.tsx | 17 +++++++------- .../features/TopMenu/UserMenu/UserMenu.tsx | 8 ++++--- 8 files changed, 51 insertions(+), 29 deletions(-) diff --git a/packages/manager/src/MainContent.tsx b/packages/manager/src/MainContent.tsx index 0d762133050..2d162b3bc5f 100644 --- a/packages/manager/src/MainContent.tsx +++ b/packages/manager/src/MainContent.tsx @@ -195,6 +195,7 @@ export const MainContent = () => { const SwitchAccountSessionProvider = switchAccountSessionContext.Provider; const switchAccountSessionContextValue = useDialogContext({ + inChildAccount: false, isOpen: false, }); diff --git a/packages/manager/src/features/Account/CloseAccountSetting.test.tsx b/packages/manager/src/features/Account/CloseAccountSetting.test.tsx index de7cab700ec..8d6e1cb39d7 100644 --- a/packages/manager/src/features/Account/CloseAccountSetting.test.tsx +++ b/packages/manager/src/features/Account/CloseAccountSetting.test.tsx @@ -7,7 +7,8 @@ import { renderWithTheme } from 'src/utilities/testHelpers'; import CloseAccountSetting from './CloseAccountSetting'; import { CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, - PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, + PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, + PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, } from './constants'; // Mock the useProfile hook to immediately return the expected data, circumventing the HTTP request and loading state. @@ -60,9 +61,7 @@ describe('Close Account Settings', () => { expect(getByRole('tooltip')).toBeInTheDocument(); }); - expect( - getByText(PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT) - ).toBeVisible(); + expect(getByText(PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT)).toBeVisible(); expect(button).toHaveAttribute('aria-describedby', 'button-tooltip'); expect(button).not.toHaveAttribute('disabled'); expect(button).toHaveAttribute('aria-disabled', 'true'); @@ -110,9 +109,7 @@ describe('Close Account Settings', () => { expect(getByRole('tooltip')).toBeInTheDocument(); }); - expect( - getByText(PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT) - ).toBeVisible(); + expect(getByText(PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT)).toBeVisible(); expect(button).toHaveAttribute('aria-describedby', 'button-tooltip'); expect(button).not.toHaveAttribute('disabled'); expect(button).toHaveAttribute('aria-disabled', 'true'); diff --git a/packages/manager/src/features/Account/CloseAccountSetting.tsx b/packages/manager/src/features/Account/CloseAccountSetting.tsx index 6158a5b0970..440fe8b7993 100644 --- a/packages/manager/src/features/Account/CloseAccountSetting.tsx +++ b/packages/manager/src/features/Account/CloseAccountSetting.tsx @@ -9,7 +9,8 @@ import { useProfile } from 'src/queries/profile'; import CloseAccountDialog from './CloseAccountDialog'; import { CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, - PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, + PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, + PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT, } from './constants'; const CloseAccountSetting = () => { @@ -22,10 +23,21 @@ const CloseAccountSetting = () => { const isCloseAccountDisabled = Boolean( flags.parentChildAccountAccess && profile?.user_type !== 'default' ); - const closeAccountButtonTooltipText = - isCloseAccountDisabled && profile?.user_type === 'child' - ? CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT - : PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT; + + let closeAccountButtonTooltipText; + const userType = profile?.user_type; + const caseKey = isCloseAccountDisabled ? userType : 'default'; + + switch (caseKey) { + case 'child': + closeAccountButtonTooltipText = CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT; + break; + case 'proxy': + closeAccountButtonTooltipText = PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT; + break; + default: + closeAccountButtonTooltipText = PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT; + } return ( <> diff --git a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx index 216ccece28a..96d8cfbb6b3 100644 --- a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx +++ b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx @@ -13,7 +13,7 @@ import { } from 'src/features/Account/utils'; import { useCurrentToken } from 'src/hooks/useAuthentication'; import { sendSwitchToParentAccountEvent } from 'src/utilities/analytics'; -import { getStorage } from 'src/utilities/storage'; +import { getStorage, setStorage } from 'src/utilities/storage'; import { ChildAccountList } from './SwitchAccounts/ChildAccountList'; @@ -155,6 +155,7 @@ export const SwitchAccountDrawer = (props: Props) => { } updateCurrentTokenBasedOnUserType({ userType: 'parent' }); + setStorage('proxy_user', 'false'); handleClose(); refreshPage(); }, [handleClose, refreshPage]); diff --git a/packages/manager/src/features/Account/constants.ts b/packages/manager/src/features/Account/constants.ts index 0d41b0493e0..2bce29439d9 100644 --- a/packages/manager/src/features/Account/constants.ts +++ b/packages/manager/src/features/Account/constants.ts @@ -1,5 +1,6 @@ export const PARENT_USER = 'parent user'; export const ADMINISTRATOR = 'account administrator'; +export const CUSTOMER_SUPPORT = 'customer support'; export const grantTypeMap = { account: 'Account', @@ -15,11 +16,11 @@ export const grantTypeMap = { vpc: 'VPCs', } as const; -export const PARENT_PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = - 'Remove indirect customers before closing the account.'; +export const PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = + 'Remove child accounts before closing the account.'; export const CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact your ${PARENT_USER} to close your account.`; - +export const PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact ${CUSTOMER_SUPPORT} to close this account.`; export const PARENT_SESSION_EXPIRED = `Session expired. Please log in again to your ${PARENT_USER} account.`; - +export const PROXY_RESTRICTED_PAT_TOOLTIP_TEXT = `You can't create access tokens for child accounts. Instead, switch to your account and create the token there.`; export const RESTRICTED_FIELD_TOOLTIP = 'This account type cannot update this field.'; diff --git a/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx b/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx index 05d57cf7b77..25503bd6aa6 100644 --- a/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx +++ b/packages/manager/src/features/Billing/BillingPanels/ContactInfoPanel/UpdateContactInformationForm/UpdateContactInformationForm.tsx @@ -57,7 +57,14 @@ const UpdateContactInformationForm = ({ focusEmail, onClose }: Props) => { zip: account?.zip, }, async onSubmit(values) { - await mutateAsync(values); + const clonedValues = { ...values }; + + if (isParentUser) { + // This is a disabled field that we want to omit from payload. + delete clonedValues.company; + } + + await mutateAsync(clonedValues); // If there's a "billing_email_bounce" notification on the account, and // the user has just updated their email, re-request notifications to diff --git a/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx b/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx index 79ead3dc7a3..58e1615d570 100644 --- a/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx +++ b/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx @@ -2,8 +2,8 @@ import { Token } from '@linode/api-v4/lib/profile'; import Grid from '@mui/material/Unstable_Grid2'; import * as React from 'react'; -import AddNewLink from 'src/components/AddNewLink'; import { Box } from 'src/components/Box'; +import { Button } from 'src/components/Button/Button'; import { DateTimeDisplay } from 'src/components/DateTimeDisplay'; import { PaginationFooter } from 'src/components/PaginationFooter/PaginationFooter'; import { Table } from 'src/components/Table'; @@ -17,6 +17,7 @@ import { TableRowLoading } from 'src/components/TableRowLoading/TableRowLoading' import { StyledTableSortCell } from 'src/components/TableSortCell/StyledTableSortCell'; import { TableSortCell } from 'src/components/TableSortCell/TableSortCell'; import { Typography } from 'src/components/Typography'; +import { PROXY_RESTRICTED_PAT_TOOLTIP_TEXT } from 'src/features/Account/constants'; import { SecretTokenDialog } from 'src/features/Profile/SecretTokenDialog/SecretTokenDialog'; import { useFlags } from 'src/hooks/useFlags'; import { useOrder } from 'src/hooks/useOrder'; @@ -205,16 +206,16 @@ export const APITokenTable = (props: Props) => { </Grid> <StyledAddNewWrapper> {type === 'Personal Access Token' && ( - <AddNewLink - disabledReason={ - isProxyUser - ? 'You can only create tokens for your own company.' - : undefined + <Button + tooltipText={ + isProxyUser ? PROXY_RESTRICTED_PAT_TOOLTIP_TEXT : undefined } + buttonType="primary" disabled={isProxyUser} - label="Create a Personal Access Token" onClick={() => setIsCreateOpen(true)} - /> + > + Create a Personal Access Token + </Button> )} </StyledAddNewWrapper> </StyledRootContainer> diff --git a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx index 68280bf0d39..3f72af54be6 100644 --- a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx +++ b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx @@ -25,7 +25,7 @@ import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGran import { useAccount } from 'src/queries/account'; import { useGrants, useProfile } from 'src/queries/profile'; import { sendSwitchAccountEvent } from 'src/utilities/analytics'; -import { getStorage } from 'src/utilities/storage'; +import { getStorage, setStorage } from 'src/utilities/storage'; interface MenuLink { display: string; @@ -116,7 +116,9 @@ export const UserMenu = React.memo(() => { React.useEffect(() => { // Run after we've switched to a proxy user. - if (isProxyUser) { + if (isProxyUser && !getStorage('proxy_user')) { + setStorage('proxy_user', 'true'); + enqueueSnackbar(`Account switched to ${companyName}.`, { variant: 'success', }); @@ -266,7 +268,7 @@ export const UserMenu = React.memo(() => { > <Stack data-qa-user-menu minWidth={250} spacing={2}> {canSwitchBetweenParentOrProxyAccount && ( - <Typography>You are currently logged in as:</Typography> + <Typography>Current account:</Typography> )} <Typography color={(theme) => theme.textColors.headlineStatic} From d46ca3b2bded4c7e849323fb0944a4001762c3e0 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos <jaalah.ramos@gmail.com> Date: Mon, 11 Mar 2024 11:36:11 -0400 Subject: [PATCH 2/4] Added changeset: Parent/Child Account Management Copy Updates & Improvements --- .../.changeset/pr-10270-upcoming-features-1710171371281.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-10270-upcoming-features-1710171371281.md diff --git a/packages/manager/.changeset/pr-10270-upcoming-features-1710171371281.md b/packages/manager/.changeset/pr-10270-upcoming-features-1710171371281.md new file mode 100644 index 00000000000..94286f2a2ec --- /dev/null +++ b/packages/manager/.changeset/pr-10270-upcoming-features-1710171371281.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +Parent/Child Account Management Copy Updates & Improvements ([#10270](https://github.com/linode/manager/pull/10270)) From 3b2e2b7c2c098119441cd394768a88c116a6af8e Mon Sep 17 00:00:00 2001 From: Jaalah Ramos <jaalah.ramos@gmail.com> Date: Tue, 12 Mar 2024 10:50:48 -0400 Subject: [PATCH 3/4] Update to latest copy - combined some constants - updated tests --- .../e2e/core/account/display-settings.spec.ts | 9 +++---- .../account/personal-access-tokens.spec.ts | 25 ++++++++++--------- .../e2e/core/account/user-profile.spec.ts | 13 +++++----- packages/manager/src/MainContent.tsx | 1 - .../features/Account/SwitchAccountDrawer.tsx | 7 ++++-- .../manager/src/features/Account/constants.ts | 15 +++++++---- .../Profile/APITokens/APITokenMenu.tsx | 3 ++- .../Profile/APITokens/APITokenTable.tsx | 4 +-- .../features/TopMenu/UserMenu/UserMenu.tsx | 1 + 9 files changed, 43 insertions(+), 35 deletions(-) diff --git a/packages/manager/cypress/e2e/core/account/display-settings.spec.ts b/packages/manager/cypress/e2e/core/account/display-settings.spec.ts index a08f8e04b94..72f3a3bd68b 100644 --- a/packages/manager/cypress/e2e/core/account/display-settings.spec.ts +++ b/packages/manager/cypress/e2e/core/account/display-settings.spec.ts @@ -11,6 +11,7 @@ import { interceptGetProfile } from 'support/intercepts/profile'; import { mockUpdateUsername } from 'support/intercepts/account'; import { ui } from 'support/ui'; import { randomString } from 'support/util/random'; +import { RESTRICTED_FIELD_TOOLTIP } from 'src/features/Account/constants'; const verifyUsernameAndEmail = ( mockRestrictedProxyProfile: Profile, @@ -50,9 +51,7 @@ const verifyUsernameAndEmail = ( .should('be.disabled') .trigger('mouseover'); // Click the button first, then confirm the tooltip is shown - ui.tooltip - .findByText('This account type cannot update this field.') - .should('be.visible'); + ui.tooltip.findByText(RESTRICTED_FIELD_TOOLTIP).should('be.visible'); } }; @@ -108,7 +107,7 @@ describe('Display Settings', () => { verifyUsernameAndEmail( mockRestrictedProxyProfile, - 'This account type cannot update this field.', + RESTRICTED_FIELD_TOOLTIP, true ); }); @@ -121,7 +120,7 @@ describe('Display Settings', () => { verifyUsernameAndEmail( mockUnrestrictedProxyProfile, - 'This account type cannot update this field.', + RESTRICTED_FIELD_TOOLTIP, true ); }); diff --git a/packages/manager/cypress/e2e/core/account/personal-access-tokens.spec.ts b/packages/manager/cypress/e2e/core/account/personal-access-tokens.spec.ts index 860799908c5..7e5f0b0f9c6 100644 --- a/packages/manager/cypress/e2e/core/account/personal-access-tokens.spec.ts +++ b/packages/manager/cypress/e2e/core/account/personal-access-tokens.spec.ts @@ -20,6 +20,7 @@ import { mockGetFeatureFlagClientstream, } from 'support/intercepts/feature-flags'; import { makeFeatureFlagData } from 'support/util/feature-flags'; +import { PROXY_USER_RESTRICTED_TOOLTIP_TEXT } from 'src/features/Account/constants'; describe('Personal access tokens', () => { /* @@ -268,17 +269,6 @@ describe('Personal access tokens', () => { '@getAppTokens', ]); - // Find 'Create a Personal Access Token' button, confirm it is disabled and tooltip displays. - ui.button - .findByTitle('Create a Personal Access Token') - .should('be.visible') - .should('be.disabled') - .click(); - - ui.tooltip - .findByText('You can only create tokens for your own company.') - .should('be.visible'); - // Find token in list, confirm "Rename" is disabled and tooltip displays. cy.findByText(proxyToken.label) .should('be.visible') @@ -292,7 +282,7 @@ describe('Personal access tokens', () => { }); ui.tooltip - .findByText('Only company users can edit API tokens.') + .findByText(PROXY_USER_RESTRICTED_TOOLTIP_TEXT) .should('be.visible'); // Confirm that token has not been renamed, initiate revocation. @@ -319,6 +309,17 @@ describe('Personal access tokens', () => { .click(); }); + // Find 'Create a Personal Access Token' button, confirm it is disabled and tooltip displays. + ui.button + .findByTitle('Create a Personal Access Token') + .should('be.visible') + .should('be.disabled') + .click(); + + ui.tooltip + .findByText(PROXY_USER_RESTRICTED_TOOLTIP_TEXT) + .should('be.visible'); + // Confirm that token is removed from list after revoking. cy.wait(['@revokeToken', '@getTokens']); ui.toast.assertMessage(`Successfully revoked ${proxyToken.label}`); diff --git a/packages/manager/cypress/e2e/core/account/user-profile.spec.ts b/packages/manager/cypress/e2e/core/account/user-profile.spec.ts index 3f56aab2206..1d36175f276 100644 --- a/packages/manager/cypress/e2e/core/account/user-profile.spec.ts +++ b/packages/manager/cypress/e2e/core/account/user-profile.spec.ts @@ -9,7 +9,10 @@ import { import { randomString } from 'support/util/random'; import { ui } from 'support/ui'; import { mockUpdateProfile } from 'support/intercepts/profile'; -import { PARENT_USER } from 'src/features/Account/constants'; +import { + PARENT_USER, + RESTRICTED_FIELD_TOOLTIP, +} from 'src/features/Account/constants'; describe('User Profile', () => { /* @@ -224,9 +227,7 @@ describe('User Profile', () => { .should('be.visible') .trigger('mouseover'); // Click the button first, then confirm the tooltip is shown. - ui.tooltip - .findByText('This account type cannot update this field.') - .should('be.visible'); + ui.tooltip.findByText(RESTRICTED_FIELD_TOOLTIP).should('be.visible'); }); cy.get('[data-qa-textfield-label="Username"]') @@ -252,9 +253,7 @@ describe('User Profile', () => { .should('be.visible') .trigger('mouseover'); // Click the button first, then confirm the tooltip is shown. - ui.tooltip - .findByText('This account type cannot update this field.') - .should('be.visible'); + ui.tooltip.findByText(RESTRICTED_FIELD_TOOLTIP).should('be.visible'); }); cy.get('[data-qa-textfield-label="Email"]') diff --git a/packages/manager/src/MainContent.tsx b/packages/manager/src/MainContent.tsx index 2d162b3bc5f..0d762133050 100644 --- a/packages/manager/src/MainContent.tsx +++ b/packages/manager/src/MainContent.tsx @@ -195,7 +195,6 @@ export const MainContent = () => { const SwitchAccountSessionProvider = switchAccountSessionContext.Provider; const switchAccountSessionContextValue = useDialogContext({ - inChildAccount: false, isOpen: false, }); diff --git a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx index 96d8cfbb6b3..c5171008ab3 100644 --- a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx +++ b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx @@ -5,7 +5,7 @@ import { StyledLinkButton } from 'src/components/Button/StyledLinkButton'; import { Drawer } from 'src/components/Drawer'; import { Notice } from 'src/components/Notice/Notice'; import { Typography } from 'src/components/Typography'; -import { PARENT_SESSION_EXPIRED } from 'src/features/Account/constants'; +import { PARENT_USER_SESSION_EXPIRED } from 'src/features/Account/constants'; import { isParentTokenValid, setTokenInLocalStorage, @@ -146,7 +146,7 @@ export const SwitchAccountDrawer = (props: Props) => { if (!isParentTokenValid()) { const expiredTokenError: APIError = { field: 'token', - reason: PARENT_SESSION_EXPIRED, + reason: PARENT_USER_SESSION_EXPIRED, }; setIsParentTokenError([expiredTokenError]); @@ -155,7 +155,10 @@ export const SwitchAccountDrawer = (props: Props) => { } updateCurrentTokenBasedOnUserType({ userType: 'parent' }); + + // Reset flag for proxy user to display success toast once. setStorage('proxy_user', 'false'); + handleClose(); refreshPage(); }, [handleClose, refreshPage]); diff --git a/packages/manager/src/features/Account/constants.ts b/packages/manager/src/features/Account/constants.ts index 2bce29439d9..83651c8a6f4 100644 --- a/packages/manager/src/features/Account/constants.ts +++ b/packages/manager/src/features/Account/constants.ts @@ -16,11 +16,16 @@ export const grantTypeMap = { vpc: 'VPCs', } as const; +export const RESTRICTED_FIELD_TOOLTIP = `This field can't be modified.`; + +// Parent User Messaging export const PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = 'Remove child accounts before closing the account.'; -export const CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact your ${PARENT_USER} to close your account.`; +export const PARENT_USER_SESSION_EXPIRED = `Session expired. Please log in again to your ${PARENT_USER} account.`; + +// Proxy User Messaging +export const PROXY_USER_RESTRICTED_TOOLTIP_TEXT = `You can't perform this action on child accounts.`; export const PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact ${CUSTOMER_SUPPORT} to close this account.`; -export const PARENT_SESSION_EXPIRED = `Session expired. Please log in again to your ${PARENT_USER} account.`; -export const PROXY_RESTRICTED_PAT_TOOLTIP_TEXT = `You can't create access tokens for child accounts. Instead, switch to your account and create the token there.`; -export const RESTRICTED_FIELD_TOOLTIP = - 'This account type cannot update this field.'; + +// Child User Messaging +export const CHILD_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact your ${PARENT_USER} to close your account.`; diff --git a/packages/manager/src/features/Profile/APITokens/APITokenMenu.tsx b/packages/manager/src/features/Profile/APITokens/APITokenMenu.tsx index 4800502e84a..22d31ee925f 100644 --- a/packages/manager/src/features/Profile/APITokens/APITokenMenu.tsx +++ b/packages/manager/src/features/Profile/APITokens/APITokenMenu.tsx @@ -5,6 +5,7 @@ import * as React from 'react'; import { Action, ActionMenu } from 'src/components/ActionMenu/ActionMenu'; import { InlineMenuAction } from 'src/components/InlineMenuAction/InlineMenuAction'; +import { PROXY_USER_RESTRICTED_TOOLTIP_TEXT } from 'src/features/Account/constants'; interface Props { isProxyUser: boolean; @@ -44,7 +45,7 @@ export const APITokenMenu = (props: Props) => { openEditDrawer(token); }, title: 'Rename', - tooltip: 'Only company users can edit API tokens.', + tooltip: PROXY_USER_RESTRICTED_TOOLTIP_TEXT, } : null, { diff --git a/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx b/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx index 58e1615d570..585463666f9 100644 --- a/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx +++ b/packages/manager/src/features/Profile/APITokens/APITokenTable.tsx @@ -17,7 +17,7 @@ import { TableRowLoading } from 'src/components/TableRowLoading/TableRowLoading' import { StyledTableSortCell } from 'src/components/TableSortCell/StyledTableSortCell'; import { TableSortCell } from 'src/components/TableSortCell/TableSortCell'; import { Typography } from 'src/components/Typography'; -import { PROXY_RESTRICTED_PAT_TOOLTIP_TEXT } from 'src/features/Account/constants'; +import { PROXY_USER_RESTRICTED_TOOLTIP_TEXT } from 'src/features/Account/constants'; import { SecretTokenDialog } from 'src/features/Profile/SecretTokenDialog/SecretTokenDialog'; import { useFlags } from 'src/hooks/useFlags'; import { useOrder } from 'src/hooks/useOrder'; @@ -208,7 +208,7 @@ export const APITokenTable = (props: Props) => { {type === 'Personal Access Token' && ( <Button tooltipText={ - isProxyUser ? PROXY_RESTRICTED_PAT_TOOLTIP_TEXT : undefined + isProxyUser ? PROXY_USER_RESTRICTED_TOOLTIP_TEXT : undefined } buttonType="primary" disabled={isProxyUser} diff --git a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx index 2adb6aa411b..ad6f5101565 100644 --- a/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx +++ b/packages/manager/src/features/TopMenu/UserMenu/UserMenu.tsx @@ -121,6 +121,7 @@ export const UserMenu = React.memo(() => { React.useEffect(() => { // Run after we've switched to a proxy user. if (isProxyUser && !getStorage('proxy_user')) { + // Flag for proxy user to display success toast once. setStorage('proxy_user', 'true'); enqueueSnackbar(`Account switched to ${companyNameOrEmail}.`, { From d0bd01b0856516728da2dc8d7390038759415035 Mon Sep 17 00:00:00 2001 From: Jaalah Ramos <jaalah.ramos@gmail.com> Date: Tue, 12 Mar 2024 10:56:06 -0400 Subject: [PATCH 4/4] Update to smart quote --- packages/manager/src/features/Account/constants.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/features/Account/constants.ts b/packages/manager/src/features/Account/constants.ts index 83651c8a6f4..af930f03f0d 100644 --- a/packages/manager/src/features/Account/constants.ts +++ b/packages/manager/src/features/Account/constants.ts @@ -16,7 +16,7 @@ export const grantTypeMap = { vpc: 'VPCs', } as const; -export const RESTRICTED_FIELD_TOOLTIP = `This field can't be modified.`; +export const RESTRICTED_FIELD_TOOLTIP = 'This field can\u{2019}t be modified.'; // Parent User Messaging export const PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = @@ -24,7 +24,8 @@ export const PARENT_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = export const PARENT_USER_SESSION_EXPIRED = `Session expired. Please log in again to your ${PARENT_USER} account.`; // Proxy User Messaging -export const PROXY_USER_RESTRICTED_TOOLTIP_TEXT = `You can't perform this action on child accounts.`; +export const PROXY_USER_RESTRICTED_TOOLTIP_TEXT = + 'You can\u{2019}t perform this action on child accounts.'; export const PROXY_USER_CLOSE_ACCOUNT_TOOLTIP_TEXT = `Contact ${CUSTOMER_SUPPORT} to close this account.`; // Child User Messaging