Skip to content

Commit 36384aa

Browse files
chore(site): Use react-query and refactor the workspaces page to use it (#5838)
1 parent bef9e72 commit 36384aa

22 files changed

+499
-314
lines changed

site/.eslintrc.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ rules:
3737
["error", "1tbs", { "allowSingleLine": false }]
3838
"@typescript-eslint/camelcase": "off"
3939
"@typescript-eslint/explicit-function-return-type": "off"
40-
"@typescript-eslint/explicit-module-boundary-types": "error"
4140
"@typescript-eslint/method-signature-style": ["error", "property"]
4241
"@typescript-eslint/no-floating-promises": error
4342
"@typescript-eslint/no-invalid-void-type": error

site/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@material-ui/icons": "4.5.1",
3838
"@material-ui/lab": "4.0.0-alpha.42",
3939
"@monaco-editor/react": "4.4.6",
40+
"@tanstack/react-query": "4.22.4",
4041
"@testing-library/react-hooks": "8.0.1",
4142
"@types/color-convert": "2.0.0",
4243
"@types/react-color": "3.0.6",

site/src/api/api.ts

+7
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,10 @@ export const getTemplateVersionLogs = async (
779779
)
780780
return response.data
781781
}
782+
783+
export const updateWorkspaceVersion = async (
784+
workspace: TypesGen.Workspace,
785+
): Promise<TypesGen.WorkspaceBuild> => {
786+
const template = await getTemplate(workspace.template_id)
787+
return startWorkspace(workspace.id, template.active_version_id)
788+
}

site/src/app.tsx

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,46 @@
11
import CssBaseline from "@material-ui/core/CssBaseline"
22
import ThemeProvider from "@material-ui/styles/ThemeProvider"
3+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
34
import { AuthProvider } from "components/AuthProvider/AuthProvider"
4-
import { FC } from "react"
5+
import { FC, PropsWithChildren } from "react"
56
import { HelmetProvider } from "react-helmet-async"
67
import { AppRouter } from "./AppRouter"
78
import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary"
89
import { GlobalSnackbar } from "./components/GlobalSnackbar/GlobalSnackbar"
910
import { dark } from "./theme"
1011
import "./theme/globalFonts"
1112

12-
export const App: FC = () => {
13+
const queryClient = new QueryClient({
14+
defaultOptions: {
15+
queries: {
16+
retry: false,
17+
cacheTime: 0,
18+
},
19+
},
20+
})
21+
22+
export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
1323
return (
1424
<HelmetProvider>
1525
<ThemeProvider theme={dark}>
1626
<CssBaseline />
1727
<ErrorBoundary>
18-
<AuthProvider>
19-
<AppRouter />
20-
<GlobalSnackbar />
21-
</AuthProvider>
28+
<QueryClientProvider client={queryClient}>
29+
<AuthProvider>
30+
{children}
31+
<GlobalSnackbar />
32+
</AuthProvider>
33+
</QueryClientProvider>
2234
</ErrorBoundary>
2335
</ThemeProvider>
2436
</HelmetProvider>
2537
)
2638
}
39+
40+
export const App: FC = () => {
41+
return (
42+
<AppProviders>
43+
<AppRouter />
44+
</AppProviders>
45+
)
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import Button from "@material-ui/core/Button"
2+
import { makeStyles, useTheme } from "@material-ui/core/styles"
3+
import useMediaQuery from "@material-ui/core/useMediaQuery"
4+
import KeyboardArrowLeft from "@material-ui/icons/KeyboardArrowLeft"
5+
import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
6+
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"
7+
import { PageButton } from "./PageButton"
8+
import { buildPagedList } from "./utils"
9+
10+
export type PaginationWidgetBaseProps = {
11+
count: number
12+
page: number
13+
limit: number
14+
onChange: (page: number) => void
15+
}
16+
17+
export const PaginationWidgetBase = ({
18+
count,
19+
page,
20+
limit,
21+
onChange,
22+
}: PaginationWidgetBaseProps): JSX.Element | null => {
23+
const theme = useTheme()
24+
const isMobile = useMediaQuery(theme.breakpoints.down("sm"))
25+
const styles = useStyles()
26+
const numPages = Math.ceil(count / limit)
27+
const isFirstPage = page === 0
28+
const isLastPage = page === numPages - 1
29+
30+
if (numPages < 2) {
31+
return null
32+
}
33+
34+
return (
35+
<div className={styles.defaultContainerStyles}>
36+
<Button
37+
className={styles.prevLabelStyles}
38+
aria-label="Previous page"
39+
disabled={isFirstPage}
40+
onClick={() => {
41+
if (!isFirstPage) {
42+
onChange(page - 1)
43+
}
44+
}}
45+
>
46+
<KeyboardArrowLeft />
47+
</Button>
48+
<ChooseOne>
49+
<Cond condition={isMobile}>
50+
<PageButton activePage={page} page={page} numPages={numPages} />
51+
</Cond>
52+
<Cond>
53+
{buildPagedList(numPages, page).map((pageItem) => {
54+
if (pageItem === "left" || pageItem === "right") {
55+
return (
56+
<PageButton
57+
key={pageItem}
58+
activePage={page}
59+
placeholder="..."
60+
disabled
61+
/>
62+
)
63+
}
64+
65+
return (
66+
<PageButton
67+
key={pageItem}
68+
page={pageItem}
69+
activePage={page}
70+
numPages={numPages}
71+
onPageClick={() => onChange(pageItem)}
72+
/>
73+
)
74+
})}
75+
</Cond>
76+
</ChooseOne>
77+
<Button
78+
aria-label="Next page"
79+
disabled={isLastPage}
80+
onClick={() => {
81+
if (!isLastPage) {
82+
onChange(page + 1)
83+
}
84+
}}
85+
>
86+
<KeyboardArrowRight />
87+
</Button>
88+
</div>
89+
)
90+
}
91+
92+
const useStyles = makeStyles((theme) => ({
93+
defaultContainerStyles: {
94+
justifyContent: "center",
95+
alignItems: "center",
96+
display: "flex",
97+
flexDirection: "row",
98+
padding: "20px",
99+
},
100+
101+
prevLabelStyles: {
102+
marginRight: `${theme.spacing(0.5)}px`,
103+
},
104+
}))

site/src/components/PaginationWidget/utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const NUM_PAGE_BLOCKS = PAGES_TO_DISPLAY + 2
3030
export const buildPagedList = (
3131
numPages: number,
3232
activePage: number,
33-
): (string | number)[] => {
33+
): ("left" | "right" | number)[] => {
3434
if (numPages > NUM_PAGE_BLOCKS) {
3535
let pages = []
3636
const leftBound = activePage - PAGE_NEIGHBORS
@@ -44,8 +44,8 @@ export const buildPagedList = (
4444
const singleSpillOffset = PAGES_TO_DISPLAY - pages.length - 1
4545
const hasLeftOverflow = startPage > 2
4646
const hasRightOverflow = endPage < beforeLastPage
47-
const leftOverflowPage = "left"
48-
const rightOverflowPage = "right"
47+
const leftOverflowPage = "left" as const
48+
const rightOverflowPage = "right" as const
4949

5050
if (hasLeftOverflow && !hasRightOverflow) {
5151
const extraPages = range(startPage - singleSpillOffset, startPage - 1)

site/src/components/WorkspacesTable/WorkspacesRow.tsx

+7-9
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,22 @@ import TableCell from "@material-ui/core/TableCell"
22
import { makeStyles } from "@material-ui/core/styles"
33
import TableRow from "@material-ui/core/TableRow"
44
import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
5-
import { useActor } from "@xstate/react"
65
import { AvatarData } from "components/AvatarData/AvatarData"
76
import { WorkspaceStatusBadge } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge"
87
import { useClickable } from "hooks/useClickable"
98
import { FC } from "react"
109
import { useNavigate } from "react-router-dom"
1110
import { getDisplayWorkspaceTemplateName } from "util/workspace"
12-
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
1311
import { LastUsed } from "../LastUsed/LastUsed"
14-
import { OutdatedHelpTooltip } from "../Tooltips"
12+
import { Workspace } from "api/typesGenerated"
13+
import { OutdatedHelpTooltip } from "components/Tooltips/OutdatedHelpTooltip"
1514

16-
export const WorkspacesRow: FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({
17-
workspaceRef,
18-
}) => {
15+
export const WorkspacesRow: FC<{
16+
workspace: Workspace
17+
onUpdateWorkspace: (workspace: Workspace) => void
18+
}> = ({ workspace, onUpdateWorkspace }) => {
1919
const styles = useStyles()
2020
const navigate = useNavigate()
21-
const [workspaceState, send] = useActor(workspaceRef)
22-
const { data: workspace } = workspaceState.context
2321
const workspacePageLink = `/@${workspace.owner_name}/${workspace.name}`
2422
const hasTemplateIcon =
2523
workspace.template_icon && workspace.template_icon !== ""
@@ -58,7 +56,7 @@ export const WorkspacesRow: FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({
5856
{workspace.outdated && (
5957
<OutdatedHelpTooltip
6058
onUpdateVersion={() => {
61-
send("UPDATE_VERSION")
59+
onUpdateWorkspace(workspace)
6260
}}
6361
/>
6462
)}

site/src/components/WorkspacesTable/WorkspacesTable.tsx

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import TableCell from "@material-ui/core/TableCell"
44
import TableContainer from "@material-ui/core/TableContainer"
55
import TableHead from "@material-ui/core/TableHead"
66
import TableRow from "@material-ui/core/TableRow"
7+
import { Workspace } from "api/typesGenerated"
78
import { FC } from "react"
8-
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
99
import { WorkspacesTableBody } from "./WorkspacesTableBody"
1010

1111
const Language = {
@@ -18,15 +18,16 @@ const Language = {
1818
}
1919

2020
export interface WorkspacesTableProps {
21-
isLoading?: boolean
22-
workspaceRefs?: WorkspaceItemMachineRef[]
23-
filter?: string
24-
isNonInitialPage: boolean
21+
workspaces?: Workspace[]
22+
isUsingFilter: boolean
23+
onUpdateWorkspace: (workspace: Workspace) => void
2524
}
2625

27-
export const WorkspacesTable: FC<
28-
React.PropsWithChildren<WorkspacesTableProps>
29-
> = ({ isLoading, workspaceRefs, filter, isNonInitialPage }) => {
26+
export const WorkspacesTable: FC<WorkspacesTableProps> = ({
27+
workspaces,
28+
isUsingFilter,
29+
onUpdateWorkspace,
30+
}) => {
3031
return (
3132
<TableContainer>
3233
<Table>
@@ -42,10 +43,9 @@ export const WorkspacesTable: FC<
4243
</TableHead>
4344
<TableBody>
4445
<WorkspacesTableBody
45-
isLoading={isLoading}
46-
workspaceRefs={workspaceRefs}
47-
filter={filter}
48-
isNonInitialPage={isNonInitialPage}
46+
workspaces={workspaces}
47+
isUsingFilter={isUsingFilter}
48+
onUpdateWorkspace={onUpdateWorkspace}
4949
/>
5050
</TableBody>
5151
</Table>

0 commit comments

Comments
 (0)