From 17ad702fc40269d23bc23cd7bfe8e3c4d082111c Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 23 Jun 2022 00:50:27 +0000 Subject: [PATCH 1/3] refactor: extract workspace filter into a separate component --- .../SearchBarWithFilter.stories.tsx | 26 ++++ .../SearchBarWithFilter.tsx | 140 ++++++++++++++++++ .../WorkspacesPage/WorkspacesPageView.tsx | 120 +-------------- 3 files changed, 173 insertions(+), 113 deletions(-) create mode 100644 site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx create mode 100644 site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx diff --git a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx new file mode 100644 index 0000000000000..cc7daea2f3902 --- /dev/null +++ b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx @@ -0,0 +1,26 @@ +import { ComponentMeta, Story } from "@storybook/react" +import { workspaceFilterQuery } from "../../util/workspace" +import { SearchBarWithFilter, SearchBarWithFilterProps } from "./SearchBarWithFilter" + +export default { + title: "components/SearchBarWithFilter", + component: SearchBarWithFilter, + argTypes: { + filter: { + defaultValue: workspaceFilterQuery.me, + }, + }, +} as ComponentMeta + +const Template: Story = (args) => + +export const WithoutPresetFilters = Template.bind({}) + +export const WithPresetFilters = Template.bind({}) +WithPresetFilters.args = { + ...WithoutPresetFilters.args, + presetFilters: [ + { query: workspaceFilterQuery.me, name: "Your workspaces" }, + { query: "random query", name: "Random query" }, + ], +} diff --git a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx new file mode 100644 index 0000000000000..2487ed2d639c8 --- /dev/null +++ b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx @@ -0,0 +1,140 @@ +import Button from "@material-ui/core/Button" +import Fade from "@material-ui/core/Fade" +import InputAdornment from "@material-ui/core/InputAdornment" +import Menu from "@material-ui/core/Menu" +import MenuItem from "@material-ui/core/MenuItem" +import { makeStyles } from "@material-ui/core/styles" +import TextField from "@material-ui/core/TextField" +import SearchIcon from "@material-ui/icons/Search" +import { FormikErrors, useFormik } from "formik" +import { useState } from "react" +import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils" +import { CloseDropdown, OpenDropdown } from "../DropdownArrows/DropdownArrows" +import { Stack } from "../Stack/Stack" + +export const Language = { + filterName: "Filters", +} + +export interface SearchBarWithFilterProps { + filter?: string + onFilter: (query: string) => void + presetFilters?: PresetFilters[] +} + +export interface PresetFilters { + name: string + query: string +} + +interface FilterFormValues { + query: string +} + +export type FilterFormErrors = FormikErrors + +export const SearchBarWithFilter: React.FC = ({ filter, onFilter, presetFilters }) => { + const styles = useStyles() + + const form = useFormik({ + enableReinitialize: true, + initialValues: { + query: filter ?? "", + }, + onSubmit: ({ query }) => { + onFilter(query) + }, + }) + + const getFieldHelpers = getFormHelpers(form) + + const [anchorEl, setAnchorEl] = useState(null) + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget) + } + + const handleClose = () => { + setAnchorEl(null) + } + + const setPresetFilter = (query: string) => () => { + void form.setFieldValue("query", query) + void form.submitForm() + handleClose() + } + + return ( + + {presetFilters && presetFilters.length > 0 && ( + + )} + +
+ + + + ), + }} + /> + + + {presetFilters && presetFilters.length > 0 && ( + + {presetFilters.map((presetFilter) => ( + + {presetFilter.name} + + ))} + + )} +
+ ) +} + +const useStyles = makeStyles((theme) => ({ + filterContainer: { + border: `1px solid ${theme.palette.divider}`, + borderRadius: theme.shape.borderRadius, + marginBottom: theme.spacing(2), + }, + filterForm: { + width: "100%", + }, + buttonRoot: { + border: "none", + borderRight: `1px solid ${theme.palette.divider}`, + borderRadius: `${theme.shape.borderRadius}px 0px 0px ${theme.shape.borderRadius}px`, + }, + textFieldRoot: { + margin: "0px", + "& fieldset": { + border: "none", + }, + }, +})) diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx index a66a58005e6e3..da24f921fd5a7 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx @@ -1,32 +1,25 @@ import Button from "@material-ui/core/Button" -import Fade from "@material-ui/core/Fade" -import InputAdornment from "@material-ui/core/InputAdornment" import Link from "@material-ui/core/Link" -import Menu from "@material-ui/core/Menu" -import MenuItem from "@material-ui/core/MenuItem" import { fade, makeStyles, Theme } from "@material-ui/core/styles" import Table from "@material-ui/core/Table" import TableBody from "@material-ui/core/TableBody" import TableCell from "@material-ui/core/TableCell" import TableHead from "@material-ui/core/TableHead" import TableRow from "@material-ui/core/TableRow" -import TextField from "@material-ui/core/TextField" import AddCircleOutline from "@material-ui/icons/AddCircleOutline" import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight" import RefreshIcon from "@material-ui/icons/Refresh" -import SearchIcon from "@material-ui/icons/Search" import useTheme from "@material-ui/styles/useTheme" import { useActor } from "@xstate/react" import dayjs from "dayjs" import relativeTime from "dayjs/plugin/relativeTime" -import { FormikErrors, useFormik } from "formik" -import { FC, useState } from "react" +import { FC } from "react" import { Link as RouterLink, useNavigate } from "react-router-dom" import { AvatarData } from "../../components/AvatarData/AvatarData" -import { CloseDropdown, OpenDropdown } from "../../components/DropdownArrows/DropdownArrows" import { EmptyState } from "../../components/EmptyState/EmptyState" import { Margins } from "../../components/Margins/Margins" import { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "../../components/PageHeader/PageHeader" +import { SearchBarWithFilter } from "../../components/SearchBarWithFilter/SearchBarWithFilter" import { Stack } from "../../components/Stack/Stack" import { TableCellLink } from "../../components/TableCellLink/TableCellLink" import { TableLoader } from "../../components/TableLoader/TableLoader" @@ -38,7 +31,6 @@ import { HelpTooltipText, HelpTooltipTitle, } from "../../components/Tooltips/HelpTooltip/HelpTooltip" -import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils" import { getDisplayStatus, workspaceFilterQuery } from "../../util/workspace" import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService" @@ -49,7 +41,6 @@ export const Language = { emptyCreateWorkspaceMessage: "Create your first workspace", emptyCreateWorkspaceDescription: "Start editing your source code and building your software", emptyResultsMessage: "No results matched your search", - filterName: "Filters", yourWorkspacesButton: "Your workspaces", allWorkspacesButton: "All workspaces", workspaceTooltipTitle: "What is a workspace?", @@ -154,12 +145,6 @@ const WorkspaceRow: React.FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({ wor ) } -interface FilterFormValues { - query: string -} - -export type FilterFormErrors = FormikErrors - export interface WorkspacesPageViewProps { loading?: boolean workspaceRefs?: WorkspaceItemMachineRef[] @@ -168,41 +153,10 @@ export interface WorkspacesPageViewProps { } export const WorkspacesPageView: FC = ({ loading, workspaceRefs, filter, onFilter }) => { - const styles = useStyles() - - const form = useFormik({ - enableReinitialize: true, - initialValues: { - query: filter ?? "", - }, - onSubmit: ({ query }) => { - onFilter(query) - }, - }) - - const getFieldHelpers = getFormHelpers(form) - - const [anchorEl, setAnchorEl] = useState(null) - - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget) - } - - const handleClose = () => { - setAnchorEl(null) - } - - const setYourWorkspaces = () => { - void form.setFieldValue("query", "owner:me") - void form.submitForm() - handleClose() - } - - const setAllWorkspaces = () => { - void form.setFieldValue("query", "") - void form.submitForm() - handleClose() - } + const presetFilters = [ + { query: workspaceFilterQuery.me, name: Language.yourWorkspacesButton }, + { query: workspaceFilterQuery.all, name: Language.allWorkspacesButton }, + ] return ( @@ -223,48 +177,7 @@ export const WorkspacesPageView: FC = ({ loading, works - - - -
- - - - ), - }} - /> - - - - {Language.yourWorkspacesButton} - {Language.allWorkspacesButton} - -
+ @@ -328,25 +241,6 @@ const useStyles = makeStyles((theme) => ({ lineHeight: `${theme.spacing(3)}px`, }, }, - filterContainer: { - border: `1px solid ${theme.palette.divider}`, - borderRadius: theme.shape.borderRadius, - marginBottom: theme.spacing(2), - }, - filterForm: { - width: "100%", - }, - buttonRoot: { - border: "none", - borderRight: `1px solid ${theme.palette.divider}`, - borderRadius: `${theme.shape.borderRadius}px 0px 0px ${theme.shape.borderRadius}px`, - }, - textFieldRoot: { - margin: "0px", - "& fieldset": { - border: "none", - }, - }, clickableTableRow: { "&:hover td": { backgroundColor: fade(theme.palette.primary.light, 0.1), From 6c19f2c1bbf311fc9ba9899f2ba336793471ce86 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 23 Jun 2022 01:14:53 +0000 Subject: [PATCH 2/3] update interface name --- .../components/SearchBarWithFilter/SearchBarWithFilter.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx index 2487ed2d639c8..4ef07939025f7 100644 --- a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx +++ b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.tsx @@ -19,10 +19,10 @@ export const Language = { export interface SearchBarWithFilterProps { filter?: string onFilter: (query: string) => void - presetFilters?: PresetFilters[] + presetFilters?: PresetFilter[] } -export interface PresetFilters { +export interface PresetFilter { name: string query: string } From d6d8b0dad5f6d719a431ab03228da40b81a00f7f Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 23 Jun 2022 15:03:18 +0000 Subject: [PATCH 3/3] remove redundant spread --- .../SearchBarWithFilter/SearchBarWithFilter.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx index cc7daea2f3902..2df5a0d485c82 100644 --- a/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx +++ b/site/src/components/SearchBarWithFilter/SearchBarWithFilter.stories.tsx @@ -18,7 +18,6 @@ export const WithoutPresetFilters = Template.bind({}) export const WithPresetFilters = Template.bind({}) WithPresetFilters.args = { - ...WithoutPresetFilters.args, presetFilters: [ { query: workspaceFilterQuery.me, name: "Your workspaces" }, { query: "random query", name: "Random query" }, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy