-
Notifications
You must be signed in to change notification settings - Fork 889
feat(site): Read users into basic UsersTable #981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
fa600a5
Start users
presleyp aa75ca0
Merge branch 'main' into users-table/presleyp/592
presleyp 665e217
Set up fake response
presleyp 934e060
Update handler
presleyp a2a1a04
Update types
presleyp 201b34a
Set up page
presleyp b45ddaf
Start adding table
presleyp 0c341ed
Add header
presleyp aac1aee
Add Header
presleyp 40c61db
Remove roles
presleyp ca729e9
Add UsersPageView
presleyp 3fce4f0
Add test
presleyp 96d3a72
Lint
presleyp 6757380
Storybook error summary
presleyp b5fd9c8
Strip Pager to just what's currently needed
presleyp 30ced2f
Clean up ErrorSummary while I'm here
presleyp 272633b
Storybook tweaks
presleyp 1dda810
Extract language
presleyp be60aa8
Lint
presleyp 8d22584
Add missing $
presleyp 91ac0d5
Merge branch 'main' into users-table/presleyp/592
presleyp a50ea8a
Lint
presleyp bf06e92
Merge branch 'users-table/presleyp/592' of github.com:coder/coder int…
presleyp 34eb66b
Lint
presleyp 8c03bbc
Fix syntax error
presleyp 1cbc885
Lint
presleyp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ComponentMeta, Story } from "@storybook/react" | ||
import React from "react" | ||
import { ErrorSummary, ErrorSummaryProps } from "." | ||
|
||
export default { | ||
title: "components/ErrorSummary", | ||
component: ErrorSummary, | ||
} as ComponentMeta<typeof ErrorSummary> | ||
|
||
const Template: Story<ErrorSummaryProps> = (args) => <ErrorSummary {...args} /> | ||
|
||
export const WithError = Template.bind({}) | ||
WithError.args = { | ||
error: new Error("Something went wrong!"), | ||
} | ||
|
||
export const WithUndefined = Template.bind({}) | ||
greyscaled marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,19 @@ | ||
import React from "react" | ||
|
||
const Language = { | ||
unknownErrorMessage: "Unknown error", | ||
} | ||
|
||
export interface ErrorSummaryProps { | ||
error: Error | undefined | ||
error: Error | unknown | ||
} | ||
|
||
export const ErrorSummary: React.FC<ErrorSummaryProps> = ({ error }) => { | ||
// TODO: More interesting error page | ||
|
||
if (typeof error === "undefined") { | ||
return <div>{"Unknown error"}</div> | ||
if (!(error instanceof Error)) { | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return <div>{Language.unknownErrorMessage}</div> | ||
} else { | ||
return <div>{error.toString()}</div> | ||
} | ||
|
||
return <div>{error.toString()}</div> | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ComponentMeta, Story } from "@storybook/react" | ||
import React from "react" | ||
import { MockUser, MockUser2 } from "../../test_helpers" | ||
import { UsersTable, UsersTableProps } from "./UsersTable" | ||
|
||
export default { | ||
title: "Components/UsersTable", | ||
component: UsersTable, | ||
} as ComponentMeta<typeof UsersTable> | ||
|
||
const Template: Story<UsersTableProps> = (args) => <UsersTable {...args} /> | ||
|
||
export const Example = Template.bind({}) | ||
Example.args = { | ||
users: [MockUser, MockUser2], | ||
} | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export const Empty = Template.bind({}) | ||
Empty.args = { | ||
users: [], | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from "react" | ||
import { UserResponse } from "../../api/types" | ||
import { Column, Table } from "../../components/Table" | ||
import { EmptyState } from "../EmptyState" | ||
import { UserCell } from "../Table/Cells/UserCell" | ||
|
||
const Language = { | ||
pageTitle: "Users", | ||
usersTitle: "All users", | ||
emptyMessage: "No users found", | ||
usernameLabel: "User", | ||
} | ||
|
||
const emptyState = <EmptyState message={Language.emptyMessage} /> | ||
|
||
const columns: Column<UserResponse>[] = [ | ||
{ | ||
key: "username", | ||
name: Language.usernameLabel, | ||
renderer: (field, data) => { | ||
return <UserCell Avatar={{ username: data.username }} primaryText={data.username} caption={data.email} /> | ||
}, | ||
}, | ||
] | ||
|
||
export interface UsersTableProps { | ||
users: UserResponse[] | ||
} | ||
|
||
export const UsersTable: React.FC<UsersTableProps> = ({ users }) => { | ||
return <Table columns={columns} data={users} title={Language.usersTitle} emptyState={emptyState} /> | ||
} | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { screen } from "@testing-library/react" | ||
import React from "react" | ||
import { MockPager, render } from "../../test_helpers" | ||
import { UsersPage } from "./UsersPage" | ||
import { Language } from "./UsersPageView" | ||
|
||
describe("Users Page", () => { | ||
it("has a header with the total number of users", async () => { | ||
render(<UsersPage />) | ||
const total = await screen.findByText(/\d+ total/) | ||
expect(total.innerHTML).toEqual(Language.pageSubtitle(MockPager)) | ||
}) | ||
it("shows users", async () => { | ||
render(<UsersPage />) | ||
const users = await screen.findAllByText(/.*@coder.com/) | ||
expect(users.length).toEqual(2) | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useActor } from "@xstate/react" | ||
import React, { useContext } from "react" | ||
import { ErrorSummary } from "../../components/ErrorSummary" | ||
import { XServiceContext } from "../../xServices/StateContext" | ||
import { UsersPageView } from "./UsersPageView" | ||
|
||
export const UsersPage: React.FC = () => { | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const xServices = useContext(XServiceContext) | ||
const [usersState] = useActor(xServices.usersXService) | ||
const { users, pager, getUsersError } = usersState.context | ||
|
||
if (usersState.matches("error")) { | ||
return <ErrorSummary error={getUsersError} /> | ||
} else { | ||
return <UsersPageView users={users} pager={pager} /> | ||
} | ||
} | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ComponentMeta, Story } from "@storybook/react" | ||
import React from "react" | ||
import { MockPager, MockUser, MockUser2 } from "../../test_helpers" | ||
import { UsersPageView, UsersPageViewProps } from "./UsersPageView" | ||
|
||
export default { | ||
title: "pages/UsersPageView", | ||
component: UsersPageView, | ||
} as ComponentMeta<typeof UsersPageView> | ||
|
||
const Template: Story<UsersPageViewProps> = (args) => <UsersPageView {...args} /> | ||
|
||
export const Ready = Template.bind({}) | ||
Ready.args = { | ||
users: [MockUser, MockUser2], | ||
pager: MockPager, | ||
} | ||
export const Empty = Template.bind({}) | ||
Empty.args = { | ||
users: [], | ||
} | ||
presleyp marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { makeStyles } from "@material-ui/core/styles" | ||
import React from "react" | ||
import { Pager, UserResponse } from "../../api/types" | ||
import { Header } from "../../components/Header" | ||
import { UsersTable } from "../../components/UsersTable/UsersTable" | ||
|
||
export const Language = { | ||
pageTitle: "Users", | ||
pageSubtitle: (pager: Pager | undefined): string => (pager ? `${pager.total} total` : ""), | ||
} | ||
|
||
export interface UsersPageViewProps { | ||
users: UserResponse[] | ||
pager?: Pager | ||
} | ||
|
||
export const UsersPageView: React.FC<UsersPageViewProps> = ({ users, pager }) => { | ||
const styles = useStyles() | ||
return ( | ||
<div className={styles.flexColumn}> | ||
<Header title={Language.pageTitle} subTitle={Language.pageSubtitle(pager)} /> | ||
<UsersTable users={users} /> | ||
</div> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles(() => ({ | ||
flexColumn: { | ||
display: "flex", | ||
flexDirection: "column", | ||
}, | ||
})) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,7 +41,6 @@ describe("SignInPage", () => { | |
const password = screen.getByLabelText(Language.passwordLabel) | ||
await userEvent.type(email, "[email protected]") | ||
await userEvent.type(password, "password") | ||
|
||
// Click sign-in | ||
const signInButton = await screen.findByText(Language.signIn) | ||
act(() => signInButton.click()) | ||
|
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import { | ||
BuildInfoResponse, | ||
Organization, | ||
Pager, | ||
Provisioner, | ||
Template, | ||
UserAgent, | ||
|
@@ -25,6 +26,17 @@ export const MockUser: UserResponse = { | |
created_at: "", | ||
} | ||
|
||
export const MockUser2: UserResponse = { | ||
id: "test-user-2", | ||
username: "TestUser2", | ||
email: "[email protected]", | ||
created_at: "", | ||
} | ||
|
||
export const MockPager: Pager = { | ||
total: 2, | ||
} | ||
|
||
export const MockOrganization: Organization = { | ||
id: "test-org", | ||
name: "Test Organization", | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { assign, createMachine } from "xstate" | ||
import * as API from "../../api" | ||
import * as Types from "../../api/types" | ||
|
||
export interface UsersContext { | ||
users: Types.UserResponse[] | ||
pager?: Types.Pager | ||
getUsersError?: Error | unknown | ||
} | ||
|
||
export type UsersEvent = { type: "GET_USERS" } | ||
|
||
export const usersMachine = createMachine( | ||
{ | ||
tsTypes: {} as import("./usersXService.typegen").Typegen0, | ||
schema: { | ||
context: {} as UsersContext, | ||
events: {} as UsersEvent, | ||
services: {} as { | ||
getUsers: { | ||
data: Types.PagedUsers | ||
} | ||
}, | ||
}, | ||
id: "usersState", | ||
context: { | ||
users: [], | ||
}, | ||
initial: "gettingUsers", | ||
states: { | ||
gettingUsers: { | ||
invoke: { | ||
src: "getUsers", | ||
id: "getUsers", | ||
onDone: [ | ||
{ | ||
target: "#usersState.ready", | ||
actions: ["assignUsers", "clearGetUsersError"], | ||
}, | ||
], | ||
onError: [ | ||
{ | ||
actions: "assignGetUsersError", | ||
target: "#usersState.error", | ||
}, | ||
], | ||
}, | ||
tags: "loading", | ||
}, | ||
ready: { | ||
on: { | ||
GET_USERS: "gettingUsers", | ||
}, | ||
}, | ||
error: { | ||
on: { | ||
GET_USERS: "gettingUsers", | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
services: { | ||
getUsers: API.getUsers, | ||
}, | ||
actions: { | ||
assignUsers: assign({ | ||
users: (_, event) => event.data.page, | ||
pager: (_, event) => event.data.pager, | ||
}), | ||
assignGetUsersError: assign({ | ||
getUsersError: (_, event) => event.data, | ||
}), | ||
clearGetUsersError: assign((context: UsersContext) => ({ | ||
...context, | ||
getUsersError: undefined, | ||
})), | ||
}, | ||
}, | ||
) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.