Skip to content

Commit

Permalink
web: add resource name filter (#4379)
Browse files Browse the repository at this point in the history
  • Loading branch information
landism committed Apr 5, 2021
1 parent 8aeb180 commit b4888e7
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 62 deletions.
1 change: 1 addition & 0 deletions web/package.json
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.3",
"@testing-library/dom": "^7.24.5",
"@types/history": "^4.7.2",
"@types/js-cookie": "^2.2.2",
Expand Down
4 changes: 4 additions & 0 deletions web/src/GlobalNav.tsx
Expand Up @@ -9,6 +9,7 @@ import { ReactComponent as SnapshotIcon } from "./assets/svg/snapshot.svg"
import { ReactComponent as UpdateAvailableIcon } from "./assets/svg/update-available.svg"
import FloatDialog from "./FloatDialog"
import MetricsDialog from "./MetricsDialog"
import { isTargetEditable } from "./shortcut"
import ShortcutsDialog from "./ShortcutsDialog"
import { SnapshotAction } from "./snapshot"
import {
Expand Down Expand Up @@ -105,6 +106,9 @@ class GlobalNavShortcuts extends Component<GlobalNavShortcutsProps> {
}

onKeydown(e: KeyboardEvent) {
if (isTargetEditable(e)) {
return
}
if (e.metaKey || e.altKey || e.ctrlKey || e.isComposing) {
return
}
Expand Down
34 changes: 19 additions & 15 deletions web/src/HUD.tsx
@@ -1,3 +1,4 @@
import { StylesProvider } from "@material-ui/core/styles"
import { History, UnregisterCallback } from "history"
import React, { Component } from "react"
import ReactOutlineManager from "react-outline-manager"
Expand Down Expand Up @@ -293,21 +294,24 @@ export default class HUD extends Component<HudProps, HudState> {
}

return (
<SnapshotActionProvider value={snapshotAction}>
<PathBuilderProvider value={this.pathBuilder}>
<LogStoreProvider value={this.state.logStore || new LogStore()}>
<Switch>
<Route
path={this.path("/r/:name/overview")}
render={(props: RouteComponentProps<any>) => (
<OverviewResourcePane view={this.state.view} />
)}
/>
<Route render={() => <OverviewPane view={this.state.view} />} />
</Switch>
</LogStoreProvider>
</PathBuilderProvider>
</SnapshotActionProvider>
/* allow Styled Components to override MUI - https://material-ui.com/guides/interoperability/#controlling-priority-3*/
<StylesProvider injectFirst>
<SnapshotActionProvider value={snapshotAction}>
<PathBuilderProvider value={this.pathBuilder}>
<LogStoreProvider value={this.state.logStore || new LogStore()}>
<Switch>
<Route
path={this.path("/r/:name/overview")}
render={(props: RouteComponentProps<any>) => (
<OverviewResourcePane view={this.state.view} />
)}
/>
<Route render={() => <OverviewPane view={this.state.view} />} />
</Switch>
</LogStoreProvider>
</PathBuilderProvider>
</SnapshotActionProvider>
</StylesProvider>
)
}

Expand Down
21 changes: 18 additions & 3 deletions web/src/LocalStorage.tsx
Expand Up @@ -34,20 +34,35 @@ export function accessorsForTesting<S>(name: string) {
}

// Like `useState`, but backed by localStorage and namespaced by the tiltfileKey
export function usePersistentState<S>(name: string, defaultValue: S) {
// maybeUpgradeSavedState: transforms any state read from storage - allows, e.g., filling in default values for
// fields added since the state was saved
export function usePersistentState<S>(
name: string,
defaultValue: S,
maybeUpgradeSavedState?: (state: S) => S
): [state: S, setState: Dispatch<SetStateAction<S>>] {
const tiltfileKey = useContext(tiltfileKeyContext)
return useStorageState<S>(
let [state, setState] = useStorageState<S>(
localStorage,
makeKey(tiltfileKey, name),
defaultValue
)
if (maybeUpgradeSavedState) {
state = maybeUpgradeSavedState(state)
}
return [state, setState]
}

export function PersistentStateProvider<S>(props: {
name: string
defaultValue: S
maybeUpgradeSavedState?: (state: S) => S
children: (state: S, setState: Dispatch<SetStateAction<S>>) => JSX.Element
}) {
const [state, setState] = usePersistentState(props.name, props.defaultValue)
let [state, setState] = usePersistentState(
props.name,
props.defaultValue,
props.maybeUpgradeSavedState
)
return props.children(state, setState)
}
5 changes: 5 additions & 0 deletions web/src/OverviewActionBarKeyboardShortcuts.tsx
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from "react"
import { incr } from "./analytics"
import { clearLogs } from "./ClearLogs"
import LogStore from "./LogStore"
import { isTargetEditable } from "./shortcut"

type Link = Proto.webviewLink

Expand Down Expand Up @@ -33,6 +34,10 @@ class OverviewActionBarKeyboardShortcuts extends Component<Props> {
}

onKeydown(e: KeyboardEvent) {
if (isTargetEditable(e)) {
return
}

if (e.altKey || e.isComposing) {
return
}
Expand Down
59 changes: 55 additions & 4 deletions web/src/OverviewSidebarOptions.test.tsx
Expand Up @@ -11,10 +11,10 @@ import {
AlertsOnTopToggle,
FilterOptionList,
OverviewSidebarOptions,
ResourceNameFilterTextField,
TestsHiddenToggle,
TestsOnlyToggle,
} from "./OverviewSidebarOptions"
import PathBuilder from "./PathBuilder"
import SidebarItemView from "./SidebarItemView"
import { SidebarPinContextProvider } from "./SidebarPin"
import SidebarResources, {
Expand All @@ -23,8 +23,6 @@ import SidebarResources, {
} from "./SidebarResources"
import { SidebarOptions } from "./types"

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

const sidebarOptionsAccessor = accessorsForTesting<SidebarOptions>(
"sidebar_options"
)
Expand All @@ -37,7 +35,8 @@ export function assertSidebarItemsAndOptions(
names: string[],
expectTestsHidden: boolean,
expectTestsOnly: boolean,
expectAlertsOnTop: boolean
expectAlertsOnTop: boolean,
expectedResourceNameFilter?: string
) {
let sidebar = root.find(SidebarResources)
expect(sidebar).toHaveLength(1)
Expand All @@ -60,6 +59,11 @@ export function assertSidebarItemsAndOptions(
expect(optSetter.find(AlertsOnTopToggle).hasClass("is-enabled")).toEqual(
expectAlertsOnTop
)
if (expectedResourceNameFilter !== undefined) {
expect(optSetter.find(ResourceNameFilterTextField).props().value).toEqual(
expectedResourceNameFilter
)
}
}

function clickTestsHiddenControl(root: ReactWrapper) {
Expand Down Expand Up @@ -199,6 +203,53 @@ describe("overview sidebar options", () => {
expect(pinned).toHaveLength(1)
expect(pinned.at(0).props().item.name).toEqual("beep")
})

it("applies the name filter", () => {
// 'B p' tests both case insensitivity and a multi-term query
sidebarOptionsAccessor.set({ ...defaultOptions, resourceNameFilter: "B p" })
const root = mount(
<MemoryRouter>
<tiltfileKeyContext.Provider value="test">
<SidebarPinContextProvider>
{TwoResourcesTwoTests()}
</SidebarPinContextProvider>
</tiltfileKeyContext.Provider>
</MemoryRouter>
)

assertSidebarItemsAndOptions(
root,
["beep", "boop"],
defaultOptions.testsHidden,
defaultOptions.testsOnly,
defaultOptions.alertsOnTop,
"B p"
)
})

it("says no matches found", () => {
sidebarOptionsAccessor.set({
...defaultOptions,
resourceNameFilter: "asdfawfwef",
})
const root = mount(
<MemoryRouter>
<tiltfileKeyContext.Provider value="test">
<SidebarPinContextProvider>
{TwoResourcesTwoTests()}
</SidebarPinContextProvider>
</tiltfileKeyContext.Provider>
</MemoryRouter>
)

const resourceSectionItems = root
.find(SidebarListSection)
.find({ name: "resources" })
.find("li")
expect(resourceSectionItems.map((n) => n.text())).toEqual([
"No matching resources",
])
})
})

it("toggles/untoggles Alerts On Top sorting when button clicked", () => {
Expand Down

0 comments on commit b4888e7

Please sign in to comment.