diff --git a/.changeset/forty-tables-yawn.md b/.changeset/forty-tables-yawn.md new file mode 100644 index 0000000000..c141d47e10 --- /dev/null +++ b/.changeset/forty-tables-yawn.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/mongo-nav': minor +--- + +Adds project status badge to ProjectNav diff --git a/.changeset/nervous-eyes-shake.md b/.changeset/nervous-eyes-shake.md new file mode 100644 index 0000000000..49d615b45d --- /dev/null +++ b/.changeset/nervous-eyes-shake.md @@ -0,0 +1,5 @@ +--- +'@leafygreen-ui/menu': patch +--- + +Fixes SubMenuIcon padding to account for change in size of xlarge glyphs diff --git a/packages/menu/src/styles.tsx b/packages/menu/src/styles.tsx index 8f1815c6d3..6b87d3fd41 100644 --- a/packages/menu/src/styles.tsx +++ b/packages/menu/src/styles.tsx @@ -3,9 +3,9 @@ import { uiColors } from '@leafygreen-ui/palette'; const indentation = 15; const leftBar = 5; -export const svgWidth = 32; +export const svgWidth = 24; export const menuItemPadding = 15; -export const paddingLeft = 60; +export const paddingLeft = 52; export const menuItemContainerStyle = css` display: flex; diff --git a/packages/mongo-nav/src/MongoNav.tsx b/packages/mongo-nav/src/MongoNav.tsx index 5603a5bcf5..2eee4f912f 100644 --- a/packages/mongo-nav/src/MongoNav.tsx +++ b/packages/mongo-nav/src/MongoNav.tsx @@ -251,6 +251,7 @@ function MongoNav({ mode={mode} activeProduct={activeProduct} activeNav={activeNav} + admin={admin} current={data?.currentProject} data={filteredProjects} constructProjectURL={constructProjectURL} diff --git a/packages/mongo-nav/src/data.ts b/packages/mongo-nav/src/data.ts index bc38601c56..b1215601c6 100644 --- a/packages/mongo-nav/src/data.ts +++ b/packages/mongo-nav/src/data.ts @@ -21,6 +21,7 @@ export const dataFixtures = { planType: 'atlas', projectId: '020019e', projectName: 'Test Project', + status: 'ACTIVE', }, organizations: [ { diff --git a/packages/mongo-nav/src/helpers/Icons.tsx b/packages/mongo-nav/src/helpers/Icons.tsx index d97626f65f..3de1e7d4a9 100644 --- a/packages/mongo-nav/src/helpers/Icons.tsx +++ b/packages/mongo-nav/src/helpers/Icons.tsx @@ -213,22 +213,12 @@ export function ChartsInactive(props: HTMLElementProps<'svg'>) { export function CloudIcon(props: HTMLElementProps<'svg'>) { return ( - - - - - - - - - + + + ); @@ -259,20 +249,10 @@ export function SupportIcon(props: HTMLElementProps<'svg'>) { export function UniversityIcon(props: HTMLElementProps<'svg'>) { return ( - - - - - - - + + + + @@ -281,34 +261,16 @@ export function UniversityIcon(props: HTMLElementProps<'svg'>) { export function MegaphoneIcon(props: HTMLElementProps<'svg'>) { return ( - + - - - - - - - - + + diff --git a/packages/mongo-nav/src/helpers/ProjectStatusBadge.tsx b/packages/mongo-nav/src/helpers/ProjectStatusBadge.tsx new file mode 100644 index 0000000000..aae2cbb800 --- /dev/null +++ b/packages/mongo-nav/src/helpers/ProjectStatusBadge.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import Badge, { Variant } from '@leafygreen-ui/badge'; +import { css } from '@leafygreen-ui/emotion'; +import { ProjectStatus } from '../types'; + +const projectStatusBadgeMargin = css` + margin-right: 20px; +`; + +const projectStatusBadgeVariant = { + [ProjectStatus.Active]: Variant.Green, + [ProjectStatus.Closing]: Variant.Yellow, + [ProjectStatus.Closed]: Variant.Red, + [ProjectStatus.Dead]: Variant.Red, +}; + +interface ProjectStatusBadgeProps { + currentStatus: ProjectStatus; +} + +export default function ProjectStatusBadge({ + currentStatus, +}: ProjectStatusBadgeProps) { + return ( + + {currentStatus} + + ); +} diff --git a/packages/mongo-nav/src/helpers/index.ts b/packages/mongo-nav/src/helpers/index.ts index 9ed1780eb6..988b500557 100644 --- a/packages/mongo-nav/src/helpers/index.ts +++ b/packages/mongo-nav/src/helpers/index.ts @@ -1,4 +1,5 @@ -import OrgNavLink from './OrgNavLink'; -import InteractionRingWrapper from './InteractionRingWrapper'; -import OnPremUserMenu from './OnPremUserMenu'; -export { OrgNavLink, InteractionRingWrapper, OnPremUserMenu }; +export { default as OrgNavLink } from './OrgNavLink'; +export { default as InteractionRingWrapper } from './InteractionRingWrapper'; +export { default as OnPremUserMenu } from './OnPremUserMenu'; +export { default as ProjectStatusBadge } from './ProjectStatusBadge'; +export { RealmIcon, AtlasIcon, ChartsIcon } from './Icons'; diff --git a/packages/mongo-nav/src/org-nav/OrgNav.tsx b/packages/mongo-nav/src/org-nav/OrgNav.tsx index dc60ef0240..a37edf9c11 100644 --- a/packages/mongo-nav/src/org-nav/OrgNav.tsx +++ b/packages/mongo-nav/src/org-nav/OrgNav.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import Tooltip from '@leafygreen-ui/tooltip'; -import Badge from '@leafygreen-ui/badge'; +import Badge, { Variant } from '@leafygreen-ui/badge'; import IconButton from '@leafygreen-ui/icon-button'; import Icon from '@leafygreen-ui/icon'; import UserMenu from '../user-menu'; @@ -78,27 +78,20 @@ const versionStyle = css` })} `; -export const Colors = { - Lightgray: 'lightgray', - Green: 'green', - Yellow: 'yellow', - Red: 'red', -} as const; - -export type Colors = typeof Colors[keyof typeof Colors]; - -const paymentStatusMap: Record> = { - [Colors.Lightgray]: [ +const paymentStatusMap: { + [K in Partial]?: ReadonlyArray; +} = { + [Variant.LightGray]: [ OrgPaymentLabel.Embargoed, OrgPaymentLabel.EmbargoConfirmed, ], - [Colors.Green]: [OrgPaymentLabel.Ok], - [Colors.Yellow]: [ + [Variant.Green]: [OrgPaymentLabel.Ok], + [Variant.Yellow]: [ OrgPaymentLabel.Warning, OrgPaymentLabel.Suspended, OrgPaymentLabel.Closing, ], - [Colors.Red]: [ + [Variant.Red]: [ OrgPaymentLabel.Dead, OrgPaymentLabel.AdminSuspended, OrgPaymentLabel.Locked, @@ -147,13 +140,13 @@ function OrgNav({ const isMobile = viewportWidth < breakpoints.small; const disabled = activeNav === ActiveNavElement.UserSettings; - let paymentVariant: Colors | undefined; - let key: Colors; + let paymentVariant: Variant | undefined; + let key: Variant; for (key in paymentStatusMap) { const paymentStatus = current?.paymentStatus; - if (paymentStatus && paymentStatusMap[key].includes(paymentStatus)) { + if (paymentStatus && paymentStatusMap[key]?.includes(paymentStatus)) { paymentVariant = key; } } diff --git a/packages/mongo-nav/src/project-nav/ProjectNav.spec.tsx b/packages/mongo-nav/src/project-nav/ProjectNav.spec.tsx index 68907da3d8..9c15aa1d0c 100644 --- a/packages/mongo-nav/src/project-nav/ProjectNav.spec.tsx +++ b/packages/mongo-nav/src/project-nav/ProjectNav.spec.tsx @@ -55,6 +55,9 @@ describe('packages/mongo-nav/src/project-nav', () => { const setExpectedElements = () => { const { queryByTestId = () => null } = queries; + expectedElements.projectStatusBadge = queryByTestId( + 'project-nav-project-status-badge', + ); expectedElements.atlas = queryByTestId('project-nav-atlas'); expectedElements.cloudManager = queryByTestId('project-nav-cloud-manager'); expectedElements.realm = queryByTestId('project-nav-realm'); @@ -144,6 +147,21 @@ describe('packages/mongo-nav/src/project-nav', () => { }); }; + const testForProjectStatusBadge = (isVisible: boolean) => { + it(`${ + isVisible ? 'displays' : 'does not display' + } the project status badge in the nav`, () => { + const statusBadge = expectedElements.projectStatusBadge; + + if (isVisible) { + expect(statusBadge).toBeInTheDocument(); + expect((statusBadge as Element).innerHTML).toContain('ACTIVE'); + } else { + expect(statusBadge).not.toBeInTheDocument(); + } + }); + }; + describe('when rendered with default props', () => { beforeEach(async () => { fetchData = []; @@ -158,6 +176,8 @@ describe('packages/mongo-nav/src/project-nav', () => { testForNavLink(linkName, true), ); + testForProjectStatusBadge(false); + it('atlas tab shows the correct link', () => { expect(expectedElements!.atlas!.getAttribute('href')).toEqual( 'https://cloud.mongodb.com/v2/020019e#', @@ -238,6 +258,12 @@ describe('packages/mongo-nav/src/project-nav', () => { }); }); + describe('when admin is set to true', () => { + beforeEach(() => renderComponent({ admin: true, current: currentProject })); + + testForProjectStatusBadge(true); + }); + describe('when the date is before MongoDB World', () => { const testDate = new Date('March 20, 2020 0:00:00'); diff --git a/packages/mongo-nav/src/project-nav/ProjectNav.tsx b/packages/mongo-nav/src/project-nav/ProjectNav.tsx index 29acd8fd6b..feed932688 100644 --- a/packages/mongo-nav/src/project-nav/ProjectNav.tsx +++ b/packages/mongo-nav/src/project-nav/ProjectNav.tsx @@ -23,8 +23,14 @@ import { NavElement, Mode, MongoNavInterface, + ProjectStatus, } from '../types'; -import { AtlasIcon, RealmIcon, ChartsIcon } from '../helpers/Icons'; +import { + AtlasIcon, + RealmIcon, + ChartsIcon, + ProjectStatusBadge, +} from '../helpers'; const { ProjectNavProjectDropdown, @@ -70,7 +76,7 @@ const navContainerStyle = css` const menuIconButtonStyle = css` z-index: 1; ${facepaint({ - marginRight: ['20px', '14px', '20px'], + marginRight: ['16px', '14px', '16px'], })} `; @@ -234,7 +240,7 @@ const secondTabName = displayProductName(); type ProjectNavProps = Pick< MongoNavInterface, - 'activeProduct' | 'activeNav' | 'onProjectChange' | 'mode' + 'activeProduct' | 'activeNav' | 'onProjectChange' | 'admin' | 'mode' > & { current?: CurrentProjectInterface; data?: Array; @@ -248,6 +254,7 @@ type ProjectNavProps = Pick< }; export default function ProjectNav({ + admin, current, data, constructProjectURL, @@ -378,6 +385,13 @@ export default function ProjectNav({ + {!isMobile && + admin && + current?.status && + Object.values(ProjectStatus).includes(current?.status) && ( + + )} +