Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@
"name": "Development server",
"request": "launch",
"type": "node-terminal"
},
{
"type": "node",
"request": "launch",
"name": "Test Spec File",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": [
"--collectCoverage=false",
"--colors",
"--config",
"${workspaceRoot}/jest.config.ts",
"--runInBand"
],
"internalConsoleOptions": "neverOpen",
"sourceMaps": true,
"skipFiles": [
"${workspaceRoot}/../../node_modules/**/*"
],
"windows": {
"skipFiles": ["C:\\\\**\\\\node_modules\\\\**\\\\*"]
},
"stopOnEntry": true
}
]
}
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default [
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/consistent-type-assertions': 'error',
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/consistent-type-definitions': 'off',
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious on the "why" behind this eslint config change

'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/indent': 'off',
Expand Down
10 changes: 0 additions & 10 deletions src/components/Breadcrumbs.astro

This file was deleted.

14 changes: 0 additions & 14 deletions src/components/KebabDropdownItems.astro

This file was deleted.

15 changes: 0 additions & 15 deletions src/components/KebabDropdownItems.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/Toolbar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
import { Toolbar as ReactToolbar } from './Toolbar.tsx'
---

<ReactToolbar client:idle />
<ReactToolbar client:idle />
167 changes: 20 additions & 147 deletions src/components/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,18 @@
import * as React from 'react'
import { useState } from 'react'
import {
Avatar,
Button,
ButtonVariant,
Divider,
Dropdown,
DropdownGroup,
DropdownList,
MenuToggle,
type MenuToggleElement,
Toolbar as PFToolbar,
ToolbarContent,
ToolbarGroup,
ToolbarItem,
} from '@patternfly/react-core'
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'
import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'

import imgAvatar from '/avatarImg.svg?url'
import { ToggleThemeSwitcher } from './toolbar/ToogleThemeSwitcher'
import { SearchComponent } from './toolbar/SearchComponent'
import { DocumentReleaseDropdown } from './toolbar/DocumentReleaseDropdown';
import GithubIcon from '@patternfly/react-icons/dist/esm/icons/github-icon';

import { KebabDropdownItems } from './KebabDropdownItems'
import { UserDropdownItems } from './UserDropdownItems'

export const Toolbar: React.FunctionComponent = () => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
const [isKebabDropdownOpen, setIsKebabDropdownOpen] = useState(false)
const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = useState(false)

const onDropdownToggle = () => {
setIsDropdownOpen(!isDropdownOpen)
}

const onDropdownSelect = () => {
setIsDropdownOpen(false)
}

const onKebabDropdownToggle = () => {
setIsKebabDropdownOpen(!isKebabDropdownOpen)
}

const onKebabDropdownSelect = () => {
setIsKebabDropdownOpen(false)
}

const onFullKebabDropdownToggle = () => {
setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen)
}

const onFullKebabDropdownSelect = () => {
setIsFullKebabDropdownOpen(false)
}

return (
export const Toolbar: React.FunctionComponent = () => (
<PFToolbar id="toolbar" isStatic>
<ToolbarContent>
<ToolbarGroup
Expand All @@ -63,111 +21,26 @@ export const Toolbar: React.FunctionComponent = () => {
gap={{ default: 'gapNone', md: 'gapMd' }}
>
<ToolbarItem>
<Button
aria-label="Notifications"
variant={ButtonVariant.plain}
icon={<BellIcon />}
/>
<ToggleThemeSwitcher/>
</ToolbarItem>
<ToolbarGroup
variant="action-group-plain"
visibility={{ default: 'hidden', lg: 'visible' }}
>
<ToolbarItem>
<Button
aria-label="Settings"
variant={ButtonVariant.plain}
icon={<CogIcon />}
/>
</ToolbarItem>
<ToolbarItem>
<Button
aria-label="Help"
variant={ButtonVariant.plain}
icon={<QuestionCircleIcon />}
/>
</ToolbarItem>
</ToolbarGroup>
<ToolbarItem
visibility={{ default: 'hidden', md: 'visible', lg: 'hidden' }}
>
<Dropdown
isOpen={isKebabDropdownOpen}
onSelect={onKebabDropdownSelect}
onOpenChange={(isOpen: boolean) => setIsKebabDropdownOpen(isOpen)}
popperProps={{ position: 'right' }}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
onClick={onKebabDropdownToggle}
isExpanded={isKebabDropdownOpen}
variant="plain"
aria-label="Settings and help"
>
<EllipsisVIcon aria-hidden="true" />
</MenuToggle>
)}
>
<DropdownList>
<KebabDropdownItems />
</DropdownList>
</Dropdown>
<ToolbarItem>
<SearchComponent/>
</ToolbarItem>
<ToolbarItem visibility={{ md: 'hidden' }}>
<Dropdown
isOpen={isFullKebabDropdownOpen}
onSelect={onFullKebabDropdownSelect}
onOpenChange={(isOpen: boolean) =>
setIsFullKebabDropdownOpen(isOpen)
}
popperProps={{ position: 'right' }}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
onClick={onFullKebabDropdownToggle}
isExpanded={isFullKebabDropdownOpen}
variant="plain"
aria-label="Toolbar menu"
>
<EllipsisVIcon aria-hidden="true" />
</MenuToggle>
)}
<ToolbarItem>
<Button
component="a"
variant="plain"
href="//github.com/patternfly"
target="top"
aria-label="PatternFly GitHub page"
>
<DropdownGroup key="group 2" aria-label="User actions">
<DropdownList>
<UserDropdownItems />
</DropdownList>
</DropdownGroup>
<Divider />
<DropdownList>
<KebabDropdownItems />
</DropdownList>
</Dropdown>
<GithubIcon />
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think the icon should be passed to an icon prop rather than as a child

</Button>
</ToolbarItem>
<ToolbarItem>
<DocumentReleaseDropdown/>
</ToolbarItem>
</ToolbarGroup>
<ToolbarItem visibility={{ default: 'hidden', md: 'visible' }}>
<Dropdown
isOpen={isDropdownOpen}
onSelect={onDropdownSelect}
onOpenChange={(isOpen: boolean) => setIsDropdownOpen(isOpen)}
popperProps={{ position: 'right' }}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
onClick={onDropdownToggle}
isExpanded={isDropdownOpen}
icon={<Avatar src={imgAvatar} alt="" size="sm" />}
>
Ned Username
</MenuToggle>
)}
>
<DropdownList>
<UserDropdownItems />
</DropdownList>
</Dropdown>
</ToolbarItem>
</ToolbarContent>
</PFToolbar>
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add tests for the Toolbar component itself?

}
9 changes: 0 additions & 9 deletions src/components/UserDropdownItems.astro

This file was deleted.

10 changes: 0 additions & 10 deletions src/components/UserDropdownItems.tsx

This file was deleted.

72 changes: 72 additions & 0 deletions src/components/toolbar/DocumentReleaseDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react'
import {
Dropdown,
DropdownList,
MenuToggle,
DropdownGroup,
DropdownItem,
Divider,
} from '@patternfly/react-core'
import { Release } from '../../types'
import versions from '../../versions.json'

export const DocumentReleaseDropdown: React.FunctionComponent = () => {
const latestRelease = versions.Releases.find(
(release) => release.latest,
) as Release
const previousReleases = Object.values(versions.Releases).filter(
(release) => !release.hidden && !release.latest,
) as Release []

const previousVersions = Object.values(versions.ArchivedReleases) as Release[];
Comment on lines +14 to +21
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: is there a way we could avoid all these type casts?


const [isDropdownOpen, setDropdownOpen] = React.useState(false)

const getDropdownItem = (version: Release, isLatest = false) => (
<DropdownItem
itemId={`${version.name}-latest-release`}
key={`${version.name}-latest`}
// eslint-disable-next-line no-nested-ternary
to={isLatest ? '/' : version.href ? version.href : `/${version.name}`}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I don't love this nested ternary either

isExternalLink = {version.href ? true : false}
>
{`Release ${version.name}`}
</DropdownItem>
)
return (
<Dropdown
onSelect={() => setDropdownOpen(!isDropdownOpen)}
onOpenChange={(isOpen) => setDropdownOpen(isOpen)}
isOpen={isDropdownOpen}
toggle={(toggleRef) => (
<MenuToggle
ref={toggleRef}
onClick={() => setDropdownOpen(!isDropdownOpen)}
isExpanded={isDropdownOpen}
>
{`Release ${latestRelease.name}`}
</MenuToggle>
)}
popperProps={{ position: 'right' }}
>
<DropdownGroup key="Latest" label="Latest">
<DropdownList>{getDropdownItem(latestRelease, true)}</DropdownList>
</DropdownGroup>
{previousReleases.length > 0 && (
<DropdownGroup key="Previous releases" label="Previous releases">
<DropdownList>
{previousReleases
.slice(0, 3)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: is this slice just a magic number sort of thing where we're grabbing the last three versions just because 3, 4 and 5 are the only previous versions we care about? If so I don't love that.

.map((version) => getDropdownItem(version))}
</DropdownList>
</DropdownGroup>
)}
{previousVersions.length > 0 && (
<><Divider key="divider1" /><DropdownGroup key="Previous versions" label="Previous versions">
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: the formatting is kind of funky here, seems like prettier just needs to be ran.

<DropdownList>
{previousVersions.map((version) => getDropdownItem(version))}
</DropdownList>
</DropdownGroup></>)}
</Dropdown>
)
}
Loading