Skip to content

Commit

Permalink
web: add starred resource bar to storybook (#4398)
Browse files Browse the repository at this point in the history
  • Loading branch information
landism committed Apr 7, 2021
1 parent 6d9f76b commit a6b0e1b
Show file tree
Hide file tree
Showing 8 changed files with 367 additions and 41 deletions.
18 changes: 18 additions & 0 deletions web/src/ResourceStatus.ts
@@ -0,0 +1,18 @@
import { ResourceStatus } from "./types"

export function ClassNameFromResourceStatus(rs: ResourceStatus): string {
switch (rs) {
case ResourceStatus.Building:
return "isBuilding"
case ResourceStatus.Pending:
return "isPending"
case ResourceStatus.Warning:
return "isWarning"
case ResourceStatus.Healthy:
return "isHealthy"
case ResourceStatus.Unhealthy:
return "isUnhealthy"
case ResourceStatus.None:
return "isNone"
}
}
55 changes: 15 additions & 40 deletions web/src/SidebarIcon.tsx
@@ -1,13 +1,15 @@
import React, { PureComponent } from "react"
import styled, { keyframes } from "styled-components"
import styled from "styled-components"
import { ReactComponent as CheckmarkSmallSvg } from "./assets/svg/checkmark-small.svg"
import { ReactComponent as ErrorSvg } from "./assets/svg/error.svg"
import { ReactComponent as WarningSvg } from "./assets/svg/warning.svg"
import { ClassNameFromResourceStatus } from "./ResourceStatus"
import {
AnimDuration,
Color,
ColorAlpha,
ColorRGBA,
Glow,
Width,
} from "./style-helpers"
import Tooltip from "./Tooltip"
Expand All @@ -26,24 +28,6 @@ export enum IconType {
StatusBuilding = "building",
}

let glowWhite = keyframes`
0% {
background-color: ${ColorRGBA(Color.white, ColorAlpha.translucent)};
}
50% {
background-color: ${ColorRGBA(Color.white, ColorAlpha.almostTransparent)};
}
`

let glowDark = keyframes`
0% {
background-color: ${ColorRGBA(Color.gray, ColorAlpha.translucent)};
}
50% {
background-color: ${ColorRGBA(Color.gray, ColorAlpha.almostTransparent)};
}
`

let SidebarIconRoot = styled.div`
display: flex;
flex-shrink: 0;
Expand Down Expand Up @@ -71,11 +55,11 @@ let SidebarIconRoot = styled.div`
}
&.isPending {
background-color: ${ColorRGBA(Color.white, ColorAlpha.translucent)};
animation: ${glowWhite} 2s linear infinite;
animation: ${Glow.white} 2s linear infinite;
}
.isSelected &.isPending {
background-color: ${ColorRGBA(Color.gray, ColorAlpha.translucent)};
animation: ${glowDark} 2s linear infinite;
animation: ${Glow.dark} 2s linear infinite;
}
&.isNone {
border-right: 1px solid ${Color.grayLighter};
Expand Down Expand Up @@ -108,30 +92,21 @@ export default class SidebarIcon extends PureComponent<SidebarIconProps> {

if (!this.props.tooltipText) {
return (
<SidebarIconRoot className={`${this.status()}`}>{icon}</SidebarIconRoot>
<SidebarIconRoot
className={`${ClassNameFromResourceStatus(this.props.status)}`}
>
{icon}
</SidebarIconRoot>
)
}
return (
<Tooltip title={this.props.tooltipText}>
<SidebarIconRoot className={`${this.status()}`}>{icon}</SidebarIconRoot>
<SidebarIconRoot
className={`${ClassNameFromResourceStatus(this.props.status)}`}
>
{icon}
</SidebarIconRoot>
</Tooltip>
)
}

status() {
switch (this.props.status) {
case ResourceStatus.Building:
return "isBuilding"
case ResourceStatus.Pending:
return "isPending"
case ResourceStatus.Warning:
return "isWarning"
case ResourceStatus.Healthy:
return "isHealthy"
case ResourceStatus.Unhealthy:
return "isUnhealthy"
case ResourceStatus.None:
return "isNone"
}
}
}
61 changes: 61 additions & 0 deletions web/src/StarredResourceBar.stories.tsx
@@ -0,0 +1,61 @@
import React from "react"
import StarredResourceBar, { ResourceNameAndStatus } from "./StarredResourceBar"
import { Color } from "./style-helpers"
import { ResourceStatus } from "./types"

export default {
title: "New UI/Shared/StarredResourceBar",
decorators: [
// make the pane bg black so that the menu bg stands out
(Story: any) => (
<div style={{ backgroundColor: Color.black, height: "300px" }}>
<Story />
</div>
),
],
}

function story(resources: ResourceNameAndStatus[], selectedResource?: string) {
return (
<StarredResourceBar
resources={resources}
unstar={(n) => {}}
selectedResource={selectedResource}
/>
)
}

export const OneItem = () =>
story([{ name: "foo", status: ResourceStatus.Healthy }])

export const ThreeItems = () =>
story(Array(3).fill(["foo", ResourceStatus.Healthy]))

export const TwentyItems = () =>
story(Array(20).fill(["foobar", ResourceStatus.Healthy]))

export const LongName = () =>
story([
{
name: "supercalifragilisticexpialidocious",
status: ResourceStatus.Unhealthy,
},
])

export const MixedNames = () =>
story(
[
{ name: "max-object-detected-name", status: ResourceStatus.Healthy },
{ name: "muxer", status: ResourceStatus.Unhealthy },
{ name: "benchmark-muxer", status: ResourceStatus.Healthy },
{ name: "benchmark-all", status: ResourceStatus.Healthy },
{ name: "recompile-storage", status: ResourceStatus.Unhealthy },
{ name: "benchamrk-rectangle-test", status: ResourceStatus.Healthy },
{ name: "benchmark-storage", status: ResourceStatus.Healthy },
{ name: "(Tiltfile)", status: ResourceStatus.Pending },
{ name: "recompile-rectangle-test", status: ResourceStatus.Unhealthy },
{ name: "SillyOne test", status: ResourceStatus.Unhealthy },
{ name: "AttackOfTheSilly test", status: ResourceStatus.Unhealthy },
],
"benchmark-muxer"
)
68 changes: 68 additions & 0 deletions web/src/StarredResourceBar.test.tsx
@@ -0,0 +1,68 @@
import { mount, ReactWrapper } from "enzyme"
import React from "react"
import { MemoryRouter } from "react-router"
import PathBuilder from "./PathBuilder"
import StarredResourceBar, {
StarButton,
StarredResource,
StarredResourceLabel,
} from "./StarredResourceBar"
import { ResourceStatus } from "./types"

const pathBuilder = PathBuilder.forTesting("localhost", "/")

function getStarredItemNames(
root: ReactWrapper<any, React.Component["state"], React.Component>
): Array<string> {
let starredItems = root.find(StarredResourceLabel)
return starredItems.map((i) => i.text())
}

function clickStar(
root: ReactWrapper<any, React.Component["state"], React.Component>,
name: string
) {
const r = root
.find(StarredResource)
.find({ resource: { name: name } })
.find(StarButton)
expect(r.length).toEqual(1)
r.at(0).simulate("click")
}

it("renders the starred items", () => {
const resources = [
{ name: "foo", status: ResourceStatus.Healthy },
{ name: "bar", status: ResourceStatus.Unhealthy },
]

const root = mount(
<MemoryRouter>
<StarredResourceBar resources={resources} unstar={() => {}} />
</MemoryRouter>
)

expect(getStarredItemNames(root)).toEqual(["foo", "bar"])
})

it("calls unstar", () => {
const resources = [
{ name: "foo", status: ResourceStatus.Healthy },
{ name: "bar", status: ResourceStatus.Unhealthy },
]

let unstars: string[] = []
let onClick = (resourceName: string) => {
unstars.push(resourceName)
}

const root = mount(
<MemoryRouter>
<StarredResourceBar resources={resources} unstar={onClick} />
</MemoryRouter>
)

clickStar(root, "foo")

expect(unstars).toEqual(["foo"])
})

0 comments on commit a6b0e1b

Please sign in to comment.