diff --git a/site/src/components/Conditionals/ChooseOne.tsx b/site/src/components/Conditionals/ChooseOne.tsx index c61082c3656af..0f9087a94b0a8 100644 --- a/site/src/components/Conditionals/ChooseOne.tsx +++ b/site/src/components/Conditionals/ChooseOne.tsx @@ -40,7 +40,7 @@ export const ChooseOne = ({ } if (conditionedOptions.some((cond) => cond.props.condition === undefined)) { throw new Error( - "A non-final Cond in a ChooseOne does not have a condition prop.", + "A non-final Cond in a ChooseOne does not have a condition prop or the prop is undefined.", ) } const chosen = conditionedOptions.find((child) => child.props.condition) diff --git a/site/src/components/PaginationWidget/utils.ts b/site/src/components/PaginationWidget/utils.ts index 5d48660b05e0f..a2cd41880ef2c 100644 --- a/site/src/components/PaginationWidget/utils.ts +++ b/site/src/components/PaginationWidget/utils.ts @@ -102,3 +102,9 @@ export const createPaginationRef = ( ): PaginationMachineRef => { return spawn(paginationMachine.withContext(context)) } + +export const nonInitialPage = (searchParams: URLSearchParams): boolean => { + const page = searchParams.get("page") + const numberPage = page ? Number(page) : 1 + return numberPage > 1 +} diff --git a/site/src/components/UsersTable/UsersTable.stories.tsx b/site/src/components/UsersTable/UsersTable.stories.tsx index a9641b2747635..a1f11d8e277c6 100644 --- a/site/src/components/UsersTable/UsersTable.stories.tsx +++ b/site/src/components/UsersTable/UsersTable.stories.tsx @@ -1,6 +1,6 @@ import { ComponentMeta, Story } from "@storybook/react" import { - MockSiteRoles, + MockAssignableSiteRoles, MockUser, MockUser2, } from "../../testHelpers/renderHelpers" @@ -9,6 +9,11 @@ import { UsersTable, UsersTableProps } from "./UsersTable" export default { title: "components/UsersTable", component: UsersTable, + argTypes: { + isNonInitialPage: { + defaultValue: false, + }, + }, } as ComponentMeta const Template: Story = (args) => @@ -16,27 +21,27 @@ const Template: Story = (args) => export const Example = Template.bind({}) Example.args = { users: [MockUser, MockUser2], - roles: MockSiteRoles, + roles: MockAssignableSiteRoles, canEditUsers: false, } export const Editable = Template.bind({}) Editable.args = { users: [MockUser, MockUser2], - roles: MockSiteRoles, + roles: MockAssignableSiteRoles, canEditUsers: true, } export const Empty = Template.bind({}) Empty.args = { users: [], - roles: MockSiteRoles, + roles: MockAssignableSiteRoles, } export const Loading = Template.bind({}) Loading.args = { users: [], - roles: MockSiteRoles, + roles: MockAssignableSiteRoles, isLoading: true, } Loading.parameters = { diff --git a/site/src/components/UsersTable/UsersTable.test.tsx b/site/src/components/UsersTable/UsersTable.test.tsx index 876e8f857989e..21ae5d57d5757 100644 --- a/site/src/components/UsersTable/UsersTable.test.tsx +++ b/site/src/components/UsersTable/UsersTable.test.tsx @@ -15,6 +15,7 @@ describe("AuditPage", () => { onActivateUser={() => jest.fn()} onResetUserPassword={() => jest.fn()} onUpdateUserRoles={() => jest.fn()} + isNonInitialPage={false} />, ) diff --git a/site/src/components/UsersTable/UsersTable.tsx b/site/src/components/UsersTable/UsersTable.tsx index 05eb6b501fbee..1226d8591fbf0 100644 --- a/site/src/components/UsersTable/UsersTable.tsx +++ b/site/src/components/UsersTable/UsersTable.tsx @@ -32,6 +32,7 @@ export interface UsersTableProps { user: TypesGen.User, roles: TypesGen.Role["name"][], ) => void + isNonInitialPage: boolean } export const UsersTable: FC> = ({ @@ -46,6 +47,7 @@ export const UsersTable: FC> = ({ isUpdatingUserRoles, canEditUsers, isLoading, + isNonInitialPage, }) => { return ( @@ -78,6 +80,7 @@ export const UsersTable: FC> = ({ onResetUserPassword={onResetUserPassword} onSuspendUser={onSuspendUser} onUpdateUserRoles={onUpdateUserRoles} + isNonInitialPage={isNonInitialPage} /> diff --git a/site/src/components/UsersTable/UsersTableBody.tsx b/site/src/components/UsersTable/UsersTableBody.tsx index de1a6573b8898..b97dbc05c2e7e 100644 --- a/site/src/components/UsersTable/UsersTableBody.tsx +++ b/site/src/components/UsersTable/UsersTableBody.tsx @@ -2,8 +2,10 @@ import Box from "@material-ui/core/Box" import { makeStyles } from "@material-ui/core/styles" import TableCell from "@material-ui/core/TableCell" import TableRow from "@material-ui/core/TableRow" +import { ChooseOne, Cond } from "components/Conditionals/ChooseOne" import { LastUsed } from "components/LastUsed/LastUsed" import { FC } from "react" +import { useTranslation } from "react-i18next" import * as TypesGen from "../../api/typesGenerated" import { combineClasses } from "../../util/combineClasses" import { AvatarData } from "../AvatarData/AvatarData" @@ -12,15 +14,6 @@ import { RoleSelect } from "../RoleSelect/RoleSelect" import { TableLoader } from "../TableLoader/TableLoader" import { TableRowMenu } from "../TableRowMenu/TableRowMenu" -export const Language = { - emptyMessage: "No users found", - suspendMenuItem: "Suspend", - deleteMenuItem: "Delete", - listWorkspacesMenuItem: "View workspaces", - activateMenuItem: "Activate", - resetPasswordMenuItem: "Reset password", -} - interface UsersTableBodyProps { users?: TypesGen.User[] roles?: TypesGen.AssignableRoles[] @@ -36,6 +29,7 @@ interface UsersTableBodyProps { user: TypesGen.User, roles: TypesGen.Role["name"][], ) => void + isNonInitialPage: boolean } export const UsersTableBody: FC< @@ -52,121 +46,144 @@ export const UsersTableBody: FC< isUpdatingUserRoles, canEditUsers, isLoading, + isNonInitialPage, }) => { const styles = useStyles() - - if (isLoading) { - return - } - - if (!users || users.length === 0) { - return ( - - - - - - - - ) - } + const { t } = useTranslation("usersPage") return ( - <> - {users.map((user) => { - // When the user has no role we want to show they are a Member - const fallbackRole: TypesGen.Role = { - name: "member", - display_name: "Member", - } - const userRoles = user.roles.length === 0 ? [fallbackRole] : user.roles + + + + + + + + + + + + + + + + + + + + + + + + + + + + <> + {users && + users.map((user) => { + // When the user has no role we want to show they are a Member + const fallbackRole: TypesGen.Role = { + name: "member", + display_name: "Member", + } + const userRoles = + user.roles.length === 0 ? [fallbackRole] : user.roles - return ( - - - + + + ) : null + } /> - ) : null - } - /> - - - {user.status} - - - - - - {canEditUsers ? ( - { - // Remove the fallback role because it is only for the UI - roles = roles.filter((role) => role !== fallbackRole.name) - onUpdateUserRoles(user, roles) - }} - /> - ) : ( - <>{userRoles.map((role) => role.display_name).join(", ")} - )} - - {canEditUsers && ( - - - - )} - - ) - })} - + + + {user.status} + + + + + + {canEditUsers ? ( + { + // Remove the fallback role because it is only for the UI + roles = roles.filter( + (role) => role !== fallbackRole.name, + ) + onUpdateUserRoles(user, roles) + }} + /> + ) : ( + <> + {userRoles.map((role) => role.display_name).join(", ")} + + )} + + {canEditUsers && ( + + + + )} + + ) + })} + + + ) } diff --git a/site/src/components/WorkspacesTable/WorkspacesTable.tsx b/site/src/components/WorkspacesTable/WorkspacesTable.tsx index 0d20841d10580..07b0e91de2c20 100644 --- a/site/src/components/WorkspacesTable/WorkspacesTable.tsx +++ b/site/src/components/WorkspacesTable/WorkspacesTable.tsx @@ -21,11 +21,12 @@ export interface WorkspacesTableProps { isLoading?: boolean workspaceRefs?: WorkspaceItemMachineRef[] filter?: string + isNonInitialPage: boolean } export const WorkspacesTable: FC< React.PropsWithChildren -> = ({ isLoading, workspaceRefs, filter }) => { +> = ({ isLoading, workspaceRefs, filter, isNonInitialPage }) => { return ( @@ -44,6 +45,7 @@ export const WorkspacesTable: FC< isLoading={isLoading} workspaceRefs={workspaceRefs} filter={filter} + isNonInitialPage={isNonInitialPage} />
diff --git a/site/src/components/WorkspacesTable/WorkspacesTableBody.tsx b/site/src/components/WorkspacesTable/WorkspacesTableBody.tsx index ca4d588127cbc..d5172901485b4 100644 --- a/site/src/components/WorkspacesTable/WorkspacesTableBody.tsx +++ b/site/src/components/WorkspacesTable/WorkspacesTableBody.tsx @@ -3,7 +3,9 @@ import Link from "@material-ui/core/Link" import TableCell from "@material-ui/core/TableCell" import TableRow from "@material-ui/core/TableRow" import AddCircleOutline from "@material-ui/icons/AddCircleOutline" +import { ChooseOne, Cond } from "components/Conditionals/ChooseOne" import { FC } from "react" +import { useTranslation } from "react-i18next" import { Link as RouterLink } from "react-router-dom" import { workspaceFilterQuery } from "../../util/filters" import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService" @@ -11,63 +13,65 @@ import { EmptyState } from "../EmptyState/EmptyState" import { TableLoader } from "../TableLoader/TableLoader" import { WorkspacesRow } from "./WorkspacesRow" -export const Language = { - emptyCreateWorkspaceMessage: "Create your first workspace", - emptyCreateWorkspaceDescription: - "Start editing your source code and building your software.", - createFromTemplateButton: "Create from template", - emptyResultsMessage: "No results matched your search", -} - interface TableBodyProps { isLoading?: boolean workspaceRefs?: WorkspaceItemMachineRef[] filter?: string + isNonInitialPage: boolean } export const WorkspacesTableBody: FC< React.PropsWithChildren -> = ({ isLoading, workspaceRefs, filter }) => { - if (isLoading) { - return - } - - if (!workspaceRefs || workspaceRefs.length === 0) { - return ( - <> - {filter === workspaceFilterQuery.me || - filter === workspaceFilterQuery.all ? ( - - - - - - } - /> - - - ) : ( - - - - - - )} - - ) - } +> = ({ isLoading, workspaceRefs, filter, isNonInitialPage }) => { + const { t } = useTranslation("workspacesPage") return ( - <> - {workspaceRefs.map((workspaceRef) => ( - - ))} - + + + + + + + + + + + + + + + + } + /> + + + + + + + + + + {workspaceRefs && + workspaceRefs.map((workspaceRef) => ( + + ))} + + ) } diff --git a/site/src/i18n/en/auditLog.json b/site/src/i18n/en/auditLog.json index 4d118ad85ada4..84be1ec8adbec 100644 --- a/site/src/i18n/en/auditLog.json +++ b/site/src/i18n/en/auditLog.json @@ -3,5 +3,9 @@ "create": "created a new", "write": "updated", "delete": "deleted" + }, + "table": { + "emptyPage": "No audit logs available on this page", + "noLogs": "No audit logs available" } } diff --git a/site/src/i18n/en/index.ts b/site/src/i18n/en/index.ts index 653ac3ed8553b..3b710390cafd2 100644 --- a/site/src/i18n/en/index.ts +++ b/site/src/i18n/en/index.ts @@ -6,6 +6,8 @@ import templatesPage from "./templatesPage.json" import workspacePage from "./workspacePage.json" import agent from "./agent.json" import buildPage from "./buildPage.json" +import workspacesPage from "./workspacesPage.json" +import usersPage from "./usersPage.json" export const en = { common, @@ -16,4 +18,6 @@ export const en = { createWorkspacePage, agent, buildPage, + workspacesPage, + usersPage, } diff --git a/site/src/i18n/en/usersPage.json b/site/src/i18n/en/usersPage.json new file mode 100644 index 0000000000000..e1f84b93df7f5 --- /dev/null +++ b/site/src/i18n/en/usersPage.json @@ -0,0 +1,9 @@ +{ + "emptyMessage": "No users found", + "emptyPageMessage": "No users found on this page", + "suspendMenuItem": "Suspend", + "deleteMenuItem": "Delete", + "listWorkspacesMenuItem": "View workspaces", + "activateMenuItem": "Activate", + "resetPasswordMenuItem": "Reset password" +} diff --git a/site/src/i18n/en/workspacesPage.json b/site/src/i18n/en/workspacesPage.json new file mode 100644 index 0000000000000..1bcb1b6f77c1b --- /dev/null +++ b/site/src/i18n/en/workspacesPage.json @@ -0,0 +1,7 @@ +{ + "emptyCreateWorkspaceMessage": "Create your first workspace", + "emptyCreateWorkspaceDescription": "Start editing your source code and building your software.", + "createFromTemplateButton": "Create from template", + "emptyResultsMessage": "No results matched your search", + "emptyPageMessage": "No results on this page" +} diff --git a/site/src/pages/AuditPage/AuditPage.tsx b/site/src/pages/AuditPage/AuditPage.tsx index 7d719daef8042..ff43d0e065888 100644 --- a/site/src/pages/AuditPage/AuditPage.tsx +++ b/site/src/pages/AuditPage/AuditPage.tsx @@ -1,5 +1,8 @@ import { useMachine } from "@xstate/react" -import { getPaginationContext } from "components/PaginationWidget/utils" +import { + getPaginationContext, + nonInitialPage, +} from "components/PaginationWidget/utils" import { FC } from "react" import { Helmet } from "react-helmet-async" import { useSearchParams } from "react-router-dom" @@ -38,6 +41,7 @@ const AuditPage: FC = () => { auditSend("FILTER", { filter }) }} paginationRef={paginationRef} + isNonInitialPage={nonInitialPage(searchParams)} /> ) diff --git a/site/src/pages/AuditPage/AuditPageView.stories.tsx b/site/src/pages/AuditPage/AuditPageView.stories.tsx index d02275f2b45b9..a645039e427ac 100644 --- a/site/src/pages/AuditPage/AuditPageView.stories.tsx +++ b/site/src/pages/AuditPage/AuditPageView.stories.tsx @@ -25,6 +25,26 @@ const Template: Story = (args) => ( export const AuditPage = Template.bind({}) +export const Loading = Template.bind({}) +Loading.args = { + auditLogs: undefined, + count: undefined, + isNonInitialPage: false, +} + +export const EmptyPage = Template.bind({}) +EmptyPage.args = { + auditLogs: [], + isNonInitialPage: true, +} + +export const NoLogs = Template.bind({}) +NoLogs.args = { + auditLogs: [], + count: 0, + isNonInitialPage: false, +} + export const AuditPageSmallViewport = Template.bind({}) AuditPageSmallViewport.parameters = { chromatic: { viewports: [600] }, diff --git a/site/src/pages/AuditPage/AuditPageView.tsx b/site/src/pages/AuditPage/AuditPageView.tsx index 8ab90b8420db0..60e731c0082cf 100644 --- a/site/src/pages/AuditPage/AuditPageView.tsx +++ b/site/src/pages/AuditPage/AuditPageView.tsx @@ -5,6 +5,7 @@ import TableContainer from "@material-ui/core/TableContainer" import TableRow from "@material-ui/core/TableRow" import { AuditLog } from "api/typesGenerated" import { AuditLogRow } from "components/AuditLogRow/AuditLogRow" +import { ChooseOne, Cond } from "components/Conditionals/ChooseOne" import { EmptyState } from "components/EmptyState/EmptyState" import { Margins } from "components/Margins/Margins" import { @@ -19,6 +20,7 @@ import { TableLoader } from "components/TableLoader/TableLoader" import { Timeline } from "components/Timeline/Timeline" import { AuditHelpTooltip } from "components/Tooltips" import { FC } from "react" +import { useTranslation } from "react-i18next" import { PaginationMachineRef } from "xServices/pagination/paginationXService" export const Language = { @@ -43,6 +45,7 @@ export interface AuditPageViewProps { filter: string onFilter: (filter: string) => void paginationRef: PaginationMachineRef + isNonInitialPage: boolean } export const AuditPageView: FC = ({ @@ -51,7 +54,9 @@ export const AuditPageView: FC = ({ filter, onFilter, paginationRef, + isNonInitialPage, }) => { + const { t } = useTranslation("auditLog") const isLoading = auditLogs === undefined || count === undefined const isEmpty = !isLoading && auditLogs.length === 0 @@ -77,23 +82,38 @@ export const AuditPageView: FC = ({ - {isLoading && } - - {auditLogs && ( - new Date(log.time)} - row={(log) => } - /> - )} - - {isEmpty && ( - - - - - - )} + + + + + + + + + + + + + + + + + + + + + + + + {auditLogs && ( + new Date(log.time)} + row={(log) => } + /> + )} + +
diff --git a/site/src/pages/UsersPage/UsersPage.test.tsx b/site/src/pages/UsersPage/UsersPage.test.tsx index 766581ca2dcf2..f7869c3ca85be 100644 --- a/site/src/pages/UsersPage/UsersPage.test.tsx +++ b/site/src/pages/UsersPage/UsersPage.test.tsx @@ -8,7 +8,6 @@ import { Role } from "../../api/typesGenerated" import { Language as ResetPasswordDialogLanguage } from "../../components/Dialogs/ResetPasswordDialog/ResetPasswordDialog" import { GlobalSnackbar } from "../../components/GlobalSnackbar/GlobalSnackbar" import { Language as RoleSelectLanguage } from "../../components/RoleSelect/RoleSelect" -import { Language as UsersTableBodyLanguage } from "../../components/UsersTable/UsersTableBody" import { MockAuditorRole, MockUser, @@ -39,9 +38,8 @@ const suspendUser = async (setupActionSpies: () => void) => { await user.click(firstMoreButton) const menu = await screen.findByRole("menu") - const suspendButton = within(menu).getByText( - UsersTableBodyLanguage.suspendMenuItem, - ) + const text = t("suspendMenuItem", { ns: "usersPage" }) + const suspendButton = within(menu).getByText(text) await user.click(suspendButton) @@ -72,9 +70,8 @@ const deleteUser = async (setupActionSpies: () => void) => { await user.click(selectedMoreButton) const menu = await screen.findByRole("menu") - const deleteButton = within(menu).getByText( - UsersTableBodyLanguage.deleteMenuItem, - ) + const text = t("deleteMenuItem", { ns: "usersPage" }) + const deleteButton = within(menu).getByText(text) await user.click(deleteButton) @@ -107,9 +104,8 @@ const activateUser = async (setupActionSpies: () => void) => { fireEvent.click(suspendedMoreButton) const menu = screen.getByRole("menu") - const activateButton = within(menu).getByText( - UsersTableBodyLanguage.activateMenuItem, - ) + const text = t("activateMenuItem", { ns: "usersPage" }) + const activateButton = within(menu).getByText(text) fireEvent.click(activateButton) // Check if the confirm message is displayed @@ -135,9 +131,8 @@ const resetUserPassword = async (setupActionSpies: () => void) => { fireEvent.click(firstMoreButton) const menu = screen.getByRole("menu") - const resetPasswordButton = within(menu).getByText( - UsersTableBodyLanguage.resetPasswordMenuItem, - ) + const text = t("resetPasswordMenuItem", { ns: "usersPage" }) + const resetPasswordButton = within(menu).getByText(text) fireEvent.click(resetPasswordButton) diff --git a/site/src/pages/UsersPage/UsersPage.tsx b/site/src/pages/UsersPage/UsersPage.tsx index 66303ebb033c5..ef4e9de025286 100644 --- a/site/src/pages/UsersPage/UsersPage.tsx +++ b/site/src/pages/UsersPage/UsersPage.tsx @@ -1,7 +1,10 @@ import { useActor, useMachine } from "@xstate/react" import { User } from "api/typesGenerated" import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog" -import { getPaginationContext } from "components/PaginationWidget/utils" +import { + getPaginationContext, + nonInitialPage, +} from "components/PaginationWidget/utils" import { usePermissions } from "hooks/usePermissions" import { FC, ReactNode, useContext, useEffect } from "react" import { Helmet } from "react-helmet-async" @@ -127,6 +130,7 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => { usersSend({ type: "UPDATE_FILTER", query }) }} paginationRef={paginationRef} + isNonInitialPage={nonInitialPage(searchParams)} /> @@ -22,29 +34,23 @@ const Template: Story = (args) => ( ) export const Admin = Template.bind({}) -Admin.args = { - users: [MockUser, MockUser2], - roles: MockAssignableSiteRoles, - canEditUsers: true, -} export const SmallViewport = Template.bind({}) -SmallViewport.args = { - ...Admin.args, -} SmallViewport.parameters = { chromatic: { viewports: [600] }, } export const Member = Template.bind({}) -Member.args = { ...Admin.args, canEditUsers: false } +Member.args = { canEditUsers: false } export const Empty = Template.bind({}) -Empty.args = { ...Admin.args, users: [] } +Empty.args = { users: [] } + +export const EmptyPage = Template.bind({}) +EmptyPage.args = { users: [], isNonInitialPage: true } export const Error = Template.bind({}) Error.args = { - ...Admin.args, users: undefined, error: { response: { diff --git a/site/src/pages/UsersPage/UsersPageView.tsx b/site/src/pages/UsersPage/UsersPageView.tsx index 9a80140a1d048..886818fc610ff 100644 --- a/site/src/pages/UsersPage/UsersPageView.tsx +++ b/site/src/pages/UsersPage/UsersPageView.tsx @@ -29,6 +29,7 @@ export interface UsersPageViewProps { ) => void onFilter: (query: string) => void paginationRef: PaginationMachineRef + isNonInitialPage: boolean } export const UsersPageView: FC> = ({ @@ -47,6 +48,7 @@ export const UsersPageView: FC> = ({ filter, onFilter, paginationRef, + isNonInitialPage, }) => { const presetFilters = [ { query: userFilterQuery.active, name: Language.activeUsersFilterName }, @@ -74,6 +76,7 @@ export const UsersPageView: FC> = ({ isUpdatingUserRoles={isUpdatingUserRoles} canEditUsers={canEditUsers} isLoading={isLoading} + isNonInitialPage={isNonInitialPage} /> diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx index 7ba6ef88ee4a4..87d4297864bc5 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx @@ -1,11 +1,13 @@ import { screen, waitFor } from "@testing-library/react" import { rest } from "msw" import * as CreateDayString from "util/createDayString" -import { Language as WorkspacesTableBodyLanguage } from "../../components/WorkspacesTable/WorkspacesTableBody" import { MockWorkspace } from "../../testHelpers/entities" import { history, render } from "../../testHelpers/renderHelpers" import { server } from "../../testHelpers/server" import WorkspacesPage from "./WorkspacesPage" +import { i18n } from "i18n" + +const { t } = i18n describe("WorkspacesPage", () => { beforeEach(() => { @@ -27,9 +29,8 @@ describe("WorkspacesPage", () => { render() // Then - await screen.findByText( - WorkspacesTableBodyLanguage.emptyCreateWorkspaceMessage, - ) + const text = t("emptyCreateWorkspaceMessage", { ns: "workspacesPage" }) + await screen.findByText(text) }) it("renders a filled workspaces page", async () => { diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx index c8204c2f9ee40..1171cc99cbf46 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx @@ -1,5 +1,8 @@ import { useMachine } from "@xstate/react" -import { getPaginationContext } from "components/PaginationWidget/utils" +import { + getPaginationContext, + nonInitialPage, +} from "components/PaginationWidget/utils" import { FC } from "react" import { Helmet } from "react-helmet-async" import { useSearchParams } from "react-router-dom" @@ -49,6 +52,7 @@ const WorkspacesPage: FC = () => { }) }} paginationRef={paginationRef} + isNonInitialPage={nonInitialPage(searchParams)} /> ) diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx index 2b06e238e6791..18dbc66405a51 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx @@ -112,6 +112,7 @@ AllStates.args = { ...Object.values(additionalWorkspaces), ], count: 14, + isNonInitialPage: false, } export const OwnerHasNoWorkspaces = Template.bind({}) @@ -119,6 +120,7 @@ OwnerHasNoWorkspaces.args = { workspaceRefs: [], filter: workspaceFilterQuery.me, count: 0, + isNonInitialPage: false, } export const NoResults = Template.bind({}) @@ -126,4 +128,13 @@ NoResults.args = { workspaceRefs: [], filter: "searchtearmwithnoresults", count: 0, + isNonInitialPage: false, +} + +export const EmptyPage = Template.bind({}) +EmptyPage.args = { + workspaceRefs: [], + filter: workspaceFilterQuery.me, + count: 0, + isNonInitialPage: true, } diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx index 0b403d01de7cf..7eeafb6f514b7 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx @@ -36,6 +36,7 @@ export interface WorkspacesPageViewProps { filter?: string onFilter: (query: string) => void paginationRef: PaginationMachineRef + isNonInitialPage: boolean } export const WorkspacesPageView: FC< @@ -49,6 +50,7 @@ export const WorkspacesPageView: FC< filter, onFilter, paginationRef, + isNonInitialPage, }) => { const presetFilters = [ { query: workspaceFilterQuery.me, name: Language.yourWorkspacesButton }, @@ -105,6 +107,7 @@ export const WorkspacesPageView: FC< isLoading={isLoading} workspaceRefs={workspaceRefs} filter={filter} + isNonInitialPage={isNonInitialPage} />