Skip to content

Commit

Permalink
Install page enhacement: version dropdown moved to PageHeader (#2217)
Browse files Browse the repository at this point in the history
* Updated styling for version switcher; removed dead code

* Removed description from PageHeader component; moved version switcher to that component; updated styling; typed change event for VersionContextSwitcher
  • Loading branch information
heatlikeheatwave committed Nov 7, 2023
1 parent 8191789 commit d99b1de
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 110 deletions.
45 changes: 5 additions & 40 deletions src/components/version-context-switcher/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
*/

import { ChangeEventHandler, ReactElement, useState } from 'react'
import { IconCaret16 } from '@hashicorp/flight-icons/svg-react/caret-16'
import { IconChevronDown16 } from '@hashicorp/flight-icons/svg-react/chevron-down-16'
import { useCurrentProduct } from 'contexts'
import ProductIcon from 'components/product-icon'
import { ContextSwitcherOption, VersionContextSwitcherProps } from './types'
import s from './version-context-switcher.module.css'

Expand All @@ -26,25 +25,8 @@ const VersionContextSwitcher = ({
options,
}: VersionContextSwitcherProps): ReactElement => {
const currentProduct = useCurrentProduct()
let latestVersion = options[0].value
/** Update `latestVersion` to the latest version of the product
* that has been released if it can be determined. This is needed
* because not all products have `latest` listed as the first item
* in the sorted array. E.g. `vault-enterprise` lists `+ent.hsm.fips1402`
* variants first.
*/
for (let i = 0; i < options.length; i++) {
const versionLabel = options[i].label
const versionValue = options[i].value
if (versionLabel.indexOf('(latest)') >= 0) {
latestVersion = versionValue
break
}
}

const [selectedVersion, setSelectedVersion] = useState<
ContextSwitcherOption['value']
>(initialValue || latestVersion)
const [selectedVersion, setSelectedVersion] =
useState<ContextSwitcherOption['value']>(initialValue)

/**
* Handle change event for switcher, invoking the `onChange` function last if
Expand All @@ -58,30 +40,15 @@ const VersionContextSwitcher = ({
}
}

/**
* TODO: hopefully this is temporary. Because Sentinel does not have a
* `ProductIcon` and the component intentionally returns `null` for if the
* value for the `product` prop is `'sentinel'`, opting to pass a different
* value for Sentinel here rather than affect all current references to
* ProductIcon.
* - `ProductSwitcher` is one example that would be imacted by adding a
* ProductIcon for Sentinel. We currently do not want to render an icon
* for Sentinel in `ProductSwitcher`.
*/
const productIconSlug =
currentProduct.slug === 'sentinel' ? 'hcp' : currentProduct.slug
return (
<div className={s.root}>
<span className={s.productIcon}>
<ProductIcon productSlug={productIconSlug} />
</span>
<select
aria-label="Choose a different version to install"
className={s.select}
onChange={handleChange}
value={selectedVersion}
>
{options.map((option) => (
{options.map((option: HTMLOptionElement) => (
<option
aria-label={`${currentProduct.name} ${option.label}`}
className={s.option}
Expand All @@ -92,9 +59,7 @@ const VersionContextSwitcher = ({
</option>
))}
</select>
<span className={s.trailingIcon}>
<IconCaret16 />
</span>
<IconChevronDown16 className={s.trailingIcon} />
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,15 @@

.root {
position: relative;
max-width: max-content;
width: 100%;
}

.productIcon,
.trailingIcon {
align-items: center;
bottom: 0;
display: flex;
pointer-events: none;
position: absolute;
top: 0;
}

.productIcon {
left: 12px;
}

.trailingIcon {
color: var(--token-color-palette-neutral-600);
right: 12px;
position: absolute;
right: 8px;
top: 10px;
}

.select {
Expand All @@ -38,10 +27,7 @@
border-radius: 5px;
border: none;
cursor: pointer;
padding-bottom: 8px;
padding-left: 34px;
padding-right: 40px;
padding-top: 8px;
padding: 10px 30px 10px 10px;
width: 100%;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@
padding-bottom: 12px;
}

.versionSwitcherWrapper {
/* Flex-grow to fill space when in separate row */
flex-grow: 1;
width: max-content;
}

.operatingSystemTitle {
color: var(--token-color-foreground-strong);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import InlineLink from 'components/inline-link'
import MobileStandaloneLink from 'components/mobile-standalone-link'
import Tabs, { Tab } from 'components/tabs'
import Text from 'components/text'
import VersionContextSwitcher from 'components/version-context-switcher'

// Local imports
import { DownloadsSectionProps } from './types'
Expand Down Expand Up @@ -255,9 +254,8 @@ const DownloadsSection = ({
isEnterpriseMode = false,
packageManagers,
selectedRelease,
versionSwitcherOptions,
}: DownloadsSectionProps): ReactElement => {
const { isLatestVersion, setCurrentVersion } = useCurrentVersion()
const { isLatestVersion } = useCurrentVersion()
const downloadsByOS = useMemo(
() => groupDownloadsByOS(selectedRelease),
[selectedRelease]
Expand All @@ -271,12 +269,6 @@ const DownloadsSection = ({
<div className={s.root}>
<Card elevation="base">
<div className={s.cardHeader}>
<div className={s.versionSwitcherWrapper}>
<VersionContextSwitcher
onChange={(e) => setCurrentVersion(e.target.value)}
options={versionSwitcherOptions}
/>
</div>
<Heading
className={s.operatingSystemTitle}
level={2}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
* SPDX-License-Identifier: MPL-2.0
*/

import { VersionContextSwitcherProps } from 'components/version-context-switcher'
import { ReleaseVersion } from 'lib/fetch-release-data'
import { PackageManager } from 'views/product-downloads-view/types'

export interface DownloadsSectionProps {
isEnterpriseMode: boolean
packageManagers: PackageManager[]
selectedRelease: ReleaseVersion
versionSwitcherOptions: VersionContextSwitcherProps['options']
}
34 changes: 16 additions & 18 deletions src/views/product-downloads-view/components/page-header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,41 @@
* SPDX-License-Identifier: MPL-2.0
*/

import { ReactElement } from 'react'
import Heading from 'components/heading'
import IconTileLogo from 'components/icon-tile-logo'
import Text from 'components/text'
import VersionContextSwitcher, {
VersionContextSwitcherProps,
} from 'components/version-context-switcher'
import { ChangeEvent, ReactElement } from 'react'
import { ProductSlug } from 'types/products'
import { useCurrentVersion } from 'views/product-downloads-view/contexts'
import { getPageSubtitle } from 'views/product-downloads-view/helpers'
import s from './page-header.module.css'
import { ProductSlug } from 'types/products'

interface PageHeaderProps {
isEnterpriseMode: boolean
product: { name: string; slug: ProductSlug }
versionSwitcherOptions: VersionContextSwitcherProps['options']
}

const PageHeader = ({
isEnterpriseMode = false,
product,
versionSwitcherOptions,
}: PageHeaderProps): ReactElement => {
const { currentVersion, isLatestVersion } = useCurrentVersion()
const { setCurrentVersion } = useCurrentVersion()

const pageTitle = isEnterpriseMode
? `${product.name} Enterprise Installation`
: `Install ${product.name}`

const pageSubtitle = isEnterpriseMode
? ''
: getPageSubtitle({
productName: product.name,
version: currentVersion,
isLatestVersion,
})

const productSlug = (
product.slug === 'sentinel' ? 'hcp' : product.slug
) as Exclude<ProductSlug, 'sentinel'>

return (
<div className={s.root}>
<IconTileLogo className={s.iconTileLogo} productSlug={productSlug} />
<div>
<div className={s.headingWrapper}>
<IconTileLogo className={s.iconTileLogo} productSlug={productSlug} />
<Heading
className={s.pageHeaderTitle}
level={1}
Expand All @@ -52,10 +47,13 @@ const PageHeader = ({
>
{pageTitle}
</Heading>
<Text className={s.pageHeaderSubtitle} size={300} weight="regular">
{pageSubtitle}
</Text>
</div>
<VersionContextSwitcher
onChange={(e: ChangeEvent<HTMLSelectElement>) =>
setCurrentVersion(e.target.value)
}
options={versionSwitcherOptions}
/>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.root {
align-items: center;
display: flex;
justify-content: space-between;
margin-bottom: 48px;
}

Expand All @@ -20,10 +21,15 @@

.pageHeaderTitle {
color: var(--token-color-foreground-strong);
margin-bottom: 12px;
margin-top: 0;
margin: 0;
}

.pageHeaderSubtitle {
color: var(--token-color-foreground-primary);
}

.headingWrapper {
align-items: center;
display: flex;
justify-content: center;
}
13 changes: 0 additions & 13 deletions src/views/product-downloads-view/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,6 @@ export function generateEnterprisePackageManagers(
]
}

export const getPageSubtitle = ({
productName,
version,
isLatestVersion,
}: {
productName: string
version: string
isLatestVersion: boolean
}): string => {
const versionText = `v${version}${isLatestVersion ? ' (latest version)' : ''}`
return `Install or update to ${versionText} of ${productName} to get started.`
}

export const initializeBreadcrumbLinks = (
currentProduct: Pick<ProductData, 'name' | 'slug'>,
isEnterpriseMode: boolean,
Expand Down
2 changes: 1 addition & 1 deletion src/views/product-downloads-view/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ const ProductDownloadsViewContent = ({
name: installName || currentProduct.name,
slug: currentProduct.slug,
}}
versionSwitcherOptions={versionSwitcherOptions}
/>
{merchandisingSlot?.position === 'above' ? merchandisingSlot.slot : null}
<DownloadsSection
isEnterpriseMode={isEnterpriseMode}
packageManagers={packageManagers}
selectedRelease={releases.versions[currentVersion]}
versionSwitcherOptions={versionSwitcherOptions}
/>
{merchandisingSlot?.position === 'below' ? merchandisingSlot.slot : null}
<OfficialReleasesSection />
Expand Down

1 comment on commit d99b1de

@vercel
Copy link

@vercel vercel bot commented on d99b1de Nov 7, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.