Skip to content

Commit

Permalink
ui / sidebar: "alerts on top" toggle (tests, styling tk) [ch10933] (#…
Browse files Browse the repository at this point in the history
…4143)

* behavior implemented (needs tests)

* storybook entry for tests with errors

* ugh stupid snapshot tests

* prettier

* web: style resource filters and alerts toggle

* tests: fix failing tests for Sidebar Options

* run prettier

* fix review comments

Co-authored-by: Han Yu <han@tilt.dev>
  • Loading branch information
Maia McCormick and Han Yu committed Feb 2, 2021
1 parent 24ede89 commit c04ecf0
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 212 deletions.
16 changes: 16 additions & 0 deletions web/src/OverviewResourceSidebar.stories.tsx
Expand Up @@ -11,6 +11,7 @@ import {
tiltfileResource,
twoResourceView,
} from "./testdata"
import { UpdateStatus } from "./types"

type Resource = Proto.webviewResource
let pathBuilder = PathBuilder.forTesting("localhost", "/")
Expand Down Expand Up @@ -53,3 +54,18 @@ export function TwoResourcesTwoTests() {
let view = { resources: all, tiltfileKey: "test" }
return <OverviewResourceSidebar name={""} view={view} />
}

export function TestsWithErrors() {
let all: Resource[] = [tiltfileResource()]
for (let i = 0; i < 8; i++) {
let test = oneResourceTest()
test.name = "test_" + i
if (i % 2 === 0) {
test.buildHistory![0].error = "egads!"
test.updateStatus = UpdateStatus.Error
}
all.push(test)
}
let view = { resources: all, tiltfileKey: "test" }
return <OverviewResourceSidebar name={""} view={view} />
}
108 changes: 89 additions & 19 deletions web/src/OverviewSidebarOptions.tsx
@@ -1,42 +1,112 @@
import Checkbox from "@material-ui/core/Checkbox"
import FormControlLabel from "@material-ui/core/FormControlLabel"
import { makeStyles } from "@material-ui/core/styles"
import CheckBoxIcon from "@material-ui/icons/CheckBox"
import CheckBoxOutlineBlankIcon from "@material-ui/icons/CheckBoxOutlineBlank"
import React from "react"
import styled from "styled-components"
import {
Color,
Font,
FontSize,
mixinResetButtonStyle,
mixinResetListStyle,
SizeUnit,
} from "./style-helpers"
import { SidebarOptions } from "./types"

const OverviewSidebarOptionsRoot = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
font-family: ${Font.sansSerif};
font-size: ${FontSize.smallester};
padding-left: ${SizeUnit(0.5)};
padding-right: ${SizeUnit(0.5)};
color: ${Color.offWhite};
`

const FilterOptionList = styled.ul`
${mixinResetListStyle}
display: flex;
user-select: none; // Prevent unsightly highlighting on the label
`

const useStyles = makeStyles({
root: {
color: Color.offWhite,
},
})

const AlertsOnTopToggle = styled.button`
${mixinResetButtonStyle}
color: ${Color.grayLightest};
background-color: ${Color.gray};
padding: ${SizeUnit(0.125)} ${SizeUnit(0.25)};
border-radius: 3px;
font-size: ${FontSize.smallester};
&.is-enabled {
color: ${Color.grayDarkest};
background-color: ${Color.offWhite};
}
`

type OverviewSidebarOptionsProps = {
curState: SidebarOptions
toggleShowResources: () => void
toggleShowTests: () => void
toggleAlertsOnTop: () => void
}

export function OverviewSidebarOptions(
props: OverviewSidebarOptionsProps
): JSX.Element {
const classes = useStyles()

return (
<OverviewSidebarOptionsRoot>
<div>
<input
type="checkbox"
id="resources"
name="resources"
checked={props.curState.showResources}
onChange={(evt) => props.toggleShowResources()}
<OverviewSidebarOptionsRoot
style={{ marginTop: SizeUnit(0.75), marginBottom: SizeUnit(-0.5) }}
>
<FilterOptionList>
<FormControlLabel
control={
<Checkbox
className={classes.root}
color={"default"}
icon={<CheckBoxOutlineBlankIcon fontSize="small" />}
checkedIcon={<CheckBoxIcon fontSize="small" />}
checked={props.curState.showResources}
onChange={(e) => props.toggleShowResources()}
name="resources"
id="resources"
/>
}
label="Resources"
/>
<label htmlFor="resources">Resources</label>
</div>
<div>
<input
type="checkbox"
id="tests"
name="tests"
checked={props.curState.showTests}
onChange={(evt) => props.toggleShowTests()}
<FormControlLabel
control={
<Checkbox
className={classes.root}
color={"default"}
icon={<CheckBoxOutlineBlankIcon fontSize="small" />}
checkedIcon={<CheckBoxIcon fontSize="small" />}
checked={props.curState.showTests}
onChange={(e) => props.toggleShowTests()}
name="tests"
id="tests"
/>
}
label="Tests"
/>
<label htmlFor="tests">Tests</label>
</div>
</FilterOptionList>

<AlertsOnTopToggle
className={props.curState.alertsOnTop ? "is-enabled" : ""}
onClick={(e) => props.toggleAlertsOnTop()}
>
Alerts on Top
</AlertsOnTopToggle>
</OverviewSidebarOptionsRoot>
)
}
41 changes: 32 additions & 9 deletions web/src/SidebarResources.tsx
Expand Up @@ -58,9 +58,10 @@ type SidebarProps = {

type SidebarState = SidebarOptions

let defaultFilters: SidebarOptions = {
let defaultOptions: SidebarOptions = {
showResources: true,
showTests: true,
alertsOnTop: false,
}

function PinnedItems(props: SidebarProps) {
Expand All @@ -86,6 +87,14 @@ function PinnedItems(props: SidebarProps) {
return <SidebarListSection name="Pinned">{pinnedItems}</SidebarListSection>
}

function hasAlerts(item: SidebarItem): boolean {
return item.buildAlertCount > 0 || item.runtimeAlertCount > 0
}

function sortByHasAlerts(itemA: SidebarItem, itemB: SidebarItem): number {
return Number(hasAlerts(itemB)) - Number(hasAlerts(itemA))
}

export class SidebarResources extends React.Component<
SidebarProps,
SidebarState
Expand All @@ -95,7 +104,8 @@ export class SidebarResources extends React.Component<
this.triggerSelected = this.triggerSelected.bind(this)
this.toggleShowResources = this.toggleShowResources.bind(this)
this.toggleShowTests = this.toggleShowTests.bind(this)
this.state = defaultFilters
this.toggleAlertsOnTop = this.toggleAlertsOnTop.bind(this)
this.state = defaultOptions
}

triggerSelected(action: string) {
Expand All @@ -120,6 +130,14 @@ export class SidebarResources extends React.Component<
})
}

toggleAlertsOnTop() {
this.setState((prevState: SidebarOptions) => {
return {
alertsOnTop: !prevState.alertsOnTop,
}
})
}

render() {
let pb = this.props.pathBuilder
let totalAlerts = this.props.items // Open Q: do we include alert totals for hidden elems?
Expand All @@ -137,6 +155,10 @@ export class SidebarResources extends React.Component<
item.isTiltfile
)

if (this.state.alertsOnTop) {
filteredItems.sort(sortByHasAlerts)
}

let listItems = filteredItems.map((item) => (
<SidebarItemView
key={"sidebarItem-" + item.name}
Expand All @@ -156,20 +178,21 @@ export class SidebarResources extends React.Component<
return (
<SidebarResourcesRoot className={`Sidebar-resources ${isOverviewClass}`}>
<SidebarList>
{testsPresent ? (
<OverviewSidebarOptions
curState={this.state}
toggleShowResources={this.toggleShowResources}
toggleShowTests={this.toggleShowTests}
/> // TODO: if this vanishes because no tests present, reset it to show everything
) : null}
<SidebarListSection name="">
<SidebarItemAll
nothingSelected={nothingSelected}
totalAlerts={totalAlerts}
/>
</SidebarListSection>
<PinnedItems {...this.props} />
{testsPresent && (
<OverviewSidebarOptions
curState={this.state}
toggleShowResources={this.toggleShowResources}
toggleShowTests={this.toggleShowTests}
toggleAlertsOnTop={this.toggleAlertsOnTop}
/> // TODO: if this vanishes because no tests present, reset it to show everything
)}
<SidebarListSection name="resources">{listItems}</SidebarListSection>
</SidebarList>
<SidebarKeyboardShortcuts
Expand Down

0 comments on commit c04ecf0

Please sign in to comment.